origen 0.44.0 → 0.50.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/config/application.rb +2 -2
  3. data/config/boot.rb +0 -7
  4. data/config/commands.rb +3 -74
  5. data/config/rubocop/easy_disabled.yml +4 -0
  6. data/config/rubocop/easy_enabled.yml +0 -4
  7. data/config/rubocop/strict_disabled.yml +4 -0
  8. data/config/rubocop/strict_enabled.yml +0 -4
  9. data/config/version.rb +1 -2
  10. data/lib/origen/application/deployer.rb +3 -1
  11. data/lib/origen/application/release.rb +2 -2
  12. data/lib/origen/application/runner.rb +9 -2
  13. data/lib/origen/application.rb +91 -2
  14. data/lib/origen/boot/app.rb +0 -4
  15. data/lib/origen/boot.rb +2 -1
  16. data/lib/origen/code_generators/actions.rb +244 -34
  17. data/lib/origen/code_generators/base.rb +9 -2
  18. data/lib/origen/code_generators/block.rb +203 -0
  19. data/lib/origen/code_generators/block_common.rb +100 -0
  20. data/lib/origen/code_generators/dut.rb +62 -0
  21. data/lib/origen/code_generators/feature.rb +50 -0
  22. data/lib/origen/code_generators/klass.rb +41 -0
  23. data/lib/origen/code_generators/model.rb +60 -0
  24. data/lib/origen/code_generators/module.rb +92 -0
  25. data/lib/origen/code_generators.rb +30 -10
  26. data/lib/origen/commands/lint.rb +6 -1
  27. data/lib/origen/commands/new.rb +1 -1
  28. data/lib/origen/commands/new_resource.rb +41 -0
  29. data/lib/origen/commands/web.rb +11 -6
  30. data/lib/origen/commands.rb +18 -0
  31. data/lib/{option_parser → origen/core_ext/option_parser}/optparse.rb +0 -0
  32. data/lib/origen/dependencies.rb +0 -0
  33. data/lib/origen/file_handler.rb +8 -4
  34. data/lib/origen/generator/pattern_finder.rb +3 -3
  35. data/lib/origen/loader.rb +377 -0
  36. data/lib/origen/model.rb +22 -1
  37. data/lib/origen/model_initializer.rb +5 -1
  38. data/lib/origen/parameters/set.rb +2 -1
  39. data/lib/origen/parameters.rb +95 -3
  40. data/lib/origen/sub_blocks.rb +21 -7
  41. data/lib/origen/top_level.rb +11 -0
  42. data/lib/origen.rb +3 -1
  43. data/origen_app_generators/Gemfile +6 -2
  44. data/origen_app_generators/Gemfile.lock +83 -72
  45. data/origen_app_generators/bin/boot.rb +4 -2
  46. data/origen_app_generators/config/commands.rb +3 -3
  47. data/origen_app_generators/config/shared_commands.rb +11 -6
  48. data/origen_app_generators/lbin/bundle +105 -0
  49. data/origen_app_generators/lbin/byebug +29 -0
  50. data/origen_app_generators/lbin/coderay +29 -0
  51. data/origen_app_generators/lbin/htmldiff +29 -0
  52. data/origen_app_generators/lbin/httparty +29 -0
  53. data/origen_app_generators/lbin/httpclient +29 -0
  54. data/origen_app_generators/lbin/kramdown +29 -0
  55. data/origen_app_generators/lbin/ldiff +29 -0
  56. data/origen_app_generators/lbin/nanoc +29 -0
  57. data/origen_app_generators/lbin/nokogiri +29 -0
  58. data/origen_app_generators/lbin/origen +62 -0
  59. data/origen_app_generators/lbin/pry +29 -0
  60. data/origen_app_generators/lbin/rackup +29 -0
  61. data/origen_app_generators/lbin/rake +29 -0
  62. data/origen_app_generators/lbin/rspec +29 -0
  63. data/origen_app_generators/lbin/rubocop +29 -0
  64. data/origen_app_generators/lbin/ruby-parse +29 -0
  65. data/origen_app_generators/lbin/ruby-rewrite +29 -0
  66. data/origen_app_generators/lbin/thor +29 -0
  67. data/origen_app_generators/lbin/tilt +29 -0
  68. data/origen_app_generators/lbin/yard +29 -0
  69. data/origen_app_generators/lbin/yardoc +29 -0
  70. data/origen_app_generators/lbin/yri +29 -0
  71. data/origen_app_generators/lib/origen_app_generators/application.rb +12 -12
  72. data/origen_app_generators/lib/origen_app_generators/base.rb +34 -8
  73. data/origen_app_generators/lib/origen_app_generators/new.rb +17 -9
  74. data/origen_app_generators/lib/{tasks/new_app_tests.rake → origen_app_generators/new_app_tests.rb} +1 -5
  75. data/origen_app_generators/lib/origen_app_generators/origen_infrastructure/app_generator_plugin.rb +6 -8
  76. data/origen_app_generators/lib/origen_app_generators/plugin.rb +4 -7
  77. data/origen_app_generators/lib/origen_app_generators/test_engineering/common.rb +29 -0
  78. data/origen_app_generators/lib/origen_app_generators/test_engineering/stand_alone_application.rb +9 -181
  79. data/origen_app_generators/lib/origen_app_generators/test_engineering/test_block.rb +4 -105
  80. data/origen_app_generators/lib/origen_app_generators.rb +6 -4
  81. data/origen_app_generators/origen_app_generators.gemspec +7 -7
  82. data/origen_app_generators/templates/app_generators/application/Gemfile +14 -3
  83. data/origen_app_generators/templates/app_generators/application/{lib → app/blocks}/top_level.rb +1 -1
  84. data/origen_app_generators/templates/app_generators/application/app/lib/module.rb +6 -0
  85. data/origen_app_generators/templates/app_generators/application/{templates → app/templates}/web/index.md.erb +0 -0
  86. data/origen_app_generators/templates/app_generators/application/{templates → app/templates}/web/layouts/_basic.html.erb +0 -0
  87. data/origen_app_generators/templates/app_generators/application/{templates → app/templates}/web/partials/_navbar.html.erb +0 -0
  88. data/origen_app_generators/templates/app_generators/application/{templates → app/templates}/web/release_notes.md.erb +0 -0
  89. data/origen_app_generators/templates/app_generators/application/config/application.rb +51 -55
  90. data/origen_app_generators/templates/app_generators/application/{spec → test/spec}/spec_helper.rb +0 -0
  91. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/{lib → app/lib}/application.rb +0 -0
  92. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/{lib → app/lib}/base.rb +0 -0
  93. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/{lib → app/lib}/module.rb +0 -0
  94. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/{lib → app/lib}/plugin.rb +0 -0
  95. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/config/load_generators.rb +1 -1
  96. data/origen_app_generators/templates/app_generators/plugin/Gemfile +5 -2
  97. data/origen_app_generators/templates/app_generators/plugin/{templates → app/templates}/web/index.md.erb +0 -0
  98. data/origen_app_generators/templates/app_generators/plugin/{templates → app/templates}/web/partials/_navbar_external.html.erb +0 -0
  99. data/origen_app_generators/templates/app_generators/plugin/{templates → app/templates}/web/partials/_navbar_internal.html.erb +0 -0
  100. data/origen_app_generators/templates/app_generators/plugin/gemspec.rb +4 -3
  101. data/origen_app_generators/templates/app_generators/test_engineering/{stand_alone_application/environment → environment}/j750.rb +0 -0
  102. data/origen_app_generators/templates/app_generators/test_engineering/{stand_alone_application/environment → environment}/uflex.rb +0 -0
  103. data/origen_app_generators/templates/app_generators/test_engineering/{stand_alone_application/environment → environment}/v93k.rb +0 -0
  104. data/origen_site_config.yml +0 -7
  105. data/templates/code_generators/attributes.rb +20 -0
  106. data/templates/code_generators/class.rb +9 -0
  107. data/templates/code_generators/controller.rb +87 -0
  108. data/templates/code_generators/model.rb +21 -0
  109. data/templates/code_generators/module.rb +4 -0
  110. data/templates/code_generators/parameters.rb +19 -0
  111. data/templates/code_generators/pins.rb +28 -0
  112. data/templates/code_generators/registers.rb +20 -0
  113. data/templates/code_generators/sub_blocks.rb +24 -0
  114. data/templates/code_generators/timesets.rb +24 -0
  115. data/templates/code_generators/version.rb +0 -1
  116. metadata +66 -77
  117. data/lib/c99/ate_interface.rb +0 -77
  118. data/lib/c99/nvm.rb +0 -110
  119. data/lib/c99/target/mock2.rb +0 -1
  120. data/lib/c99/target/subdir/mock3.rb +0 -1
  121. data/lib/origen/code_generators/bundler.rb +0 -17
  122. data/lib/origen/code_generators/gem_setup.rb +0 -49
  123. data/lib/origen/code_generators/rake.rb +0 -13
  124. data/lib/origen/code_generators/rspec.rb +0 -12
  125. data/lib/origen/commands/add.rb +0 -12
  126. data/lib/tasks/private/build.rake +0 -8
  127. data/origen_app_generators/bin/fix_my_workspace +0 -100
  128. data/origen_app_generators/lib/origen_app_generators/sub_block_parser.rb +0 -81
  129. data/origen_app_generators/lib/tasks/app_generators.rake +0 -6
  130. data/origen_app_generators/spec/sub_block_spec.rb +0 -36
  131. data/origen_app_generators/templates/app_generators/application/lib/app.rake +0 -6
  132. data/origen_app_generators/templates/app_generators/application/lib/module.rb +0 -22
  133. data/origen_app_generators/templates/app_generators/plugin/lib/README +0 -4
  134. data/origen_app_generators/templates/app_generators/plugin/lib_dev/README +0 -5
  135. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/Gemfile +0 -23
  136. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/environment/jlink.rb +0 -1
  137. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/lib/ip_block.rb +0 -23
  138. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/lib/ip_block_controller.rb +0 -5
  139. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/lib/top_level.rb +0 -33
  140. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/lib/top_level_controller.rb +0 -21
  141. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/pattern/example.rb +0 -4
  142. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/target/top_level.rb +0 -4
  143. data/origen_app_generators/templates/app_generators/test_engineering/test_block/environment/j750.rb +0 -2
  144. data/origen_app_generators/templates/app_generators/test_engineering/test_block/environment/ultraflex.rb +0 -2
  145. data/origen_app_generators/templates/app_generators/test_engineering/test_block/environment/v93k.rb +0 -2
  146. data/origen_app_generators/templates/app_generators/test_engineering/test_block/lib/controller.rb +0 -12
  147. data/origen_app_generators/templates/app_generators/test_engineering/test_block/lib/interface.rb +0 -21
  148. data/origen_app_generators/templates/app_generators/test_engineering/test_block/lib/model.rb +0 -18
  149. data/origen_app_generators/templates/app_generators/test_engineering/test_block/lib_dev/dut.rb +0 -27
  150. data/origen_app_generators/templates/app_generators/test_engineering/test_block/lib_dev/dut_controller.rb +0 -26
  151. data/origen_app_generators/templates/app_generators/test_engineering/test_block/pattern/example.rb +0 -5
  152. data/origen_app_generators/templates/app_generators/test_engineering/test_block/program/prb1.rb +0 -11
  153. data/origen_app_generators/templates/app_generators/test_engineering/test_block/target/default.rb +0 -2
  154. data/templates/code_generators/gemfile_app.rb +0 -4
  155. data/templates/code_generators/gemfile_plugin.rb +0 -6
  156. data/templates/code_generators/gemspec.rb +0 -33
  157. data/templates/code_generators/rakefile.rb +0 -10
  158. data/templates/code_generators/spec_helper.rb +0 -49
@@ -1,13 +1,18 @@
1
1
  require 'open-uri'
2
- require 'rbconfig'
2
+ require 'set'
3
3
 
4
4
  module Origen
5
5
  module CodeGenerators
6
+ # Common helpers available to all Origen code generators.
7
+ # Some of these have been copied from Rails and don't make a lot of sense in an Origen context,
8
+ # however they are being kept around for now as they serve as good examples of how to write
9
+ # generator helpers.
6
10
  module Actions
7
11
  def initialize(*args) # :nodoc:
8
12
  if args.last.is_a?(Hash)
9
13
  @config = args.last.delete(:config) || {}
10
14
  end
15
+ @required_acronyms = Set.new
11
16
  super
12
17
  @in_group = nil
13
18
  end
@@ -16,13 +21,77 @@ module Origen
16
21
  @config
17
22
  end
18
23
 
24
+ def underscored_app_namespace
25
+ Origen.app.namespace.to_s.underscore
26
+ end
27
+
28
+ # Equivalent to calling name.camelcase, but this will identify the need to register any acronyms
29
+ # necessary to ensure the camelcased name can be translated back to the original name by the
30
+ # underscore method.
31
+ # The required acronyms will be saved to an instance variable, @required_acronyms, and calling
32
+ # the add_acronyms will add the code to register them to the current application.
33
+ def camelcase(name)
34
+ name = name.to_s
35
+ name.split('_').each do |n|
36
+ # Numbers won't be recognized as a split point when going back to underscore, so need to
37
+ # register this field beginning with a number as an acronym
38
+ @required_acronyms << n if n =~ /^\d/
39
+ end
40
+ name.camelcase
41
+ end
42
+
43
+ def add_acronyms
44
+ unless @required_acronyms.empty?
45
+ top_level_file = File.join('app', 'lib', "#{underscored_app_namespace}.rb")
46
+ if File.exist?(top_level_file)
47
+ require_origen = "require 'origen'\n"
48
+ prepend_to_file top_level_file, require_origen
49
+ comment = "# The following acronyms are required to ensure that auto-loading works\n# properly with some of this application's class names\n"
50
+ insert_into_file top_level_file, comment, after: require_origen
51
+ @required_acronyms.each do |acronym|
52
+ insert_into_file top_level_file, "Origen.register_acronym '#{acronym}'\n", after: comment
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ # Adds an autoload statement for the given resource name into +app/lib/my_app_name.rb+
59
+ #
60
+ # An array of namespaces can optionally be supplied in the arguments. The name and namespaces
61
+ # should all be lower cased and underscored.
62
+ #
63
+ # add_autoload "my_model", namespaces: ["my_namespace", "my_other_namespace"]
64
+ def add_autoload(name, options = {})
65
+ namespaces = Array(options[:namespaces])
66
+ # Remove the app namespace if present, we will add the autoload inside the top-level module block
67
+ namespaces.shift if namespaces.first == app_namespace
68
+ top_level_file = File.join('app', 'lib', "#{underscored_app_namespace}.rb")
69
+ if namespaces.empty?
70
+ line = " autoload :#{camelcase(name)}, '#{underscored_app_namespace}/#{name}'\n"
71
+ insert_into_file top_level_file, line, after: /module #{Origen.app.namespace}\n/
72
+ else
73
+ contents = File.read(top_level_file)
74
+ regex = "module #{Origen.app.namespace}\s*(#.*)?\n"
75
+ indent = ''
76
+ namespaces.each do |namespace|
77
+ indent += ' '
78
+ new_regex = regex + "(\n|.)*^\s*module #{camelcase(namespace)}\s*(#.*)?\n"
79
+ unless contents =~ Regexp.new(new_regex)
80
+ lines = "#{indent}module #{camelcase(namespace)}\n"
81
+ lines << "#{indent}end\n"
82
+ insert_into_file top_level_file, lines, after: Regexp.new(regex), force: true
83
+ end
84
+ regex = new_regex
85
+ end
86
+ line = "#{indent} autoload :#{camelcase(name)}, '#{underscored_app_namespace}/#{namespaces.join('/')}/#{name}'\n"
87
+ insert_into_file top_level_file, line, after: Regexp.new(regex)
88
+ end
89
+ end
90
+
19
91
  # Removes (comments out) the specified configuration setting from +config/application.rb+
20
92
  #
21
93
  # comment_config :semantically_version
22
- def comment_config(*args)
23
- options = args.extract_options!
24
- name = args.first.to_s
25
-
94
+ def comment_config(name, options = {})
26
95
  # Set the message to be shown in logs
27
96
  log :comment, name
28
97
 
@@ -31,10 +100,7 @@ module Origen
31
100
  end
32
101
 
33
102
  # Adds an entry into +config/application.rb+
34
- def add_config(*args)
35
- options = args.extract_options!
36
- name, value = args
37
-
103
+ def add_config(name, value, options = {})
38
104
  # Set the message to be shown in logs
39
105
  message = name.to_s
40
106
  if value ||= options.delete(:value)
@@ -53,10 +119,7 @@ module Origen
53
119
  # gem "rspec", group: :test
54
120
  # gem "technoweenie-restful-authentication", lib: "restful-authentication", source: "http://gems.github.com/"
55
121
  # gem "rails", "3.0", git: "git://github.com/rails/rails"
56
- def gem(*args)
57
- options = args.extract_options!
58
- name, version = args
59
-
122
+ def gem(name, version, options = {})
60
123
  # Set the message to be shown in logs. Uses the git repo if one is given,
61
124
  # otherwise use name (version).
62
125
  parts, message = [quote(name)], name
@@ -129,7 +192,7 @@ module Origen
129
192
  data = yield if !data && block_given?
130
193
 
131
194
  in_root do
132
- if options[:env].nil?
195
+ if options[:env].nil?.map(&:camelcase).join('::')
133
196
  inject_into_file 'config/application.rb', "\n #{data}", after: sentinel, verbose: false
134
197
  else
135
198
  Array(options[:env]).each do |env|
@@ -200,18 +263,6 @@ module Origen
200
263
  in_root { run_ruby_script("bin/rails generate #{what} #{argument}", verbose: false) }
201
264
  end
202
265
 
203
- # Runs the supplied rake task
204
- #
205
- # rake("db:migrate")
206
- # rake("db:migrate", env: "production")
207
- # rake("gems:install", sudo: true)
208
- def rake(command, options = {})
209
- log :rake, command
210
- env = options[:env] || ENV['RAILS_ENV'] || 'development'
211
- sudo = options[:sudo] && RbConfig::CONFIG['host_os'] !~ /mswin|mingw/ ? 'sudo ' : ''
212
- in_root { run("#{sudo}#{extify(:rake)} #{command} RAILS_ENV=#{env}", verbose: false) }
213
- end
214
-
215
266
  # Reads the given file at the source root and prints it in the console.
216
267
  #
217
268
  # readme "README"
@@ -219,6 +270,168 @@ module Origen
219
270
  log File.read(find_in_source_paths(path))
220
271
  end
221
272
 
273
+ # Should probably move to its own file, these are general helpers rather than actions
274
+ module Helpers
275
+ # Returns the depth of the given file, where depth is the number of modules and classes it contains
276
+ def internal_depth(file)
277
+ depth = 0
278
+ File.readlines(file).each do |line|
279
+ if line =~ /^\s*(end|def)/
280
+ return depth
281
+ elsif line =~ /^\s*(module|class)/
282
+ depth += 1
283
+ end
284
+ end
285
+ end
286
+
287
+ # Only executes the given block if the given file does not already define the given method, where the
288
+ # block would normally go on to insert the method.
289
+ #
290
+ # See the ensure_define_sub_blocks method in the sub_blocks.rb generator for a usage example.
291
+ def unless_has_method(filepath, name)
292
+ unless File.read(filepath) =~ /^\s*def #{name}(\(|\s|\n)/
293
+ yield
294
+ end
295
+ end
296
+
297
+ # Executes the given block unless the given string is lower cased and underscored and doesn't start
298
+ # with a number of contain any special characters
299
+ def unless_valid_underscored_identifier(str)
300
+ if str =~ /[^0-9a-z_]/ || str =~ /^[0-9]/
301
+ yield
302
+ end
303
+ end
304
+
305
+ def validate_resource_path(name)
306
+ name.split('/').each do |n|
307
+ unless_valid_underscored_identifier(n) do
308
+ Origen.log.error "All parts of a resource name must be lower-cased, underscored and start with letter, '#{n}' is invalid"
309
+ exit 1
310
+ end
311
+ end
312
+ name
313
+ end
314
+ alias_method :validate_resource_name, :validate_resource_path
315
+
316
+ # Converts a path to a resource identifier, by performing the following operations on the given path:
317
+ # 1) Convert any absolute paths to relative
318
+ # 2) Removes any leading blocks/, lib/ or application namespaces
319
+ # 3) Remove any derivatives directories from the path
320
+ # 3) Removes any trailing .rb
321
+ #
322
+ # Examples:
323
+ #
324
+ # /my/code/my_app/app/blocks/dut/derivatives/falcon => dut/falcon
325
+ # app/lib/my_app/eagle.rb => eagle
326
+ def resource_path(path)
327
+ path = Pathname.new(path).expand_path.relative_path_from(Pathname.pwd).to_s
328
+ path = path.sub('.rb', '')
329
+ path = path.split('/')
330
+ from_block_dir_path = false
331
+ path.shift if path.first == 'app'
332
+ path.shift if path.first == 'lib'
333
+ if path.first == 'blocks'
334
+ path.shift
335
+ from_block_dir_path = true
336
+ end
337
+ path.shift if path.first == underscored_app_namespace
338
+ if path.include?('derivatives')
339
+ path.delete('derivatives')
340
+ from_block_dir_path = true
341
+ end
342
+ if from_block_dir_path
343
+ path.delete('sub_blocks')
344
+ path.pop if path.last == 'model'
345
+ if path.last == 'controller'
346
+ path.pop
347
+ path << "#{path.pop}_controller"
348
+ end
349
+ end
350
+ path.join('/')
351
+ end
352
+
353
+ # Returns a Pathname to the blocks directory that should contain the given class name. No checking is
354
+ # done of the name and it is assumed that it is a valid class name including the application namespace.
355
+ def class_name_to_blocks_dir(name)
356
+ name = name.split('::')
357
+ name.shift # Drop the application name
358
+ dir = Origen.root.join('app', 'blocks')
359
+ name.each_with_index do |n, i|
360
+ if i == 0
361
+ dir = dir.join(n.underscore)
362
+ else
363
+ dir = dir.join('derivatives', n.underscore)
364
+ end
365
+ end
366
+ dir
367
+ end
368
+
369
+ # Returns a Pathname to the lib directory file that should contain the given class name. No checking is
370
+ # done of the name and it is assumed that it is a valid class name including the application namespace.
371
+ def class_name_to_lib_file(name)
372
+ name = name.split('::')
373
+ dir = Origen.root.join('app', 'lib')
374
+ name.each_with_index do |n, i|
375
+ dir = dir.join(i == name.size - 1 ? "#{n.underscore}.rb" : n.underscore)
376
+ end
377
+ dir
378
+ end
379
+
380
+ def resource_path_to_blocks_dir(path)
381
+ name = resource_path(path).split('/') # Ensure this is clean, don't care about performance here
382
+ dir = Origen.root.join('app', 'blocks')
383
+ name.each_with_index do |n, i|
384
+ if i == 0
385
+ dir = dir.join(n.underscore)
386
+ else
387
+ if dir.join('sub_blocks', n.underscore).exist?
388
+ dir = dir.join('sub_blocks', n.underscore)
389
+ else
390
+ dir = dir.join('derivatives', n.underscore)
391
+ end
392
+ end
393
+ end
394
+ dir
395
+ end
396
+
397
+ def resource_path_to_lib_file(path)
398
+ name = resource_path(path).split('/') # Ensure this is clean, don't care about performance here
399
+ dir = Origen.root.join('app', 'lib', underscored_app_namespace)
400
+ name.each_with_index do |n, i|
401
+ dir = dir.join(i == name.size - 1 ? "#{n.underscore}.rb" : n.underscore)
402
+ end
403
+ dir
404
+ end
405
+
406
+ def resource_path_to_class(path)
407
+ name = resource_path(path).split('/') # Ensure this is clean, don't care about performance here
408
+ name.unshift(underscored_app_namespace)
409
+ name.map { |n| camelcase(n) }.join('::')
410
+ end
411
+
412
+ # Adds :class and :module identifiers to an array of namespaces
413
+ #
414
+ # ["my_app", "models", "bist"] => [[:module, "my_app"], [:module, "models"], [:class, "bist"]]
415
+ #
416
+ def add_type_to_namespaces(namespaces)
417
+ identifier = nil
418
+ namespaces.map do |namespace|
419
+ if identifier
420
+ identifier += "::#{camelcase(namespace)}"
421
+ else
422
+ identifier = camelcase(namespace)
423
+ end
424
+ begin
425
+ const = identifier.constantize
426
+ [const.is_a?(Class) ? :class : :module, namespace]
427
+ rescue NameError
428
+ [:module, namespace]
429
+ end
430
+ end
431
+ end
432
+ end
433
+ include Helpers
434
+
222
435
  protected
223
436
 
224
437
  # Define log for backwards compatibility. If just one argument is sent,
@@ -233,17 +446,14 @@ module Origen
233
446
  end
234
447
  end
235
448
 
236
- # Add an extension to the given name based on the platform.
237
- def extify(name)
238
- if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
239
- "#{name}.bat"
240
- else
241
- name
449
+ def in_root
450
+ Dir.chdir(Origen.root) do
451
+ yield
242
452
  end
243
453
  end
244
454
 
245
- # Surround string with single quotes if there is no quotes.
246
- # Otherwise fall back to double quotes
455
+ # Surround string with single quotes if there are no quotes,
456
+ # otherwise fall back to double quotes
247
457
  def quote(value)
248
458
  return value.inspect unless value.is_a? String
249
459
 
@@ -27,7 +27,14 @@ module Origen
27
27
  # Sets the base_name taking into account the current class namespace.
28
28
  def self.name
29
29
  @name ||= begin
30
- to_s.split('::').last.sub(/(CodeGenerator|Generator)$/, '').underscore
30
+ name = to_s.split('::').last.sub(/(CodeGenerator|Generator)$/, '').underscore
31
+ if name == 'klass'
32
+ 'class'
33
+ elsif name == 'mod'
34
+ 'module'
35
+ else
36
+ name
37
+ end
31
38
  end
32
39
  end
33
40
 
@@ -50,7 +57,7 @@ module Origen
50
57
  end
51
58
 
52
59
  def self.banner
53
- "origen add #{namespace == 'origen' ? '' : namespace + ':'}#{name} [options]"
60
+ "origen new #{namespace == 'origen' ? '' : namespace + ':'}#{name} [options]"
54
61
  end
55
62
  end
56
63
  end
@@ -0,0 +1,203 @@
1
+ module Origen
2
+ module CodeGenerators
3
+ class Block < Origen::CodeGenerators::Base
4
+ include BlockCommon
5
+
6
+ # class_option :duts, type: :boolean, desc: 'Instantiate the new sub-block in all DUT models', default: true
7
+ # class_option :instance, desc: 'The main NAME argument will be the name given to the model and the instantiated sub-block, optionally provide a different name for the instance'
8
+
9
+ def self.banner
10
+ 'origen new block [TYPE/]DERIVATIVE [BLOCK]'
11
+ end
12
+
13
+ desc <<-END
14
+ This generator creates a block (e.g. to represent RAM, ATD, Flash, DAC, etc.) and all of the associated
15
+ resources for it, e.g. a model, controller, timesets, parameters, etc.
16
+
17
+ The TYPE and DERIVATIVE names should be given in lower case (e.g. flash/flash2kb, atd/atd16), optionally with
18
+ additional parent sub-block names after the initial type.
19
+
20
+ Alternatively, a reference to an existing BLOCK can be added, in which case a nested block will be created
21
+ within that block's sub_blocks directory, rather than a primary block.
22
+ Note that nested blocks do not support derivatives or inheritance and should therefore only be used for
23
+ relatively simple entities which are tightly coupled to a parent block.
24
+
25
+ Any parent block(s) will be created if they don't exist, but they will not be modified if they do.
26
+
27
+ Examples:
28
+ origen new block atd/atd8bit # Creates app/blocks/atd/derivatives/atd8bit/...
29
+ origen new block atd/atd16bit # Creates app/blocks/atd/derivatives/atd16bit/...
30
+ origen new block nvm/flash/flash2kb # Creates app/blocks/nvm/derivatives/flash/derivatives/flash2kb/...
31
+
32
+ # Example of creating a nested sub-block
33
+ origen new block nvm/flash/flash2kb bist # Creates app/blocks/nvm/derivatives/flash/derivatives/flash2kb/sub_blocks/bist/...
34
+ END
35
+
36
+ def validate_args
37
+ if args.size > 2 || args.size == 0
38
+ msg = args.size == 0 ? 'At least one argument is' : 'No more than two arguments are'
39
+ msg << " expected by the block generator, e.g. 'origen new block atd/atd16bit', 'origen new block sampler app/blocks/atd/derivatives/atd16bit"
40
+ puts msg
41
+ exit 1
42
+ end
43
+
44
+ if args.size == 2
45
+ validate_args_common(args.last)
46
+ else
47
+ validate_args_common
48
+ end
49
+
50
+ @nested = args.size == 2
51
+ if !@nested && args.first.split('/').size == 1
52
+ msg = "You must supply a leading type to the name of the block, e.g. 'origen new block atd/atd16bit'"
53
+ puts msg
54
+ exit 1
55
+ end
56
+ if @nested && args.last.split('/').size != 1
57
+ msg = "No leading type is allowed when generating a nested block, e.g. 'origen new block sampler app/blocks/atd/derivatives/atd16bit"
58
+ puts msg
59
+ exit 1
60
+ end
61
+ end
62
+
63
+ def setup
64
+ @generate_model = true
65
+ @generate_pins = false
66
+ @generate_timesets = !@nested
67
+ @generate_parameters = !@nested
68
+ if @nested
69
+ @final_name = args.last
70
+ @fullname = resource_path_to_class(args.first)
71
+ @dir = resource_path_to_blocks_dir(args.first).join('sub_blocks', @final_name)
72
+ @namespaces = add_type_to_namespaces(@fullname.split('::').map(&:underscore))
73
+ else
74
+ extract_model_name
75
+ end
76
+ create_files
77
+ end
78
+
79
+ def instantiate_sub_block
80
+ if @nested
81
+ # First create the parent's sub_blocks.rb file if it doesn't exist
82
+ f = "#{@dir.parent}.rb"
83
+ unless File.exist?(f)
84
+ @nested = false
85
+ orig_fullname = @fullname
86
+ orig_resouce_path = @resource_path
87
+ @fullname = @fullname.split('::')
88
+ @fullname.pop
89
+ @fullname = @fullname.join('::')
90
+ @resource_path = @resource_path.split('/')
91
+ @resource_path.pop
92
+ @resource_path = @resource_path.join('/')
93
+ template 'templates/code_generators/sub_blocks.rb', f
94
+ @fullname = orig_fullname
95
+ @resource_path = orig_resouce_path
96
+ @nested = true
97
+ end
98
+
99
+ line = "sub_block :#{@final_name}, class_name: '#{@fullname}'#, base_address: 0x4000_0000"
100
+ append_to_file f, "\n#{line}"
101
+ else
102
+ @line = "sub_block :#{@final_namespaces[1]}, class_name: '#{class_name}'#, base_address: 0x4000_0000"
103
+
104
+ unless duts.empty?
105
+ puts
106
+ @dut_index = [nil]
107
+ index = 1
108
+ duts.each do |name, children|
109
+ index = print_dut(name, index, children, 0)
110
+ end
111
+ puts
112
+ puts 'DO YOU WANT TO INSTANTIATE THIS SUB-BLOCK IN YOUR DUT MODELS?'
113
+ puts
114
+ puts 'If so enter the number(s) of the DUT(s) you wish to add it to from the list above, separating multiple entries with a space'
115
+ puts '(note that adding it to a parent DUT in the hierarchy will already be adding it to all of its children).'
116
+ puts
117
+ response = ask 'Enter the DUT number(s), or just press return to skip:'
118
+
119
+ done = []
120
+ response.strip.split(/\s+/).each do |index|
121
+ index = index.to_i
122
+ target = @dut_index[index]
123
+ if target
124
+ # Don't add the sub-block to children if we've already added it to the parent, this will
125
+ # cause an already defined sub-block error since it will be added by both instantiations
126
+ unless done.any? { |c| target =~ /^#{c}::/ }
127
+ done << target
128
+ sub_blocks = class_name_to_blocks_dir(target).join('sub_blocks.rb')
129
+ unless sub_blocks.exist?
130
+ orig = @fullname
131
+ @fullname = target
132
+ template 'templates/code_generators/sub_blocks.rb', sub_blocks
133
+ @fullname = orig
134
+ end
135
+ @sub_block_instantiated = true
136
+ append_to_file sub_blocks, "\n#{@line}"
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ def completed
145
+ add_acronyms
146
+ puts
147
+ if @nested
148
+ puts 'New sub-block created and instantiated.'.green
149
+ else
150
+ if @sub_block_instantiated
151
+ puts 'New sub-block created and instantiated within your DUT(s) as:'.green + " dut.#{@final_namespaces[1]}"
152
+ else
153
+ puts 'New sub-block created, you can instantiate it within your blocks like this:'.green
154
+ puts
155
+ puts " #{@line}"
156
+ end
157
+ end
158
+ puts
159
+ end
160
+
161
+ private
162
+
163
+ def print_dut(name, index, children, offset)
164
+ @dut_index << name
165
+ puts "#{index}".ljust(2) + ': ' + (' ' * offset) + name
166
+ index += 1
167
+ children.each do |name, children|
168
+ index = print_dut(name, index, children, offset + 1)
169
+ end
170
+ index
171
+ end
172
+
173
+ # Returns a look up table for all dut blocks defined in this application (only those defined
174
+ # as blocks, as they all should be now).
175
+ # This is arranged by hierarchy.
176
+ def duts
177
+ @duts ||= begin
178
+ duts = {}
179
+ dut_dir = Pathname.new(File.join(Origen.root, 'app', 'blocks', 'dut'))
180
+ if dut_dir.exist?
181
+ name = "#{Origen.app.namespace}::DUT"
182
+ duts[name] = {}
183
+ add_derivatives(duts[name], name, dut_dir)
184
+ end
185
+ duts
186
+ end
187
+ end
188
+
189
+ def add_derivatives(duts, name, dir)
190
+ derivatives = dir.join('derivatives')
191
+ if derivatives.exist?
192
+ derivatives.children.each do |item|
193
+ if item.directory?
194
+ child_name = "#{name}::#{camelcase(item.basename)}"
195
+ duts[child_name] = {}
196
+ add_derivatives(duts[child_name], child_name, item)
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,100 @@
1
+ module Origen
2
+ module CodeGenerators
3
+ # Base generator for the DUT, block and feature generators
4
+ module BlockCommon
5
+ def validate_args_common(arg = nil)
6
+ validate_resource_name(arg || args.first)
7
+ end
8
+
9
+ def extract_model_name
10
+ @final_namespaces = args.first.downcase.split('/')
11
+
12
+ @final_name = @final_namespaces.pop
13
+ @final_name.gsub!(/\.rb/, '')
14
+
15
+ @final_namespaces.unshift('dut') if @top_level
16
+ @final_namespaces.unshift(underscored_app_namespace)
17
+
18
+ @model_path = @final_namespaces.dup
19
+ @namespaces = [[:module, @model_path.shift]]
20
+ end
21
+
22
+ def create_files
23
+ # @summary = ask 'Describe your plugin in a few words:'
24
+ @block = true
25
+ @root_class = true
26
+
27
+ # Nested sub-blocks do not support inheritance
28
+ unless @nested
29
+ dir = File.join(Origen.root, 'app', 'blocks')
30
+ @fullname = Origen.app.namespace.to_s
31
+
32
+ @model_path.each do |path|
33
+ dir = File.join(dir, path)
34
+ @name = path
35
+ @fullname += "::#{camelcase(@name)}"
36
+ @resource_path = resource_path(dir)
37
+
38
+ if @generate_model
39
+ f = File.join(dir, 'model.rb')
40
+ template 'templates/code_generators/model.rb', f unless File.exist?(f)
41
+ f = File.join(dir, 'controller.rb')
42
+ template 'templates/code_generators/controller.rb', f unless File.exist?(f)
43
+ end
44
+ if @generate_pins
45
+ f = File.join(dir, 'pins.rb')
46
+ template 'templates/code_generators/pins.rb', f unless File.exist?(f)
47
+ end
48
+ if @generate_timesets
49
+ f = File.join(dir, 'timesets.rb')
50
+ template 'templates/code_generators/timesets.rb', f unless File.exist?(f)
51
+ end
52
+ if @generate_parameters
53
+ f = File.join(dir, 'parameters.rb')
54
+ template 'templates/code_generators/parameters.rb', f unless File.exist?(f)
55
+ end
56
+ f = File.join(dir, 'registers.rb')
57
+ template 'templates/code_generators/registers.rb', f unless File.exist?(f)
58
+ f = File.join(dir, 'sub_blocks.rb')
59
+ template 'templates/code_generators/sub_blocks.rb', f unless File.exist?(f)
60
+ f = File.join(dir, 'attributes.rb')
61
+ template 'templates/code_generators/attributes.rb', f unless File.exist?(f)
62
+ dir = File.join(dir, 'derivatives')
63
+ @namespaces << [:class, path]
64
+ @root_class = false
65
+
66
+ @parent_class = @namespaces.map { |type, name| camelcase(name) }.join('::')
67
+ end
68
+
69
+ @parent_class ||= @namespaces.map { |type, name| camelcase(name) }.join('::')
70
+ end
71
+
72
+ @name = @final_name
73
+ @fullname += "::#{camelcase(@name)}"
74
+ dir = @dir || File.join(dir, @name)
75
+ @resource_path = resource_path(dir)
76
+
77
+ if @generate_model
78
+ template 'templates/code_generators/model.rb', File.join(dir, 'model.rb')
79
+ template 'templates/code_generators/controller.rb', File.join(dir, 'controller.rb')
80
+ end
81
+ if @generate_pins
82
+ template 'templates/code_generators/pins.rb', File.join(dir, 'pins.rb')
83
+ end
84
+ if @generate_timesets
85
+ template 'templates/code_generators/timesets.rb', File.join(dir, 'timesets.rb')
86
+ end
87
+ if @generate_parameters
88
+ template 'templates/code_generators/parameters.rb', File.join(dir, 'parameters.rb')
89
+ end
90
+ template 'templates/code_generators/registers.rb', File.join(dir, 'registers.rb')
91
+ template 'templates/code_generators/sub_blocks.rb', File.join(dir, 'sub_blocks.rb')
92
+ template 'templates/code_generators/attributes.rb', File.join(dir, 'attributes.rb')
93
+ end
94
+
95
+ def class_name
96
+ (@final_namespaces + Array(@name)).map { |n| camelcase(n) }.join('::')
97
+ end
98
+ end
99
+ end
100
+ end