class Origen::Application::Runner

The Runner is responsible for co-ordinating all compile and generate requests from the command line

Attributes

options[RW]

Public Instance Methods

confirm_production_ready(_options = {}) click to toggle source
# File lib/origen/application/runner.rb, line 269
      def confirm_production_ready(_options = {})
        # The caller would have already verified the status before submission
        if Origen.running_locally?
          if Origen.mode.production? && Origen.app.rc
            unless Origen.app.rc.local_modifications.empty?
              puts <<-EOT
    Your workspace is running in production mode and it has local modifications which are preventing
    the requested action, run the following command to see what files have been modified:

      origen rc mods

    If you are currently developing this application and are not ready to check everything in yet,
    then run the following command to switch your workspace to debug/development mode:

      origen m debug
              EOT
              exit 1
            end
          end
        end
      end
expand_lists_and_directories(files, options = {}) click to toggle source

Expands any list references in the supplied pattern array and returns an array of pattern names. No guarantee is made to whether the pattern names are valid at this stage. Any duplicates will be removed.

# File lib/origen/application/runner.rb, line 207
def expand_lists_and_directories(files, options = {})
  Origen.file_handler.expand_list(files, options)
end
extract_action(options) click to toggle source

The action to take should be set by the action option, but legacy code will pass things like :compile => true, the extract_action method handles the old code

# File lib/origen/application/runner.rb, line 173
def extract_action(options)
  return options[:action] if options[:action]

  if options[:compile]
    :compile
  elsif options[:program]
    :program
  elsif options[:job_type] == :merge
    :merge
  else
    :pattern
  end
end
extract_files(options) click to toggle source

Legacy file references can be input via :pattern, :patterns, etc. this cleans it up and forces them all to be in an array assigned to options

# File lib/origen/application/runner.rb, line 189
def extract_files(options)
  files = [options[:pattern]] + [options[:patterns]] + [options[:file]] + [options[:files]]
  files.flatten!
  files.compact!
  files
end
generate(options = {})
Alias for: launch
launch(options = {}) click to toggle source

Launch Origen, any command which generates an output file should launch from here as it gives a common point for listeners to hook in and to establish output directories and so on.

Originally this method was called generate but that is now deprecated in favour of the more generic ‘launch’ as the Origen feature set has expanded.

# File lib/origen/application/runner.rb, line 17
def launch(options = {})
  Origen.file_handler.preserve_state do
    # Clean up the input from legacy code
    options[:action] = extract_action(options)
    options[:files] = extract_files(options)
    @options = options
    prepare_and_validate_workspace(options)
    if options[:lsf]
      record_invocation(options) do
        prepare_for_lsf
        Origen.app.listeners_for(:before_lsf_submission).each(&:before_lsf_submission)
        batch = []
        expand_lists_and_directories(options[:files], options).each do |file|
          if options[:batch]
            # Batch jobs into groups of 10
            batch << file
            if batch.size == options[:batch]
              Origen.app.lsf_manager.submit_origen_job(batch.join(' '), options)
              batch = []
            end
          else
            Origen.app.lsf_manager.submit_origen_job(file, options)
          end
        end
        if options[:batch]
          Origen.app.lsf_manager.submit_origen_job(batch.join(' '), options) unless batch.empty?
        end
      end
      Origen.log.info ''
      Origen.log.info 'Monitor status of remote jobs via:'
      Origen.log.info '  origen l'
    else
      unless tester && tester.try(:sim?)
        Origen.log.info '*' * 70 unless options[:quiet]
      end
      Origen.app.listeners_for(:before_generate).each do |listener|
        if listener.class.instance_method(:before_generate).arity == 0
          listener.before_generate
        else
          listener.before_generate(options)
        end
      end
      if Origen.running_remotely?
        Origen.app.listeners_for(:before_generate_remote).each do |listener|
          if listener.class.instance_method(:before_generate_remote).arity == 0
            listener.before_generate_remote
          else
            listener.before_generate_remote(options)
          end
        end
      else
        Origen.app.listeners_for(:before_generate_local).each do |listener|
          if listener.class.instance_method(:before_generate_local).arity == 0
            listener.before_generate_local
          else
            listener.before_generate_local(options)
          end
        end
      end

      record_invocation(options) do
        case options[:action]
        when :forecast_test_time
          Origen.time.forecast_test_time(options)
        else
          if options[:action] == :program
            Origen.generator.generate_program(expand_lists_and_directories(options[:files], options), options)
            Origen.app.listeners_for(:program_generated).each(&:program_generated)
          else
            temporary_plugin_from_options = options[:current_plugin]
            if options[:action] == :pattern && options[:sequence]
              patterns = expand_lists_and_directories(options[:files], options.merge(preserve_duplicates: true))
              Origen.generator.generate_pattern(patterns, options)
              Origen.app.plugins.temporary = nil if temporary_plugin_from_options
            else
              expand_lists_and_directories(options[:files], options).each do |file|
                if temporary_plugin_from_options
                  Origen.app.plugins.temporary = temporary_plugin_from_options
                end
                case options[:action]
                when :compile
                  Origen.generator.compile_file_or_directory(file, options)
                when :merge
                  Origen.generator.merge_file_or_directory(file, options)
                when :import_test_time
                  Origen.time.import_test_time(file, options)
                when :import_test_flow
                  Origen.time.import_test_flow(file, options)
                else
                  Origen.generator.generate_pattern(file, options)
                end
                Origen.app.plugins.temporary = nil if temporary_plugin_from_options
              end
            end
          end
        end
      end

      unless options[:quiet] || (tester && tester.try(:sim?))
        Origen.log.info '*' * 70
        stats.print_summary unless options[:action] == :merge
      end
    end
  end
end
Also aliased as: generate
mkdir(dir) click to toggle source

Make the given directory if it doesn’t exist, must be a full path

# File lib/origen/application/runner.rb, line 263
def mkdir(dir)
  unless File.exist?(dir)
    FileUtils.mkdir_p(dir)
  end
end
prepare_and_validate_workspace(options = {}) click to toggle source
# File lib/origen/application/runner.rb, line 124
def prepare_and_validate_workspace(options = {})
  confirm_production_ready(options)
  prepare_directories(options)
end
prepare_directories(options = {}) click to toggle source
# File lib/origen/application/runner.rb, line 242
def prepare_directories(options = {})
  # When running remotely on the LSF never create directories to
  # prevent race conditions as multiple processes run concurrently,
  # instead assume they were already created by the runner who
  # submitted the job.
  Origen.file_handler.set_output_directory(options.merge(create: Origen.running_locally?))
  Origen.file_handler.set_reference_directory(options.merge(create: Origen.running_locally?))
  unless Origen.running_globally?
    tmp = "#{Origen.root}/tmp"
    FileUtils.mkdir(tmp) unless File.exist?(tmp)
    if Origen.running_locally?
      mkdir Origen::Log.log_file_directory
      mkdir "#{Origen.root}/.lsf"
    end
    if options[:lsf]
      mkdir Origen.app.lsf_manager.log_file_directory
    end
  end
end
prepare_for_lsf() click to toggle source
# File lib/origen/application/runner.rb, line 216
def prepare_for_lsf
  if options[:lsf]
    # Build an options string for saving with the LSF job that represents this runtime environment
    str = "-t #{Origen.target.file.basename}"
    if Origen.environment.file
      str += " --environment #{Origen.environment.file.basename}"
    end
    if options[:output]
      str += " -o #{options[:output]}"
    end
    if options[:reference]
      str += " -r #{options[:reference]}"
    end
    options[:lsf_option_string] = str
    # Clear the LSF manager job list if specifically requested or if that is the default action and
    # no specific action has been requested
    if options[:lsf_action]
      if options[:lsf_action] == :clear
        Origen.app.lsf_manager.clear_all
      end
    elsif Origen.config.default_lsf_action == :clear
      Origen.app.lsf_manager.clear_all
    end
  end
end
record_invocation(options) { || ... } click to toggle source

Post an invocation to the Origen server for usage statistics tracking.

Posting an invocation was found to add ~0.5s to all command times, so here we run it in a separate thread to try and hide it behind the user’s command.

@api private

# File lib/origen/application/runner.rb, line 136
def record_invocation(options)
  if Origen.site_config.record_invocation == true
    record_invocation = false
    begin
      # Only record user invocations at this time, also bypass windows since it seems
      # that threads can't be trusted not to block
      unless Origen.running_remotely? # || Origen.running_on_windows?
        record_invocation = Thread.new do
          Origen.client.record_invocation(options[:action]) if options[:action]
        rescue
          # Dont allow server being down to flood the screen with the stacktrace
        end
      end
    rescue
      # Don't allow this to kill an origen command
    end
  end
  # yield here is really important for the callback tests!!
  yield

  if Origen.site_config.record_invocation == true
    begin
      unless Origen.running_remotely?
        # Wait for a server response, ideally would like to not wait here, but it seems if not
        # then invocation postings can be dropped, especially on windows
        Origen.profile 'waiting for recording invocation' do
          record_invocation.value
        end
      end
    rescue
      # Don't allow this to kill an origen command
    end
  end
end
shutdown() click to toggle source
# File lib/origen/application/runner.rb, line 196
def shutdown
  if Origen.app.stats.failed_files > 0 ||
     Origen.app.stats.failed_patterns > 0
    exit 1
  end
end
statistics() click to toggle source
# File lib/origen/application/runner.rb, line 211
def statistics
  @statistics ||= Statistics.new(options)
end
Also aliased as: stats
stats()
Alias for: statistics