Class: Origen::Application::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/origen/application/runner.rb

Overview

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



9
10
11
# File 'lib/origen/application/runner.rb', line 9

def options
  @options
end

Instance Method Details

#confirm_production_ready(_options = {}) ⇒ Object



234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/origen/application/runner.rb', line 234

def confirm_production_ready(_options = {})
  # The caller would have already verified the status before submission
  if Origen.running_locally?
    if Origen.mode.production?
      unless Origen.app.rc.local_modifications.empty?
        puts "    Your workspace has local modifications that are preventing the requested action\n- run 'origen rc mods' to see them.\n        EOT\n        exit 1\n      end\n    end\n  end\nend\n"

#expand_lists_and_directories(files, options = {}) ⇒ Object

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.



174
175
176
# File 'lib/origen/application/runner.rb', line 174

def expand_lists_and_directories(files, options = {})
  Origen.file_handler.expand_list(files, options)
end

#extract_action(options) ⇒ Object

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



141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/origen/application/runner.rb', line 141

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) ⇒ Object

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



156
157
158
159
160
161
# File 'lib/origen/application/runner.rb', line 156

def extract_files(options)
  files = [options[:pattern]] + [options[:patterns]] + [options[:file]] + [options[:files]]
  files.flatten!
  files.compact!
  files
end

#launch(options = {}) ⇒ Object Also known as: generate

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.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/origen/application/runner.rb', line 17

def launch(options = {})
  # 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)
      expand_lists_and_directories(options[:files], options).each do |file|
        Origen.app.lsf_manager.submit_origen_job(file, options)
      end
    end
    Origen.log.info ''
    Origen.log.info 'Monitor status of remote jobs via:'
    Origen.log.info '  origen l'
  else
    Origen.log.info '*' * 70 unless options[:quiet]
    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)
        else
          temporary_plugin_from_options = options[:current_plugin]
          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

    unless options[:quiet]
      Origen.log.info '*' * 70
      stats.print_summary unless options[:action] == :merge
    end
  end
end

#mkdir(dir) ⇒ Object

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



228
229
230
231
232
# File 'lib/origen/application/runner.rb', line 228

def mkdir(dir)
  unless File.exist?(dir)
    FileUtils.mkdir_p(dir)
  end
end

#prepare_and_validate_workspace(options = {}) ⇒ Object



100
101
102
103
# File 'lib/origen/application/runner.rb', line 100

def prepare_and_validate_workspace(options = {})
  confirm_production_ready(options)
  prepare_directories(options)
end

#prepare_directories(options = {}) ⇒ Object



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/origen/application/runner.rb', line 209

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?))
  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

#prepare_for_lsfObject



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/origen/application/runner.rb', line 183

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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/origen/application/runner.rb', line 112

def record_invocation(options)
  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]
      end
    end
  rescue
    # Don't allow this to kill an origen command
  end
  yield
  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

#shutdownObject



163
164
165
166
167
168
# File 'lib/origen/application/runner.rb', line 163

def shutdown
  if Origen.app.stats.failed_files > 0 ||
     Origen.app.stats.failed_patterns > 0
    exit 1
  end
end

#statisticsObject Also known as: stats



178
179
180
# File 'lib/origen/application/runner.rb', line 178

def statistics
  @statistics ||= Statistics.new(options)
end