module Origen::Boot

Provides methods for setting up, booting and archiving an Origen application

Constants

BINSTUB
BIN_DEPS

Gem executables that Origen depends on [bin name, gem name]

BUNDLER_SETUP
BUNDLER_WARNING
UPDATER_WARNING

Public Class Methods

app!(origen_root) click to toggle source

Boot the application at the given root

# File lib/origen/boot/app.rb, line 129
def app!(origen_root)
  # This will be used to collect warnings about the user's application environment, however showing them
  # will be deferred until it has been determined that the application is using Origen >= 0.40.0 - i.e. we
  # don't want to start complaining to the user about existing apps until they have intentionally upgraded
  # their Origen version.
  warnings = []

  exec_remote = ARGV.include?('--exec_remote') ? true : false
  lbin_dir = File.join(origen_root, 'lbin')
  origen_binstub = File.join(lbin_dir, 'origen')

  unless exec_remote
    if !File.exist?(origen_binstub) ||
       (File.exist?(origen_binstub) && File.read(origen_binstub) !~ /This file was generated by Origen/)
      warnings << BUNDLER_WARNING
    elsif File.exist?(File.join(origen_root, 'bin', 'fix_my_workspace'))
      warnings << UPDATER_WARNING
    end

    setup_bundler(origen_root)
  end

  boot_app = true

  Dir.chdir origen_root do
    # Overriding bundler here so that bundle install can be automated as required, otherwise if just call
    # require 'bundler/setup' then it will exit in the event of errors
    require 'bundler'
    begin
      Bundler.setup
    rescue Gem::LoadError, Bundler::BundlerError => e
      puts e
      puts
      if exec_remote
        puts 'App failed to boot, run it locally so that this can be resolved before re-submitting to the LSF'
        exit 1
      end
      puts 'Attempting to resolve this...'
      puts

      passed = false

      Bundler.with_clean_env do
        cmd = 'bundle install'
        cmd += ' --local' if File.exist?('.origen_archive')
        passed = system(cmd)
      end

      if passed
        Bundler.with_clean_env do
          exec "origen #{ARGV.join(' ')}"
        end
        exit 0
      else
        puts
        puts "If you have just updated a gem version and are now getting an error that Bundler cannot find compatible versions for it then first try running 'bundle update <gemname>'."
        puts "For example if you have just changed the version of origen run 'bundle update origen'."
        exit 1
      end
    end
  end
  unless exec_remote
    # The application's bundle is safely loaded, do a final check to make sure that Origen's
    # required bin dependencies have binstubs
    if BIN_DEPS.any? { |bin, gem| !File.exist?(File.join(lbin_dir, bin)) }
      system "bundle binstubs #{BIN_DEPS.map { |bin, gem| gem }.join(' ')} --path #{lbin_dir} --force"
    end
  end
  require 'origen'
  warnings
end
copy_system_gems(origen_root, bundle_path) click to toggle source
# File lib/origen/boot/app.rb, line 236
def copy_system_gems(origen_root, bundle_path)
  if Origen.site_config.gem_use_from_system
    local_gem_dir = "#{bundle_path}/ruby/#{Pathname.new(Gem.dir).basename}"
    gem_dir = Pathname.new(Gem.dir)

    Origen.site_config.gem_use_from_system.each do |gem, version|
      # This will raise an error if the system doesn't have this gem installed, that
      # will be rescued below
      spec = Gem::Specification.find_by_name(gem, version)

      # If the spec has returned a handle to a system installed gem. If this script has been invoked through
      # Bundler then it could point to some other gem dir. The only time this should occur is when switching
      # from the old system to the new system, but can't work out how to fix it so just disabling in that case.
      if spec.gem_dir =~ /#{gem_dir}/

        local_dir = File.join(local_gem_dir, Pathname.new(spec.gem_dir).relative_path_from(gem_dir))
        FileUtils.mkdir_p local_dir
        FileUtils.cp_r("#{spec.gem_dir}/.", local_dir)

        local_file = Pathname.new(File.join(local_gem_dir, Pathname.new(spec.cache_file).relative_path_from(gem_dir)))
        FileUtils.mkdir_p local_file.dirname
        FileUtils.cp(spec.cache_file, local_file)

        if spec.extension_dir && File.exist?(spec.extension_dir)
          local_dir = File.join(local_gem_dir, Pathname.new(spec.extension_dir).relative_path_from(gem_dir))
          FileUtils.mkdir_p local_dir
          FileUtils.cp_r("#{spec.extension_dir}/.", local_dir)
        end

        local_file = Pathname.new(File.join(local_gem_dir, Pathname.new(spec.spec_file).relative_path_from(gem_dir)))
        FileUtils.mkdir_p local_file.dirname
        FileUtils.cp(spec.spec_file, local_file)

        puts "Copied #{gem} #{version} from the system into #{bundle_path}"

      end

    rescue Exception # Gem::LoadError  # Rescue everything here, this is a try-our-best operation, better to
      # continue and try and install the gem if this fails rather than crash
      # This just means that one of the gems that should be copied from the system
      # was not actually installed in the system, so nothing we can do about that here
    end
  end
end
create_origen_binstub(origen_root) click to toggle source
# File lib/origen/boot/app.rb, line 209
def create_origen_binstub(origen_root)
  lbin_dir = File.join(origen_root, 'lbin')

  FileUtils.mkdir_p(lbin_dir)
  File.open(File.join(lbin_dir, 'origen'), 'w') do |f|
    f.puts BINSTUB
  end
  FileUtils.chmod('+x', File.join(lbin_dir, 'origen'))

  if Origen.os.windows?
    Dir.glob("#{origen_root}/lbin/*").each do |bin|
      unless bin =~ /.bat$/
        bat = "#{bin}.bat"
        unless File.exist?(bat)
          File.open(bat, 'w') { |f| f.write('@"ruby.exe" "%~dpn0" %*') }
        end
      end
    end
  end
end
setup(origen_root) click to toggle source
# File lib/origen/boot/app.rb, line 201
def setup(origen_root)
  create_origen_binstub(origen_root)
  bundle_path = setup_bundler(origen_root)
  unless File.exist?(File.join(origen_root, '.origen_archive'))
    copy_system_gems(origen_root, bundle_path)
  end
end
setup_bundler(origen_root) click to toggle source
# File lib/origen/boot/app.rb, line 230
def setup_bundler(origen_root)
  bundle_path = nil
  eval BUNDLER_SETUP # Will update bundle_path
  bundle_path
end