origen 0.2.6 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/bin/origen +3 -1
  3. data/config/boot.rb +1 -7
  4. data/config/commands.rb +0 -1
  5. data/config/version.rb +2 -2
  6. data/lib/c99/{j750_interface.rb → ate_interface.rb} +3 -11
  7. data/lib/c99/doc_interface.rb +1 -1
  8. data/lib/origen.rb +9 -30
  9. data/lib/origen/application.rb +10 -8
  10. data/lib/origen/application/configuration.rb +13 -26
  11. data/lib/origen/application/plugins.rb +122 -0
  12. data/lib/origen/application/plugins_manager.rb +16 -254
  13. data/lib/origen/application/release.rb +2 -2
  14. data/lib/origen/application/runner.rb +2 -4
  15. data/lib/origen/chips.rb +0 -0
  16. data/lib/origen/chips/chip.rb +0 -0
  17. data/lib/origen/chips/design_entry.rb +0 -0
  18. data/lib/origen/chips/doc_entry.rb +0 -0
  19. data/lib/origen/chips/note.rb +0 -0
  20. data/lib/origen/commands.rb +4 -44
  21. data/lib/origen/commands/compile.rb +1 -2
  22. data/lib/origen/commands/generate.rb +1 -1
  23. data/lib/origen/commands/interactive.rb +1 -2
  24. data/lib/origen/commands/plugin.rb +49 -56
  25. data/lib/origen/commands/program.rb +1 -1
  26. data/lib/origen/commands/rc.rb +2 -2
  27. data/lib/origen/commands/version.rb +2 -17
  28. data/lib/origen/commands_global.rb +3 -0
  29. data/lib/origen/file_handler.rb +10 -10
  30. data/lib/origen/generator.rb +1 -1
  31. data/lib/origen/generator/job.rb +1 -1
  32. data/lib/origen/generator/pattern.rb +2 -2
  33. data/lib/origen/generator/pattern_finder.rb +10 -9
  34. data/lib/origen/pins/pin.rb +0 -0
  35. data/lib/origen/regression_manager.rb +0 -0
  36. data/lib/origen/remote_manager.rb +2 -8
  37. data/lib/origen/revision_control/design_sync.rb +0 -0
  38. data/lib/origen/revision_control/git.rb +0 -0
  39. data/lib/origen/specs.rb +0 -0
  40. data/lib/origen/specs/checkers.rb +0 -0
  41. data/lib/origen/specs/creation_info.rb +0 -0
  42. data/lib/origen/specs/exhibit.rb +0 -0
  43. data/lib/origen/specs/spec.rb +0 -0
  44. data/lib/origen/utility.rb +0 -1
  45. data/lib/origen/utility/diff.rb +0 -0
  46. metadata +42 -119
  47. data/lib/origen/import_manager.rb +0 -596
  48. data/lib/origen/nvm.rb +0 -6
  49. data/lib/origen/nvm/block_array.rb +0 -72
  50. data/lib/origen/tester.rb +0 -56
  51. data/lib/origen/tester/api.rb +0 -277
  52. data/lib/origen/tester/bdm/bdm.rb +0 -25
  53. data/lib/origen/tester/doc/doc.rb +0 -226
  54. data/lib/origen/tester/doc/generator.rb +0 -126
  55. data/lib/origen/tester/doc/generator/flow.rb +0 -71
  56. data/lib/origen/tester/doc/generator/flow_line.rb +0 -203
  57. data/lib/origen/tester/doc/generator/test.rb +0 -68
  58. data/lib/origen/tester/doc/generator/test_group.rb +0 -66
  59. data/lib/origen/tester/doc/generator/tests.rb +0 -47
  60. data/lib/origen/tester/doc/model.rb +0 -162
  61. data/lib/origen/tester/generator.rb +0 -271
  62. data/lib/origen/tester/generator/flow_control_api.rb +0 -606
  63. data/lib/origen/tester/generator/identity_map.rb +0 -25
  64. data/lib/origen/tester/generator/placeholder.rb +0 -13
  65. data/lib/origen/tester/generator/test_numberer.rb +0 -25
  66. data/lib/origen/tester/interface.rb +0 -154
  67. data/lib/origen/tester/j750/files.rb +0 -45
  68. data/lib/origen/tester/j750/generator.rb +0 -203
  69. data/lib/origen/tester/j750/generator/flow.rb +0 -123
  70. data/lib/origen/tester/j750/generator/flow_line.rb +0 -288
  71. data/lib/origen/tester/j750/generator/patgroup.rb +0 -111
  72. data/lib/origen/tester/j750/generator/patgroups.rb +0 -41
  73. data/lib/origen/tester/j750/generator/patset.rb +0 -111
  74. data/lib/origen/tester/j750/generator/patsets.rb +0 -41
  75. data/lib/origen/tester/j750/generator/templates/flow.txt.erb +0 -9
  76. data/lib/origen/tester/j750/generator/templates/instances.txt.erb +0 -16
  77. data/lib/origen/tester/j750/generator/templates/patgroups.txt.erb +0 -8
  78. data/lib/origen/tester/j750/generator/templates/patsets.txt.erb +0 -10
  79. data/lib/origen/tester/j750/generator/test_instance.rb +0 -846
  80. data/lib/origen/tester/j750/generator/test_instance_group.rb +0 -60
  81. data/lib/origen/tester/j750/generator/test_instances.rb +0 -182
  82. data/lib/origen/tester/j750/j750.rb +0 -845
  83. data/lib/origen/tester/j750/j750_hpt.rb +0 -35
  84. data/lib/origen/tester/j750/parser.rb +0 -104
  85. data/lib/origen/tester/j750/parser/ac_spec.rb +0 -11
  86. data/lib/origen/tester/j750/parser/ac_specs.rb +0 -0
  87. data/lib/origen/tester/j750/parser/dc_spec.rb +0 -36
  88. data/lib/origen/tester/j750/parser/dc_specs.rb +0 -50
  89. data/lib/origen/tester/j750/parser/descriptions.rb +0 -340
  90. data/lib/origen/tester/j750/parser/flow.rb +0 -111
  91. data/lib/origen/tester/j750/parser/flow_line.rb +0 -207
  92. data/lib/origen/tester/j750/parser/flows.rb +0 -23
  93. data/lib/origen/tester/j750/parser/pattern_set.rb +0 -94
  94. data/lib/origen/tester/j750/parser/pattern_sets.rb +0 -33
  95. data/lib/origen/tester/j750/parser/test_instance.rb +0 -322
  96. data/lib/origen/tester/j750/parser/test_instances.rb +0 -26
  97. data/lib/origen/tester/j750/parser/timeset.rb +0 -15
  98. data/lib/origen/tester/j750/parser/timesets.rb +0 -0
  99. data/lib/origen/tester/jlink/jlink.rb +0 -33
  100. data/lib/origen/tester/parser.rb +0 -24
  101. data/lib/origen/tester/parser/description_lookup.rb +0 -64
  102. data/lib/origen/tester/parser/searchable_array.rb +0 -32
  103. data/lib/origen/tester/parser/searchable_hash.rb +0 -32
  104. data/lib/origen/tester/time.rb +0 -338
  105. data/lib/origen/tester/timing.rb +0 -253
  106. data/lib/origen/tester/ultraflex/files.rb +0 -45
  107. data/lib/origen/tester/ultraflex/generator.rb +0 -200
  108. data/lib/origen/tester/ultraflex/generator/flow.rb +0 -119
  109. data/lib/origen/tester/ultraflex/generator/flow_line.rb +0 -269
  110. data/lib/origen/tester/ultraflex/generator/patgroup.rb +0 -111
  111. data/lib/origen/tester/ultraflex/generator/patgroups.rb +0 -41
  112. data/lib/origen/tester/ultraflex/generator/patset.rb +0 -111
  113. data/lib/origen/tester/ultraflex/generator/patsets.rb +0 -41
  114. data/lib/origen/tester/ultraflex/generator/templates/flow.txt.erb +0 -9
  115. data/lib/origen/tester/ultraflex/generator/templates/instances.txt.erb +0 -16
  116. data/lib/origen/tester/ultraflex/generator/templates/patgroups.txt.erb +0 -8
  117. data/lib/origen/tester/ultraflex/generator/templates/patsets.txt.erb +0 -10
  118. data/lib/origen/tester/ultraflex/generator/test_instance.rb +0 -622
  119. data/lib/origen/tester/ultraflex/generator/test_instance_group.rb +0 -60
  120. data/lib/origen/tester/ultraflex/generator/test_instances.rb +0 -174
  121. data/lib/origen/tester/ultraflex/parser.rb +0 -104
  122. data/lib/origen/tester/ultraflex/parser/ac_spec.rb +0 -11
  123. data/lib/origen/tester/ultraflex/parser/ac_specs.rb +0 -0
  124. data/lib/origen/tester/ultraflex/parser/dc_spec.rb +0 -36
  125. data/lib/origen/tester/ultraflex/parser/dc_specs.rb +0 -50
  126. data/lib/origen/tester/ultraflex/parser/descriptions.rb +0 -342
  127. data/lib/origen/tester/ultraflex/parser/flow.rb +0 -111
  128. data/lib/origen/tester/ultraflex/parser/flow_line.rb +0 -207
  129. data/lib/origen/tester/ultraflex/parser/flows.rb +0 -23
  130. data/lib/origen/tester/ultraflex/parser/pattern_set.rb +0 -94
  131. data/lib/origen/tester/ultraflex/parser/pattern_sets.rb +0 -33
  132. data/lib/origen/tester/ultraflex/parser/test_instance.rb +0 -262
  133. data/lib/origen/tester/ultraflex/parser/test_instances.rb +0 -26
  134. data/lib/origen/tester/ultraflex/parser/timeset.rb +0 -15
  135. data/lib/origen/tester/ultraflex/parser/timesets.rb +0 -0
  136. data/lib/origen/tester/ultraflex/ultraflex.rb +0 -759
  137. data/lib/origen/tester/v93k/generator.rb +0 -80
  138. data/lib/origen/tester/v93k/generator/flow.rb +0 -63
  139. data/lib/origen/tester/v93k/generator/flow_node.rb +0 -17
  140. data/lib/origen/tester/v93k/generator/flow_node/print.rb +0 -10
  141. data/lib/origen/tester/v93k/generator/pattern.rb +0 -16
  142. data/lib/origen/tester/v93k/generator/pattern_master.rb +0 -54
  143. data/lib/origen/tester/v93k/generator/templates/_test_method.txt.erb +0 -6
  144. data/lib/origen/tester/v93k/generator/templates/_test_suite.txt.erb +0 -11
  145. data/lib/origen/tester/v93k/generator/templates/template.flow.erb +0 -121
  146. data/lib/origen/tester/v93k/generator/templates/template.pmfl.erb +0 -9
  147. data/lib/origen/tester/v93k/generator/test_function.rb +0 -103
  148. data/lib/origen/tester/v93k/generator/test_functions.rb +0 -79
  149. data/lib/origen/tester/v93k/generator/test_method.rb +0 -46
  150. data/lib/origen/tester/v93k/generator/test_methods.rb +0 -75
  151. data/lib/origen/tester/v93k/generator/test_suite.rb +0 -54
  152. data/lib/origen/tester/v93k/generator/test_suites.rb +0 -65
  153. data/lib/origen/tester/v93k/v93k.rb +0 -420
  154. data/lib/origen/tester/vector.rb +0 -86
  155. data/lib/origen/tester/vector_generator.rb +0 -637
  156. data/lib/origen/tester/vector_pipeline.rb +0 -150
  157. data/lib/origen/utility/design_sync.rb +0 -494
  158. data/lib/origen/version_checker.rb +0 -117
@@ -1,596 +0,0 @@
1
- module Origen
2
- # Responsible for ensuring that all dependencies defined in
3
- # config.imports are available.
4
- #
5
- # Workspaces will automatically be created and updated to the
6
- # correct version as required.
7
- #
8
- # An instance of this class is hooked up to:
9
- # Origen.import_manager
10
- class ImportManager
11
- SHARED_CONTENTS_TYPES = [:pattern, :templates, :command_launcher, :program]
12
-
13
- def initialize
14
- @required = false
15
- # These will be updated as plugins are imported.
16
- # Min and required are treated the same here, basically we don't allow plugins
17
- # to dictate a specific version and this will be taken as a minimum requirement.
18
- # Plugins can however block execution by specifying a max required version
19
- # that must not be exceeded.
20
- @required_origen_version = Origen.config.required_origen_version ||
21
- Origen.config.min_required_origen_version
22
- @max_required_origen_version = Origen.config.max_required_origen_version
23
- end
24
-
25
- # This will fetch all imports (if required), add the libs to
26
- # the load path, and require the environments.
27
- def require!
28
- unless required?
29
- while updates_required?
30
- puts 'The following imports need to be updated, this will now happen automatically:'
31
- puts ''
32
- dirty_imports.each do |name, import|
33
- if import[:path]
34
- puts " #{name} - #{import[:path]}"
35
- else
36
- puts " #{name} - #{import[:version]}"
37
- end
38
- end
39
- puts ''
40
- update!
41
- end
42
- if @required_origen_version
43
- if @max_required_origen_version
44
- if Origen::VersionString.new(@required_origen_version).greater_than?(@max_required_origen_version)
45
- puts ''
46
- puts "Your application needs to run Origen version #{@required_origen_version}, however"
47
- puts "the version of the #{@max_lib} plugin required by your import tree is not"
48
- puts "permitted to run above Origen version #{@max_required_origen_version}."
49
- puts 'You may need to consult with the plugin owner to see if this restriction can be'
50
- puts 'removed or if a newer version of the plugin without this restriction already'
51
- puts 'exists.'
52
- puts ''
53
- exit 0
54
- end
55
- end
56
- if Origen.version.less_than?(@required_origen_version)
57
- if Origen.config.required_origen_version
58
- puts ''
59
- puts "A dependent plugin requires at least Origen version #{@required_origen_version}, however"
60
- puts "your main application currently specifies #{Origen.config.required_origen_version}."
61
- puts 'To proceed you must update the required_origen_version in config/application.rb'
62
- puts "to be: #{@required_origen_version}"
63
- puts ''
64
- exit 0
65
- else
66
- Origen.version_checker.update_origen(@required_origen_version)
67
- end
68
- end
69
- end
70
- add_libs_to_load_path!
71
- require_environments!
72
- add_shared_contents!
73
- remove_unwanted_symlinks!
74
- @required = true
75
- end
76
- end
77
-
78
- # Returns true if the imports have already been required and added
79
- # to the load path of the current thread
80
- def required?
81
- @required
82
- end
83
-
84
- def required=(value)
85
- @required = value
86
- end
87
-
88
- def validate_production_status(force = false)
89
- if Origen.mode.production? || force
90
- imports.each do |_name, import|
91
- if import[:path]
92
- fail "The following import is defined as a path, but that is not allowed in production: #{import}"
93
- end
94
- version = Origen::VersionString.new(import[:version])
95
- unless version.valid?
96
- fail "The following import version is not in a valid format: #{import}"
97
- end
98
- if version.latest?
99
- fail "Latest is not allowed as an import version in production: #{import}"
100
- end
101
- end
102
-
103
- if File.exist?("#{Origen.root}/Gemfile")
104
- File.readlines("#{Origen.root}/Gemfile").each do |line|
105
- # http://rubular.com/r/yNGDGB6M2r
106
- if line =~ /^\s*gem\s+(("|')\w+("|')),.*(:path\s*=>|path:)/
107
- fail "The following gem is defined as a path in your Gemfile, but that is not allowed in production: #{Regexp.last_match[1]}"
108
- end
109
- end
110
- end
111
- end
112
- end
113
-
114
- # Returns the version of the given plugin that is installed
115
- def plugin_version(plugin_name)
116
- load File.join(origen_root_for(imports[plugin_name]), 'config', 'version.rb')
117
- Origen::VersionString.new(Origen.import_manager.plugin_instance(plugin_name).class::VERSION)
118
- end
119
-
120
- # Returns the app instance of the given plugin name
121
- def plugin_instance(name)
122
- Origen.application_instance(origen_root_for(imports[name]))
123
- end
124
-
125
- # Returns an array of symbols that represent the names of all imports
126
- def names
127
- return @names if @names
128
- names = Origen.plugins.map(&:name)
129
- # Had a bug where this was caching too early, don't cache until all plugins are loaded
130
- @names = names if Origen.app_loaded?
131
- names
132
- end
133
-
134
- # Returns a hash containing all imports
135
- def named_imports
136
- imports
137
- end
138
-
139
- # Returns the path to origen root for the given import name
140
- def origen_root(name)
141
- origen_root_for(named_imports[name])
142
- end
143
-
144
- # Handles all symlink creation since Ruby/Windows is ropey. On windows it will create
145
- # an additional flag file to easily tell us a symlink is active later.
146
- # @api private
147
- def create_symlink(from, to)
148
- if Origen.running_on_windows?
149
- system("call mklink /D #{to.to_s.gsub('/', '\\')} #{from.to_s.gsub('/', '\\')}")
150
- File.new("#{to}_is_a_symlink", 'w') {}
151
- else
152
- FileUtils.symlink from, to
153
- end
154
- end
155
-
156
- # Manually handle symlink deletion to support windows
157
- # @api private
158
- def delete_symlink(path)
159
- if Origen.running_on_windows?
160
- # Don't use regular rm on windows symlink, will delete into the remote dir!
161
- system("call cmd /c rmdir #{path.to_s.gsub('/', '\\')}")
162
- FileUtils.rm_f("#{path}_is_a_symlink")
163
- else
164
- FileUtils.rm_f(path)
165
- end
166
- end
167
-
168
- # Returns true if the given path is a symlink. Since Ruby's handling of symlinks is ropey
169
- # we will manually maintain a flag (an empty file that means true when present) to indicate
170
- # when an import is currently setup as a symlink to a path.
171
- # @api private
172
- def symlink?(path)
173
- if Origen.running_on_windows?
174
- File.exist?("#{path}_is_a_symlink")
175
- else
176
- File.symlink?(path)
177
- end
178
- end
179
-
180
- # Returns true if the given file is a symlink and a link to a file
181
- # within the application's imports directory, generally this can be used
182
- # to identify symlinks which have been added by the imports/plugin manager
183
- # to expose the pattern/program/templates directories of plugins
184
- def symlink_to_imports_dir?(path)
185
- if Origen.running_on_windows?
186
- # Not sure how to do this yet on windows, for now just defaulting
187
- # to the original behavior of testing if it is a symlink
188
- symlink?(path)
189
- else
190
- if File.symlink?(path)
191
- !!(File.readlink(path) =~ /^#{ws.imports_directory}/)
192
- end
193
- end
194
- end
195
-
196
- # Return the plugin name if the path specified is
197
- # from that plugin
198
- def path_within_a_plugin(path)
199
- ret_value = nil
200
- names.each do |plugin|
201
- subpath = path.slice(/.*\/#{plugin.to_s}/)
202
- if subpath && symlink?(subpath)
203
- ret_value = (plugin.to_sym if plugin.class != Symbol) || plugin
204
- break
205
- end
206
- end
207
- ret_value
208
- end
209
-
210
- # Returns a list of paths which are symlinks within the supplied dir
211
- def symlinks_in_dir(dir)
212
- list = []
213
- if File.exist?(dir)
214
- Dir.entries(dir).each do |file|
215
- if symlink_to_imports_dir?("#{dir}/#{file}")
216
- list << "#{dir}/#{file}"
217
- end
218
- end
219
- end
220
- list
221
- end
222
-
223
- # Returns all symlinks created by adding plugins
224
- # Usage right now is to mask these links in unmanaged files.
225
- def all_symlinks
226
- links = []
227
- SHARED_CONTENTS_TYPES.each do |type|
228
- links << symlinks_in_dir("#{type}") unless type == :command_launcher
229
- end
230
- links.flatten.uniq.compact
231
- end
232
-
233
- # Deletes any symlink pointing to the shared content of the
234
- # specified plugin
235
- def delete_symlinks_of_plugin(plugin)
236
- SHARED_CONTENTS_TYPES.each do |type|
237
- unless type == :command_launcher
238
- link = "#{Origen.root}/#{type}/#{plugin.name}"
239
- if File.exist?(link)
240
- delete_symlink(link) if symlink?(link)
241
- end
242
- end
243
- end
244
- end
245
-
246
- def command_launcher
247
- @command_launcher ||= []
248
- end
249
-
250
- private
251
-
252
- # Returns the name of the given import (a lower cased symbol)
253
- def name_of(import)
254
- vault = import[:vault].dup
255
- vault.gsub!(/(\/|\\)tool_data(\/|\\)origen.*$/, '')
256
- if import[:app_path]
257
- path = import[:app_path]
258
- path = "/#{path}" unless path[0] == '/'
259
- vault.gsub! path, ''
260
- end
261
- name = vault.split('/').last.downcase.to_sym
262
- end
263
-
264
- def require_environments!
265
- resolve_imports
266
- ordered_imports.reverse_each do |name|
267
- root = origen_root_for(imports[name.to_sym])
268
- Origen.with_origen_root(root) do
269
- require root.join('config', 'environment')
270
- end
271
- end
272
- end
273
-
274
- def add_libs_to_load_path!
275
- imports.each do |_name, import|
276
- root = origen_root_for(import)
277
- [root.join('lib'), root.join('vendor', 'lib')].each do |path|
278
- $LOAD_PATH.unshift(path.to_s) if File.exist?(path) && !$LOAD_PATH.include?(path.to_s)
279
- end
280
- end
281
- end
282
-
283
- # Reads config.shared from the given plugin and returns the types of contents
284
- # that are shared.
285
- def shared_types(plugin_name)
286
- types = []
287
- shared = plugin_instance(plugin_name).config.shared
288
- if shared
289
- shared.each do |type, _data|
290
- types << check_type(type) if check_type(type)
291
- end
292
- end
293
- types
294
- end
295
-
296
- # Checks whether the shared content type is valid or not
297
- def check_type(type)
298
- type = :pattern if type == :patterns
299
- type = :program if type == :programs
300
- type = :templates if type == :template
301
- if SHARED_CONTENTS_TYPES.include?(type)
302
- return type
303
- end
304
- end
305
-
306
- def remove_unwanted_symlinks!
307
- SHARED_CONTENTS_TYPES.each do |type|
308
- symlinks = symlinks_in_dir("#{Origen.root}/#{type}") unless type == :command_launcher
309
- if symlinks
310
- symlinks.each do |symlink|
311
- plugin = path_within_a_plugin(symlink)
312
- unless plugin && shared_types(plugin) && shared_types(plugin).include?(type)
313
- delete_symlink(symlink)
314
- end
315
- end
316
- end
317
- end
318
- end
319
-
320
- # Removes symlinks of all plugins, irrespective of whether it is active or not.
321
- def remove_all_symlinks!
322
- remove_unwanted_symlinks!
323
- Origen.plugins.each do |plugin|
324
- delete_symlinks_of_plugin(plugin)
325
- end
326
- end
327
-
328
- # Adds symlinks of shared contents from imported plugins and includes shared commands
329
- def add_shared_contents!
330
- [Origen.app, Origen.plugins].flatten.each do |plugin|
331
- shared_content = plugin.config.shared
332
- if shared_content
333
- shared_content.each do |type, data|
334
- type = check_type(type)
335
- if type && type != :command_launcher
336
- # Disabling symlinks, too hard to manage and a direct root into the gem bundle seems
337
- # too dangerous
338
- # if File.exist?("#{plugin.root}/#{data}")
339
- # FileUtils.mkdir_p("#{Origen.root}/#{type}") unless File.exist?("#{Origen.root}/#{type}")
340
- # unless File.exist?("#{Origen.root}/#{type}/#{plugin.name}/")
341
- # create_symlink("#{plugin.root}/#{data}", "#{Origen.root}/#{type}/#{plugin.name}")
342
- # end
343
- # else
344
- # fail "Invalid path to #{type} dir in shared content of plugin #{plugin.name}!"
345
- # end
346
- elsif type == :command_launcher
347
- command_launcher << "#{plugin.root}/#{data}"
348
- else
349
- # ignore anything else
350
- if Origen.config.strict_errors
351
- puts "Unrecognized shared content type #{type} of plugin #{plugin.name}"
352
- fail 'Invalid shared parameter!'
353
- end
354
- end
355
- end
356
- end
357
- end
358
- end
359
-
360
- def origen_root_for(import, options = {})
361
- workspace = Pathname.new(workspace_of(import))
362
- if File.exist?("#{workspace}/config/application.rb")
363
- root = workspace
364
- elsif import[:app_path] && File.exist?("#{workspace}/#{import[:app_path]}/config/application.rb")
365
- root = workspace.join(import[:app_path])
366
- else
367
- root = workspace.join('tool_data', 'origen')
368
- end
369
- if File.exist?("#{root}/config/application.rb")
370
- root
371
- else
372
- if options[:accept_missing]
373
- nil
374
- else
375
- puts 'A problem was encountered with the following import:'
376
- puts import
377
- puts 'Please check that all vault, version or path references are correct.'
378
- puts ''
379
- puts 'If you are sure that the import is setup correctly and this error'
380
- puts 'persists, you can try running the following command to blow away'
381
- puts 'the local import cache and then try again from scratch:'
382
- puts ''
383
- puts "rm -fr #{ws.imports_directory}"
384
- puts ''
385
- fail 'Import error!'
386
- end
387
- end
388
- end
389
-
390
- def updates_required?
391
- @current_app_name = Origen.app.name
392
- @current_app = {
393
- vault: Origen.app.config.vault,
394
- path: Origen.root
395
- }
396
- resolve_imports
397
- dirty_imports.size > 0
398
- end
399
-
400
- def dirty_imports
401
- imports.select do |_name, import|
402
- dirty?(import)
403
- end
404
- end
405
-
406
- def dirty?(import)
407
- if import[:path] && path_enabled?(import)
408
- false
409
- else
410
- (!import[:path] && path_enabled?(import)) ||
411
- (import[:path] && !path_enabled?(import)) ||
412
- current_version_of(import) != import[:version]
413
- end
414
- end
415
-
416
- def current_version_of(import)
417
- ws.current_version_of(workspace_of(import))
418
- end
419
-
420
- # Returns true if the given import is currently setup as a path
421
- def path_enabled?(import)
422
- dir = workspace_of(import)
423
- File.exist?(dir) && symlink?(dir)
424
- end
425
-
426
- # Populate an array of required imports from the current application
427
- # state and resolve any duplications or conflicts.
428
- # Conflicts are resolved by the following rules:
429
- # * A path reference always wins.
430
- # * If two different paths are found an errors will be raised.
431
- # * If multiple versions of the same plugin are found the most
432
- # recent one wins.
433
- def resolve_imports
434
- @imports = {}
435
- @ordered_imports = []
436
- top_level_imports
437
- top_level_imports.each do |import|
438
- traverse_imports(import) do |import|
439
- add_import(import)
440
- end
441
- end
442
- @imports
443
- end
444
-
445
- def top_level_imports
446
- Origen.app.config.imports + Origen.app.config.imports_dev
447
- end
448
-
449
- # Walks down an import tree recursively yielding all nested imports, if
450
- # the imported application has not been populated yet then it will
451
- # not return any nested imports.
452
- #
453
- # This will also update the required origen version if a app
454
- # instance is encountered that requires a newer version than the current
455
- # version.
456
- def traverse_imports(import, &block)
457
- yield import
458
- if import_present?(import)
459
- app = Origen.application_instance(origen_root_for(import), reload: true)
460
- update_required_origen_version(app)
461
- app.config.imports.each do |import|
462
- traverse_imports(import, &block)
463
- end
464
- end
465
- end
466
-
467
- # If the given app (plugin) requires a newer Origen than the current latest
468
- # required version then the required version parameter will be updated.
469
- def update_required_origen_version(app)
470
- min = app.config.required_origen_version || app.config.min_required_origen_version
471
- max = app.config.max_required_origen_version
472
- if min
473
- if @required_origen_version
474
- latest = Origen::VersionString.new(@required_origen_version)
475
- if latest.less_than?(min)
476
- @required_origen_version = min
477
- end
478
- else
479
- @required_origen_version = min
480
- end
481
- end
482
- if max
483
- if @max_required_origen_version
484
- latest = Origen::VersionString.new(@max_required_origen_version)
485
- if latest.less_than?(max)
486
- @max_required_origen_version = max
487
- @max_lib = app.class.to_s.sub('_Application', '')
488
- end
489
- else
490
- @max_required_origen_version = max
491
- @max_lib = app.class.to_s.sub('_Application', '')
492
- end
493
- end
494
- end
495
-
496
- def imports
497
- @imports ||= resolve_imports
498
- end
499
-
500
- def ordered_imports
501
- @ordered_imports
502
- end
503
-
504
- def import_present?(import)
505
- !!origen_root_for(import, accept_missing: true)
506
- end
507
-
508
- # Conflicts are resolved by the following rules:
509
- # * A path reference always wins.
510
- # * If two different paths are found an errors will be raised.
511
- # * If multiple versions of the same plugin are found the most
512
- # recent one wins.
513
- def add_import(new)
514
- name = name_of(new)
515
- # If the current app has been imported by one of it's dev dependencies
516
- # then always use the local workspace
517
- if name == @current_app_name
518
- new = @current_app
519
- end
520
- existing = imports[name]
521
- if existing
522
- if new[:path]
523
- if existing[:path]
524
- if existing[:path] != new[:path]
525
- puts 'Cannot resolve plugin dependencies due to conflicting paths:'
526
- puts " #{name}:"
527
- puts " - #{existing[:path]}"
528
- puts " - #{new[:path]}"
529
- puts ''
530
- fail 'Import error!'
531
- end
532
- else
533
- ordered_imports.delete(name.to_s)
534
- ordered_imports.push(name.to_s)
535
- imports[name] = new
536
- end
537
- elsif existing[:version] != new[:version]
538
- existing_version = Origen::VersionString.new(existing[:version])
539
- if existing_version.less_than?(new[:version])
540
- ordered_imports.delete(name.to_s)
541
- ordered_imports.push(name.to_s)
542
- imports[name] = new
543
- end
544
- else
545
- ordered_imports.delete(name.to_s)
546
- ordered_imports.push(name.to_s)
547
- end
548
- else
549
- ordered_imports.push(name.to_s)
550
- imports[name] = new
551
- end
552
- end
553
-
554
- # Makes all dirty imports clean
555
- def update!
556
- ensure_imports_directory
557
- dirty_imports.each do |_name, import|
558
- dir = workspace_of(import)
559
- if import[:path] || path_enabled?(import)
560
- if symlink?(dir)
561
- delete_symlink(dir)
562
- else
563
- FileUtils.rm_rf(dir) if File.exist?(dir)
564
- end
565
- end
566
- if import[:path]
567
- create_symlink(import[:path], dir)
568
-
569
- else
570
- unless File.exist?("#{dir}/.initial_populate_successful")
571
- ws.build(dir, vault: import[:vault], allow_rebuild: true)
572
- ws.switch_version(dir, import[:version])
573
- `touch "#{dir}/.initial_populate_successful"`
574
- end
575
- ws.switch_version(dir, import[:version])
576
- end
577
- end
578
- end
579
-
580
- def workspace_of(import)
581
- Pathname.new("#{ws.imports_directory}/#{name_of(import)}")
582
- end
583
-
584
- def ensure_imports_directory
585
- unless imports.empty?
586
- unless File.exist?(ws.imports_directory)
587
- FileUtils.mkdir_p(ws.imports_directory)
588
- end
589
- end
590
- end
591
-
592
- def ws
593
- Origen.app.workspace_manager
594
- end
595
- end
596
- end