origen 0.44.0 → 0.50.0

Sign up to get free protection for your applications and to get access to all the features.
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