origen_app_generators 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/config/commands.rb +13 -25
  3. data/config/version.rb +2 -2
  4. data/lib/origen_app_generators.rb +22 -6
  5. data/lib/origen_app_generators/application.rb +21 -14
  6. data/lib/origen_app_generators/base.rb +18 -3
  7. data/lib/origen_app_generators/plugin.rb +17 -2
  8. data/lib/origen_app_generators/sub_block_parser.rb +81 -0
  9. data/lib/origen_app_generators/test_engineering/stand_alone_application.rb +232 -0
  10. data/lib/origen_app_generators/test_engineering/{generic_test_block.rb → test_block.rb} +2 -2
  11. data/lib/tasks/app_generators.rake +42 -3
  12. data/lib/tasks/boot.rb +1 -1
  13. data/templates/app_generators/application/Gemfile +6 -7
  14. data/templates/app_generators/application/Rakefile +0 -4
  15. data/templates/app_generators/application/config/application.rb +8 -11
  16. data/templates/app_generators/application/config/{environment.rb → boot.rb} +0 -0
  17. data/templates/app_generators/application/config/commands.rb +11 -13
  18. data/templates/app_generators/application/origen_core_session +2 -0
  19. data/templates/app_generators/plugin/Gemfile +9 -0
  20. data/templates/app_generators/plugin/Rakefile +9 -0
  21. data/templates/app_generators/plugin/config/boot.rb +17 -0
  22. data/templates/app_generators/test_engineering/stand_alone_application/Gemfile +14 -0
  23. data/templates/app_generators/test_engineering/stand_alone_application/environment/j750.rb +1 -0
  24. data/templates/app_generators/test_engineering/stand_alone_application/environment/jlink.rb +1 -0
  25. data/templates/app_generators/test_engineering/stand_alone_application/environment/uflex.rb +1 -0
  26. data/templates/app_generators/test_engineering/stand_alone_application/environment/v93k.rb +1 -0
  27. data/templates/app_generators/test_engineering/stand_alone_application/lib/ip_block.rb +23 -0
  28. data/templates/app_generators/test_engineering/stand_alone_application/lib/ip_block_controller.rb +5 -0
  29. data/templates/app_generators/test_engineering/stand_alone_application/lib/top_level.rb +33 -0
  30. data/templates/app_generators/test_engineering/stand_alone_application/lib/top_level_controller.rb +21 -0
  31. data/templates/app_generators/test_engineering/stand_alone_application/pattern/example.rb +4 -0
  32. data/templates/app_generators/test_engineering/stand_alone_application/target/top_level.rb +8 -0
  33. data/templates/app_generators/test_engineering/{generic_test_block → test_block}/lib/interface.rb +0 -0
  34. data/templates/app_generators/test_engineering/{generic_test_block → test_block}/program/prb1.rb +0 -0
  35. data/templates/app_generators/test_engineering/{generic_test_block → test_block}/target/j750.rb +0 -0
  36. data/templates/app_generators/test_engineering/{generic_test_block → test_block}/target/ultraflex.rb +0 -0
  37. data/templates/app_generators/test_engineering/{generic_test_block → test_block}/target/v93k.rb +0 -0
  38. data/templates/web/origen_app_generators/test_engineering/generic_stand_alone_application.md.erb +9 -0
  39. metadata +28 -41
  40. data/templates/app_generators/application/config/users.rb +0 -29
  41. data/templates/app_generators/application/templates/web/archive.md.erb +0 -11
  42. data/templates/app_generators/application/templates/web/contact.md.erb +0 -36
  43. data/templates/app_generators/application/templates/web/docs/environment/definitions.md.erb +0 -17
  44. data/templates/app_generators/application/templates/web/docs/environment/installation.md.erb +0 -22
  45. data/templates/app_generators/application/templates/web/docs/environment/introduction.md.erb +0 -5
  46. data/templates/app_generators/application/templates/web/index.md.erb +0 -12
  47. data/templates/app_generators/application/templates/web/layouts/_basic.html.erb +0 -14
  48. data/templates/app_generators/application/templates/web/layouts/_doc.html.erb +0 -35
  49. data/templates/app_generators/application/templates/web/partials/_navbar.html.erb +0 -23
  50. data/templates/app_generators/application/templates/web/references.md.erb +0 -39
  51. data/templates/app_generators/application/templates/web/release_notes.md.erb +0 -5
  52. data/templates/app_generators/plugin/config/development.rb +0 -12
  53. data/templates/app_generators/plugin/templates/web/index.md.erb +0 -60
  54. data/templates/app_generators/plugin/templates/web/partials/_navbar.html.erb +0 -22
  55. data/templates/web/_history.md +0 -166
  56. data/templates/web/archive.md.erb +0 -11
  57. data/templates/web/contact.md.erb +0 -36
  58. data/templates/web/docs/developers/creating.md.erb +0 -290
  59. data/templates/web/docs/environment/installation.md.erb +0 -12
  60. data/templates/web/docs/environment/introduction.md.erb +0 -10
  61. data/templates/web/example.md.erb +0 -73
  62. data/templates/web/index.md.erb +0 -48
  63. data/templates/web/layouts/_basic.html.erb +0 -18
  64. data/templates/web/layouts/_doc.html.erb +0 -37
  65. data/templates/web/origen_app_generators/application.md.erb +0 -116
  66. data/templates/web/origen_app_generators/plugin.md.erb +0 -29
  67. data/templates/web/origen_app_generators/test_engineering/generic_test_block.md.erb +0 -16
  68. data/templates/web/partials/_navbar.html.erb +0 -22
  69. data/templates/web/release_notes.md.erb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 33cb984e45e37d72975819a593e86344319d9740
4
- data.tar.gz: 395d5c5f0168dc3440593a50205015977910755b
3
+ metadata.gz: 12f932a68b79d412af20be670cbc65b00a46a070
4
+ data.tar.gz: 1fbdec258c274fc187afabddf0541a3168db5650
5
5
  SHA512:
6
- metadata.gz: baed87490e8e0137b4d9af0234dd4bc2b73f70432866e76a40edc920c757416faaf301425110c1a09fe378d127ed2d35608cb93526c1fd05bfc45b63bad36c52
7
- data.tar.gz: 9647e1fa305fa8c0c117f19364f5b5c981ffe2ba4b1c1b1f069b218865d517235ada00de734359c5e16edf968aa28f5cc50d6614f18f3cb2560ae9ece772fb3f
6
+ metadata.gz: 76cb92b2edd4ee49d245e7a560aa98faaee5907c6e5b26dc7062b22e532a893ae5eb11ab8830616a55807dfdb34ada4706935b1b89df8d30df51d1ceab0ec4d2
7
+ data.tar.gz: f58c7cb74b8af6159e2c65cd672e37ad23f357b66b7de8a372b890898262ce8df93a4822d1c6bf68e29d45b4c7fc1d9fb6cb7de39e397a4c424da535033c92cf
data/config/commands.rb CHANGED
@@ -18,20 +18,13 @@ aliases ={
18
18
  @command = aliases[@command] || @command
19
19
 
20
20
  ## Now branch to the specific task code
21
- #case @command
22
- #
23
- ## Run the unit tests
24
- #when "specs"
25
- # ARGV.unshift "spec"
26
- # require "rspec"
27
- # # For some unidentified reason Rspec does not autorun on this version
28
- # if RSpec::Core::Version::STRING && RSpec::Core::Version::STRING == "2.11.1"
29
- # RSpec::Core::Runner.run ARGV
30
- # else
31
- # require "rspec/autorun"
32
- # end
33
- # exit 0 # This will never be hit on a fail, RSpec will automatically exit 1
34
- #
21
+ case @command
22
+
23
+ # Run the unit tests
24
+ when "specs"
25
+ require "rspec"
26
+ exit RSpec::Core::Runner.run(['spec'])
27
+
35
28
  ## Run the example-based (diff) tests
36
29
  #when "examples"
37
30
  # Origen.load_application
@@ -62,14 +55,9 @@ aliases ={
62
55
  ## You probably want to also add the command details to the help shown via
63
56
  ## origen -h, you can do this be assigning the required text to @application_commands
64
57
  ## before handing control back to Origen. Un-comment the example below to get started.
65
- #else
66
- # @application_commands = <<-EOT
67
- # specs Run the specs (tests), -c will enable coverage
68
- # examples Run the examples (tests), -c will enable coverage
69
- # EOT
70
- #
71
- # # Uncomment the following and update the path with the file
72
- # # that handles the commands that are shared from this plugin
73
- # #require "#{Origen.app_root}/config/shared_commands"
74
- #
75
- #end
58
+ else
59
+ @application_commands = <<-EOT
60
+ specs Run the specs (tests), -c will enable coverage
61
+ EOT
62
+
63
+ end
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module OrigenAppGenerators
2
2
  MAJOR = 0
3
- MINOR = 0
4
- BUGFIX = 3
3
+ MINOR = 1
4
+ BUGFIX = 0
5
5
  DEV = nil
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
@@ -6,16 +6,27 @@ require 'origen_app_generators/plugin'
6
6
  require 'origen_app_generators/generic_application'
7
7
  require 'origen_app_generators/generic_plugin'
8
8
  require 'origen_app_generators/new'
9
- require 'origen_app_generators/test_engineering/generic_test_block'
9
+ require 'origen_app_generators/test_engineering/test_block'
10
+ require 'origen_app_generators/test_engineering/stand_alone_application'
10
11
 
11
12
  module OrigenAppGenerators
12
13
  extend Origen::Utility::InputCapture
13
14
 
15
+ TEST_INPUTS = [
16
+ # Generic app
17
+ ['0', '0', :default, :default, []],
18
+ # Generic plugin
19
+ ['0', '1', :default, :default, 'A test block', 'yes', []],
20
+ # Stand alone test engineering app
21
+ ['1', '0', :default, :default, 'Falcon, Eagle', 'Falcon[ram, atd(2), comm[ram(2), osc](3)], Eagle[ram(2), atd(4)]', ['origen g example']]
22
+ ]
23
+
14
24
  # If adding any new generators manually always add them at the top, but
15
25
  # generally speaking don't, use 'rake new' to create a new generator instead
16
26
  AVAILABLE = {
17
27
  'Test Engineering' => [
18
- OrigenAppGenerators::TestEngineering::GenericTestBlock
28
+ OrigenAppGenerators::TestEngineering::TestBlock,
29
+ OrigenAppGenerators::TestEngineering::StandAloneApplication
19
30
  ]
20
31
  }
21
32
 
@@ -23,7 +34,7 @@ module OrigenAppGenerators
23
34
  puts
24
35
  puts 'CHOOSE AN ENGINEERING DOMAIN'
25
36
  puts
26
- puts "Domain specific application templates are available for the following areas (enter '0' to build a generic one)"
37
+ puts "Domain-specific application templates are available for the following areas (enter '0' to build an empty generic one)"
27
38
  puts
28
39
  i = 0
29
40
  accept = [0]
@@ -39,11 +50,16 @@ module OrigenAppGenerators
39
50
  puts
40
51
  puts "WHAT TYPE OF APPLICATION DO YOU WANT TO BUILD? (if you don't know go with 'application')"
41
52
  puts
42
- type = get_text(single: true, default: 'application', accept: %w(application plugin)).downcase.to_sym
53
+ puts '0 - Application'
54
+ puts '1 - Plugin'
55
+ puts
56
+ accept = [0, 1]
57
+ selection = get_text(single: true, accept: accept, default: 0).to_i
43
58
 
44
- if type == :application
59
+ case selection
60
+ when 0
45
61
  OrigenAppGenerators::GenericApplication.start [path]
46
- else
62
+ when 1
47
63
  OrigenAppGenerators::GenericPlugin.start [path]
48
64
  end
49
65
  else
@@ -27,8 +27,7 @@ module OrigenAppGenerators
27
27
  @filelist ||= {
28
28
  config_application: { source: 'config/application.rb' },
29
29
  config_version: { source: 'config/version.rb' },
30
- config_users: { source: 'config/users.rb' },
31
- config_environment: { source: 'config/environment.rb' },
30
+ config_boot: { source: 'config/boot.rb' },
32
31
  config_commands: { source: 'config/commands.rb' },
33
32
  doc_history: { source: 'doc/history' },
34
33
  target_debug: { source: 'target/debug.rb' },
@@ -43,19 +42,27 @@ module OrigenAppGenerators
43
42
  lib_tasks: { source: 'lib/app.rake',
44
43
  dest: "lib/tasks/#{@name}.rake" },
45
44
  spec_helper: { source: 'spec/spec_helper.rb' },
46
- web_index: { source: 'templates/web/index.md.erb' },
47
- web_basic_layout: { source: 'templates/web/layouts/_basic.html.erb' },
48
- web_doc_layout: { source: 'templates/web/layouts/_doc.html.erb' },
49
- web_navbar: { source: 'templates/web/partials/_navbar.html.erb' },
50
- web_references: { source: 'templates/web/references.md.erb' },
51
- web_archive: { source: 'templates/web/archive.md.erb' },
52
- web_contact: { source: 'templates/web/contact.md.erb' },
53
- web_release_notes: { source: 'templates/web/release_notes.md.erb' },
54
- web_defintions: { source: 'templates/web/docs/environment/definitions.md.erb' },
55
- web_installation: { source: 'templates/web/docs/environment/installation.md.erb' },
56
- web_introduction: { source: 'templates/web/docs/environment/introduction.md.erb' },
45
+ # web_index: { source: 'templates/web/index.md.erb' },
46
+ # web_basic_layout: { source: 'templates/web/layouts/_basic.html.erb' },
47
+ # web_doc_layout: { source: 'templates/web/layouts/_doc.html.erb' },
48
+ # web_navbar: { source: 'templates/web/partials/_navbar.html.erb' },
49
+ # web_references: { source: 'templates/web/references.md.erb' },
50
+ # web_archive: { source: 'templates/web/archive.md.erb' },
51
+ # web_contact: { source: 'templates/web/contact.md.erb' },
52
+ # web_release_notes: { source: 'templates/web/release_notes.md.erb' },
53
+ # web_defintions: { source: 'templates/web/docs/environment/definitions.md.erb' },
54
+ # web_installation: { source: 'templates/web/docs/environment/installation.md.erb' },
55
+ # web_introduction: { source: 'templates/web/docs/environment/introduction.md.erb' },
57
56
  rakefile: { source: 'Rakefile' },
58
- gemfile: { source: 'Gemfile' }
57
+ gemfile: { source: 'Gemfile' },
58
+ gitignore: { source: '.gitignore' },
59
+ irbrc: { source: '.irbrc' },
60
+ rspec: { source: '.rspec' },
61
+ # This sets the default mode of the new workspace to 'default'
62
+ session: { source: 'origen_core_session',
63
+ dest: '.session/origen_core',
64
+ copy: true
65
+ }
59
66
  }
60
67
  end
61
68
  end
@@ -36,6 +36,19 @@ module OrigenAppGenerators
36
36
 
37
37
  protected
38
38
 
39
+ def debugger
40
+ require 'byebug'
41
+ byebug # rubocop:disable Lint/Debugger
42
+ end
43
+
44
+ def plugin?
45
+ type == :plugin
46
+ end
47
+
48
+ def application?
49
+ !plugin?
50
+ end
51
+
39
52
  def self.title
40
53
  desc.sub(/^An? /, '').titleize
41
54
  end
@@ -96,6 +109,7 @@ module OrigenAppGenerators
96
109
  if file[:copy] || dest =~ /.erb$/
97
110
  copy_file(file[:source], dest)
98
111
  else
112
+ @options = file[:options] || {}
99
113
  template(file[:source], dest)
100
114
  end
101
115
  end
@@ -118,8 +132,9 @@ module OrigenAppGenerators
118
132
  puts "SELECT YOUR #{type.to_s.upcase}'S NAMESPACE"
119
133
  puts
120
134
  puts "All #{type} code needs to reside in a unique namespace, this prevents naming collisions with 3rd party plugins."
121
- puts 'By Ruby conventions this must start with a capital letter and should ideally be CamelCased and not use underscores'
122
- puts 'Some examples:: C40TFSNVMTester, CAPIOrigen, LS2080, ApacheOrigen'
135
+ puts 'By Ruby conventions, this must start with a capital letter and should ideally be CamelCased and not use underscores.'
136
+ # puts 'Some examples:: C40TFSNVMTester, CAPIOrigen, LS2080, ApacheOrigen'
137
+ [@namespace_advice].each { |l| puts l } if @namespace_advice
123
138
  puts
124
139
  if !proposal && @name
125
140
  proposal = @name.to_s.camelize
@@ -175,7 +190,7 @@ module OrigenAppGenerators
175
190
  puts "WHAT DO YOU WANT TO CALL YOUR NEW #{type.to_s.upcase}?"
176
191
  puts
177
192
  puts "This should be lowercased and underscored and will be used to uniquely identify your #{type} within the Origen ecosystem."
178
- puts 'Some examples: c40tfs_nvm_tester, capi_origen, ls2080, apache_origen'
193
+ [@name_advice].each { |l| puts l } if @name_advice
179
194
  puts
180
195
  valid = false
181
196
  until valid
@@ -4,7 +4,8 @@ module OrigenAppGenerators
4
4
  def get_common_user_input
5
5
  get_name_and_namespace
6
6
  get_summary
7
- get_revision_control
7
+ get_audience
8
+ # get_revision_control
8
9
  end
9
10
 
10
11
  protected
@@ -18,9 +19,11 @@ module OrigenAppGenerators
18
19
  list.delete(:web_defintions)
19
20
  list.delete(:web_installation)
20
21
  list.delete(:web_introduction)
21
- list[:config_development] = { source: 'config/development.rb' }
22
22
  list[:gemspec] = { source: 'gemspec.rb', dest: "#{@name}.gemspec" }
23
23
  list[:templates_shared] = { dest: 'templates/shared', type: :directory }
24
+ if @audience == :external
25
+ list[:travis] = { source: '.travis.yml' }
26
+ end
24
27
  list
25
28
  end
26
29
  end
@@ -32,6 +35,18 @@ module OrigenAppGenerators
32
35
  @summary = get_text(single: true)
33
36
  end
34
37
 
38
+ # Prompts the user to say whether the new plugin is intended for an internal
39
+ # or external audience (meaning it will published to rubygems.org)
40
+ def get_audience(proposal = nil)
41
+ puts
42
+ puts 'IS THIS PLUGIN GOING TO BE RELEASED TO AN EXTERNAL AUDIENCE?'
43
+ puts
44
+ puts 'By answering yes...'
45
+ puts
46
+ confirm_external = get_text(confirm: :return_boolean, default: 'no')
47
+ @audience = :external if confirm_external
48
+ end
49
+
35
50
  def type
36
51
  :plugin
37
52
  end
@@ -0,0 +1,81 @@
1
+ module OrigenAppGenerators
2
+ require 'strscan'
3
+ # Responsible for parsing something like this:
4
+ #
5
+ # "ram, osc, pll, atd(2), comms[ram(2), osc](3)"
6
+ #
7
+ # into this:
8
+ #
9
+ # {
10
+ # "RAM"=>{}, "Osc"=>{}, "PLL"=>{}, "ATD"=> {:instances=>2},
11
+ # "Comms"=>{:instances=>3, :children=>{"RAM"=>{:instances=>2}, "Osc"=>{}}}
12
+ # }
13
+ #
14
+ class SubBlockParser
15
+ def parse(str)
16
+ r = {}
17
+ split(str).each do |tag|
18
+ tag, i = extract_instances(tag)
19
+ name, children = extract_children(tag)
20
+ name = camelize(name)
21
+ r[name] = {}
22
+ r[name][:instances] = i if i
23
+ r[name][:children] = children if children
24
+ end
25
+ r
26
+ end
27
+
28
+ private
29
+
30
+ # Splits the given string by comma, but understands that nested
31
+ # commas should not be split on
32
+ def split(str)
33
+ r = []
34
+ str = StringScanner.new(str)
35
+ r << next_tag(str) until str.eos?
36
+ r
37
+ end
38
+
39
+ def next_tag(str)
40
+ v = str.scan_until(/,|\[|$/)
41
+ if v[-1] == ','
42
+ v.chop.strip
43
+ elsif v[-1] == '['
44
+ open = 1
45
+ while open > 0
46
+ v += str.scan_until(/\[|\]/)
47
+ if v[-1] == '['
48
+ open += 1
49
+ else
50
+ open -= 1
51
+ end
52
+ end
53
+ v += next_tag(str)
54
+ # End of line
55
+ else
56
+ v.strip
57
+ end
58
+ end
59
+
60
+ def extract_children(tag)
61
+ # http://rubular.com/r/plGILY2e2U
62
+ if tag.strip =~ /([^\[]*)\[(.*)\]/
63
+ [Regexp.last_match(1), parse(Regexp.last_match(2))]
64
+ else
65
+ [tag.strip, nil]
66
+ end
67
+ end
68
+
69
+ def extract_instances(tag)
70
+ if tag.strip =~ /(.*)\((\d+)\)$/
71
+ [Regexp.last_match(1), Regexp.last_match(2).to_i]
72
+ else
73
+ [tag.strip, nil]
74
+ end
75
+ end
76
+
77
+ def camelize(val)
78
+ val.strip.gsub(/\s+/, '_').camelize
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,232 @@
1
+ module OrigenAppGenerators
2
+ module TestEngineering
3
+ require 'origen_app_generators/sub_block_parser'
4
+ # Generates a generic application shell
5
+ class StandAloneApplication < Application
6
+ desc 'A stand alone test engineering application'
7
+
8
+ # Any methods that are not protected will get invoked in the order that they are
9
+ # defined when the generator is run, method naming is irrelevant unless you want
10
+ # to override a method that is defined by the parent class
11
+
12
+ def get_user_input
13
+ # The methods to get the common user input that applies to all applications will
14
+ # get called at the start automatically, you have a chance here to ask any additional
15
+ # questions that are specific to the type of application being generated
16
+ get_top_level_names
17
+ get_sub_block_names
18
+ end
19
+
20
+ def generate_files
21
+ # Calling this will build all files, directories and symlinks contained in the
22
+ # hash returned by the filelist method
23
+ build_filelist
24
+ end
25
+
26
+ def modify_files
27
+ # If you want to modify any of the generated files you can do so now, you have access
28
+ # to all of the Thor Action methods described here:
29
+ # http://www.rubydoc.info/github/wycats/thor/Thor/Actions
30
+ # See the enable method in lib/app_generators/new.rb for some examples of using these.
31
+ end
32
+
33
+ def conclude
34
+ # Print out anything you think the user should know about their new application at the end
35
+ puts "New app created at: #{destination_root}"
36
+ end
37
+
38
+ protected
39
+
40
+ def sub_block_parser
41
+ @sub_block_parser ||= SubBlockParser.new
42
+ end
43
+
44
+ def get_top_level_names
45
+ puts
46
+ puts 'NAME YOUR TOP-LEVEL DEVICE(S)'
47
+ puts
48
+ puts 'What do you want to call the top-level class that represents your device?'
49
+ puts 'By default it will be called TopLevel, but if you want this application to support multiple devices you should'
50
+ puts 'give them unique names.'
51
+ puts 'Separate multiple names with a comma: Falcon, Eagle, Vulture'
52
+ puts
53
+
54
+ valid = false
55
+ until valid
56
+ @top_level_names = get_text(single: true, default: 'TopLevel').strip.split(',').map do |name|
57
+ name.strip.gsub(/\s+/, '_').camelize
58
+ end
59
+ unless @top_level_names.empty?
60
+ # Should we check anything here?
61
+ valid = true
62
+ end
63
+ end
64
+ @top_level_names
65
+ end
66
+
67
+ def get_sub_block_names
68
+ puts
69
+ puts 'DEFINE YOUR SUB-BLOCKS'
70
+ puts
71
+ puts 'What sub-blocks does this device contain?'
72
+ puts 'You can leave this blank, but entering some details of the sub-blocks you will want to involve in your tests'
73
+ puts 'will save you some manual setup of the associated models and controllers.'
74
+ puts 'You can specify layers of hierarchy and multiple instantiations, here are some examples:'
75
+ puts
76
+ puts ' A RAM, OSC, PLL and 2 ATDs at the top-level: ram, osc, pll, atd(2)'
77
+ puts ' With 3 COMMS blocks with embedded components: ram, osc, pll, atd(2), comms[ram(2), osc](3)'
78
+ if @top_level_names.size > 1
79
+ puts
80
+ puts 'If you want different modules for each of your top-level devices you can do:'
81
+ puts
82
+ puts " #{@top_level_names[0]}[ram, atd(2)], #{@top_level_names[1]}[ram(2), atd(4)]"
83
+ end
84
+ puts
85
+
86
+ valid = false
87
+ until valid
88
+ input = get_text(single: true).strip
89
+ if input.empty?
90
+ @sub_blocks_lookup = {}
91
+ valid = true
92
+ else
93
+ begin
94
+ @sub_blocks_lookup = sub_block_parser.parse(input)
95
+ valid = true
96
+ rescue
97
+ valid = false
98
+ end
99
+ end
100
+ end
101
+ @sub_blocks_lookup
102
+ end
103
+
104
+ # Returns a hash that looks like:
105
+ #
106
+ # {"Falcon"=>{"RAM"=>{}, "ATD"=>{:instances=>2}}, "Eagle"=>{"RAM"=>{:instances=>2}, "ATD"=>{:instances=>4}}}
107
+ def top_level_sub_blocks
108
+ blocks = {}
109
+ # Make sure that each top-level object has a sub blocks assignment
110
+ if @top_level_names.any? { |n| @sub_blocks_lookup[n] }
111
+ @top_level_names.each do |name|
112
+ if @sub_blocks_lookup[name]
113
+ blocks[name] = @sub_blocks_lookup[name][:children] || {}
114
+ else
115
+ blocks[name] = {}
116
+ end
117
+ end
118
+ # Duplicate the given sub blocks to all top-level objects if none have been specified
119
+ else
120
+ @top_level_names.each do |name|
121
+ blocks[name] = @sub_blocks_lookup
122
+ end
123
+ end
124
+ blocks
125
+ end
126
+
127
+ # Returns a hash with all sub-blocks at the top-level, e.g.:
128
+ #
129
+ # {"RAM"=>{}, "ATD"=>{}, "Comms"=>{"RAM"=>{:instances=>2}, "Osc"=>{}}, "Osc"=>{}}
130
+ def sub_blocks
131
+ blocks = {}
132
+ top_level_sub_blocks.each do |top, attrs|
133
+ extract_sub_blocks(attrs) do |name, attrs|
134
+ if blocks[name]
135
+ if blocks[name] != (attrs[:children] || {})
136
+ Origen.log.warning "The app builder does not currently support different sub-block definitions for block #{name}"
137
+ Origen.log.warning 'Only the first defintion has been built'
138
+ end
139
+ else
140
+ blocks[name] = attrs[:children] || {}
141
+ end
142
+ end
143
+ end
144
+ blocks
145
+ end
146
+
147
+ def extract_sub_blocks(blocks, &block)
148
+ blocks.each do |name, attrs|
149
+ yield name, attrs
150
+ extract_sub_blocks(attrs[:children], &block) if attrs[:children]
151
+ end
152
+ end
153
+
154
+ # Defines the filelist for the generator, the default list is inherited from the
155
+ # parent class (Application).
156
+ # The filelist can contain references to generate files, directories or symlinks in the
157
+ # new application.
158
+ #
159
+ # Generally to make your generator more maintainable try and re-use as much as possible
160
+ # from the parent generator, this means that your generator will automatically stay up
161
+ # to date with the latest conventions
162
+ #
163
+ # The master templates live in templates/app_generators/application, but
164
+ # DO NOT MODIFY THESE FILES DIRECTLY.
165
+ # Either add or remove things post-generation in the modify_files method or copy the
166
+ # master file to the equivalent sub-directory of templates/app_generators/test_engineering/generic_stand_alone_application
167
+ # which will override the version in the master directory.
168
+ #
169
+ # Additional files can be added or removed from the filelist as shown below.
170
+ def filelist
171
+ @filelist ||= begin
172
+ list = super # Always pick up the parent list
173
+ # Example of how to remove a file from the parent list
174
+ list.delete(:lib_top_level)
175
+ list.delete(:target_debug)
176
+ list.delete(:target_production)
177
+ list.delete(:target_default)
178
+ # Example of how to add a file, in this case the file will be compiled and copied to
179
+ # the same location in the new app
180
+ @top_level_names.each_with_index do |name, i|
181
+ list["top_level_model_#{i}"] = { source: 'lib/top_level.rb',
182
+ dest: "lib/#{@name}/#{name.underscore}.rb",
183
+ options: { name: name, sub_blocks: top_level_sub_blocks[name] }
184
+ }
185
+
186
+ list["top_level_controller_#{i}"] = { source: 'lib/top_level_controller.rb',
187
+ dest: "lib/#{@name}/#{name.underscore}_controller.rb",
188
+ options: { name: name }
189
+ }
190
+
191
+ list["target_#{name}"] = { source: 'target/top_level.rb',
192
+ dest: "target/#{name.underscore}.rb",
193
+ options: { name: name }
194
+ }
195
+ if i == 0
196
+ list[:target_default] = { source: "#{name.underscore}.rb", # Relative to the file being linked to
197
+ dest: 'target/default.rb', # Relative to destination_root
198
+ type: :symlink }
199
+ end
200
+ end
201
+
202
+ sub_blocks.each do |name, blocks|
203
+ list["ip_block_#{name}"] = { source: 'lib/ip_block.rb',
204
+ dest: "lib/#{@name}/#{name.underscore}.rb",
205
+ options: { name: name, sub_blocks: blocks }
206
+ }
207
+
208
+ list["ip_block_controller_#{name}"] = { source: 'lib/ip_block_controller.rb',
209
+ dest: "lib/#{@name}/#{name.underscore}_controller.rb" }
210
+ end
211
+
212
+ list[:environment_j750] = { source: 'environment/j750.rb' }
213
+ list[:environment_uflex] = { source: 'environment/uflex.rb' }
214
+ list[:environment_v93k] = { source: 'environment/v93k.rb' }
215
+ list[:environment_jlink] = { source: 'environment/jlink.rb' }
216
+ # Alternatively specifying a different destination, typically you would do this when
217
+ # the final location is dynamic
218
+ # list[:gemspec] = { source: 'gemspec.rb', dest: "#{@name}.gemspec" }
219
+ # Example of how to create a directory
220
+ # list[:pattern_dir] = { dest: "pattern", type: :directory }
221
+ # Example of how to create a symlink
222
+ list[:environment_default] = { source: 'j750.rb', # Relative to the file being linked to
223
+ dest: 'environment/default.rb', # Relative to destination_root
224
+ type: :symlink }
225
+ list[:pattern_example] = { source: 'pattern/example.rb' }
226
+ # Remember to return the final list
227
+ list
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end