origen 0.34.3 → 0.52.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. checksums.yaml +5 -5
  2. data/bin/origen +1 -231
  3. data/config/application.rb +12 -3
  4. data/config/boot.rb +2 -7
  5. data/config/commands.rb +3 -74
  6. data/config/rubocop/easy_disabled.yml +4 -0
  7. data/config/rubocop/easy_enabled.yml +0 -4
  8. data/config/rubocop/strict_disabled.yml +4 -0
  9. data/config/rubocop/strict_enabled.yml +0 -4
  10. data/config/version.rb +2 -3
  11. data/lib/origen.rb +27 -14
  12. data/lib/origen/application.rb +88 -2
  13. data/lib/origen/application/deployer.rb +3 -1
  14. data/lib/origen/application/release.rb +2 -2
  15. data/lib/origen/application/runner.rb +35 -20
  16. data/lib/origen/boot.rb +302 -0
  17. data/lib/origen/boot/api.rb +13 -0
  18. data/lib/origen/boot/app.rb +284 -0
  19. data/lib/origen/code_generators.rb +30 -10
  20. data/lib/origen/code_generators/actions.rb +244 -34
  21. data/lib/origen/code_generators/base.rb +9 -2
  22. data/lib/origen/code_generators/block.rb +203 -0
  23. data/lib/origen/code_generators/block_common.rb +100 -0
  24. data/lib/origen/code_generators/dut.rb +62 -0
  25. data/lib/origen/code_generators/feature.rb +50 -0
  26. data/lib/origen/code_generators/klass.rb +41 -0
  27. data/lib/origen/code_generators/model.rb +60 -0
  28. data/lib/origen/code_generators/module.rb +92 -0
  29. data/lib/origen/commands.rb +30 -13
  30. data/lib/origen/commands/archive.rb +175 -0
  31. data/lib/origen/commands/extract.rb +43 -0
  32. data/lib/origen/commands/generate.rb +1 -0
  33. data/lib/origen/commands/lint.rb +6 -1
  34. data/lib/origen/commands/new.rb +48 -24
  35. data/lib/origen/commands/new_resource.rb +41 -0
  36. data/lib/origen/commands/site.rb +52 -0
  37. data/lib/origen/commands/web.rb +11 -6
  38. data/lib/origen/commands_global.rb +9 -7
  39. data/lib/origen/core_ext/numeric.rb +20 -0
  40. data/lib/{option_parser → origen/core_ext/option_parser}/optparse.rb +0 -0
  41. data/lib/origen/dependencies.rb +0 -0
  42. data/lib/origen/file_handler.rb +18 -6
  43. data/lib/origen/generator.rb +19 -10
  44. data/lib/origen/generator/comparator.rb +2 -1
  45. data/lib/origen/generator/flow.rb +3 -1
  46. data/lib/origen/generator/job.rb +60 -16
  47. data/lib/origen/generator/pattern.rb +132 -72
  48. data/lib/origen/generator/pattern_finder.rb +3 -3
  49. data/lib/origen/generator/pattern_sequence.rb +201 -0
  50. data/lib/origen/generator/pattern_sequencer.rb +99 -0
  51. data/lib/origen/generator/pattern_thread.rb +175 -0
  52. data/lib/origen/loader.rb +381 -0
  53. data/lib/origen/log.rb +250 -108
  54. data/lib/origen/model.rb +22 -1
  55. data/lib/origen/model/exporter.rb +50 -10
  56. data/lib/origen/model_initializer.rb +5 -1
  57. data/lib/origen/operating_systems.rb +4 -0
  58. data/lib/origen/parameters.rb +96 -4
  59. data/lib/origen/parameters/set.rb +4 -3
  60. data/lib/origen/pins.rb +10 -8
  61. data/lib/origen/pins/pin.rb +61 -46
  62. data/lib/origen/ports/port.rb +5 -0
  63. data/lib/origen/registers.rb +5 -0
  64. data/lib/origen/registers/bit.rb +57 -53
  65. data/lib/origen/registers/bit_collection.rb +100 -43
  66. data/lib/origen/registers/msb0_delegator.rb +47 -0
  67. data/lib/origen/registers/reg.rb +114 -99
  68. data/lib/origen/revision_control.rb +1 -1
  69. data/lib/origen/revision_control/git.rb +23 -3
  70. data/lib/origen/site_config.rb +251 -60
  71. data/lib/origen/site_config/config.rb +217 -0
  72. data/lib/origen/sub_blocks.rb +106 -31
  73. data/lib/origen/top_level.rb +11 -0
  74. data/lib/origen/users/user.rb +3 -2
  75. data/lib/origen/utility/mailer.rb +42 -9
  76. data/lib/origen/value/bin_str_val.rb +1 -1
  77. data/lib/origen/value/hex_str_val.rb +1 -1
  78. data/lib/origen/version_string.rb +6 -1
  79. data/lib/tasks/gem.rake +6 -1
  80. data/origen_app_generators/Gemfile +19 -0
  81. data/origen_app_generators/Gemfile.lock +152 -0
  82. data/origen_app_generators/LICENSE +21 -0
  83. data/origen_app_generators/README.md +368 -0
  84. data/{templates/code_generators/rakefile.rb → origen_app_generators/Rakefile} +0 -0
  85. data/origen_app_generators/bin/boot.rb +39 -0
  86. data/origen_app_generators/config/application.rb +153 -0
  87. data/origen_app_generators/config/boot.rb +1 -0
  88. data/origen_app_generators/config/commands.rb +63 -0
  89. data/origen_app_generators/config/shared_commands.rb +177 -0
  90. data/origen_app_generators/config/version.rb +8 -0
  91. data/origen_app_generators/doc/history +223 -0
  92. data/origen_app_generators/lbin/bundle +105 -0
  93. data/origen_app_generators/lbin/byebug +29 -0
  94. data/origen_app_generators/lbin/coderay +29 -0
  95. data/origen_app_generators/lbin/htmldiff +29 -0
  96. data/origen_app_generators/lbin/httparty +29 -0
  97. data/origen_app_generators/lbin/httpclient +29 -0
  98. data/origen_app_generators/lbin/kramdown +29 -0
  99. data/origen_app_generators/lbin/ldiff +29 -0
  100. data/origen_app_generators/lbin/nanoc +29 -0
  101. data/origen_app_generators/lbin/nokogiri +29 -0
  102. data/origen_app_generators/lbin/origen +62 -0
  103. data/origen_app_generators/lbin/pry +29 -0
  104. data/origen_app_generators/lbin/rackup +29 -0
  105. data/origen_app_generators/lbin/rake +29 -0
  106. data/origen_app_generators/lbin/rspec +29 -0
  107. data/origen_app_generators/lbin/rubocop +29 -0
  108. data/origen_app_generators/lbin/ruby-parse +29 -0
  109. data/origen_app_generators/lbin/ruby-rewrite +29 -0
  110. data/origen_app_generators/lbin/thor +29 -0
  111. data/origen_app_generators/lbin/tilt +29 -0
  112. data/origen_app_generators/lbin/yard +29 -0
  113. data/origen_app_generators/lbin/yardoc +29 -0
  114. data/origen_app_generators/lbin/yri +29 -0
  115. data/origen_app_generators/lib/origen_app_generators.rb +125 -0
  116. data/origen_app_generators/lib/origen_app_generators/application.rb +62 -0
  117. data/origen_app_generators/lib/origen_app_generators/base.rb +257 -0
  118. data/origen_app_generators/lib/origen_app_generators/empty_application.rb +15 -0
  119. data/origen_app_generators/lib/origen_app_generators/empty_plugin.rb +15 -0
  120. data/origen_app_generators/lib/origen_app_generators/new.rb +170 -0
  121. data/origen_app_generators/lib/origen_app_generators/new_app_tests.rb +4 -0
  122. data/origen_app_generators/lib/origen_app_generators/origen_infrastructure/app_generator_plugin.rb +107 -0
  123. data/origen_app_generators/lib/origen_app_generators/plugin.rb +55 -0
  124. data/origen_app_generators/lib/origen_app_generators/test_engineering/common.rb +29 -0
  125. data/origen_app_generators/lib/origen_app_generators/test_engineering/stand_alone_application.rb +64 -0
  126. data/origen_app_generators/lib/origen_app_generators/test_engineering/test_block.rb +61 -0
  127. data/origen_app_generators/origen_app_generators.gemspec +33 -0
  128. data/{templates/code_generators → origen_app_generators/spec}/spec_helper.rb +0 -0
  129. data/origen_app_generators/target/debug.rb +8 -0
  130. data/origen_app_generators/target/default.rb +8 -0
  131. data/origen_app_generators/target/production.rb +0 -0
  132. data/origen_app_generators/templates/app_generators/application/.gitignore +37 -0
  133. data/origen_app_generators/templates/app_generators/application/.irbrc +9 -0
  134. data/origen_app_generators/templates/app_generators/application/.rspec +1 -0
  135. data/origen_app_generators/templates/app_generators/application/.travis.yml +11 -0
  136. data/origen_app_generators/templates/app_generators/application/Gemfile +34 -0
  137. data/origen_app_generators/templates/app_generators/application/Rakefile +7 -0
  138. data/origen_app_generators/templates/app_generators/application/app/blocks/top_level.rb +12 -0
  139. data/origen_app_generators/templates/app_generators/application/app/lib/module.rb +6 -0
  140. data/origen_app_generators/templates/app_generators/application/app/templates/web/index.md.erb +19 -0
  141. data/origen_app_generators/templates/app_generators/application/app/templates/web/layouts/_basic.html.erb +13 -0
  142. data/origen_app_generators/templates/app_generators/application/app/templates/web/partials/_navbar.html.erb +20 -0
  143. data/origen_app_generators/templates/app_generators/application/app/templates/web/release_notes.md.erb +5 -0
  144. data/origen_app_generators/templates/app_generators/application/config/application.rb +121 -0
  145. data/origen_app_generators/templates/app_generators/application/config/boot.rb +4 -0
  146. data/origen_app_generators/templates/app_generators/application/config/commands.rb +79 -0
  147. data/origen_app_generators/templates/app_generators/application/config/maillist_dev.txt +4 -0
  148. data/origen_app_generators/templates/app_generators/application/config/maillist_prod.txt +3 -0
  149. data/origen_app_generators/templates/app_generators/application/config/version.rb +8 -0
  150. data/origen_app_generators/templates/app_generators/application/doc/history +0 -0
  151. data/origen_app_generators/templates/app_generators/application/dot_keep +0 -0
  152. data/origen_app_generators/templates/app_generators/application/origen_core_session +2 -0
  153. data/origen_app_generators/templates/app_generators/application/spec/spec_helper.rb +44 -0
  154. data/origen_app_generators/templates/app_generators/application/target/debug.rb +8 -0
  155. data/origen_app_generators/templates/app_generators/application/target/default.rb +1 -0
  156. data/origen_app_generators/templates/app_generators/application/target/production.rb +4 -0
  157. data/origen_app_generators/templates/app_generators/new/generator.rb +102 -0
  158. data/origen_app_generators/templates/app_generators/new/info.md.erb +9 -0
  159. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/app/lib/application.rb +54 -0
  160. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/app/lib/base.rb +55 -0
  161. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/app/lib/module.rb +28 -0
  162. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/app/lib/plugin.rb +64 -0
  163. data/origen_app_generators/templates/app_generators/origen_infrastructure/app_generator_plugin/config/load_generators.rb +6 -0
  164. data/origen_app_generators/templates/app_generators/plugin/Gemfile +32 -0
  165. data/origen_app_generators/templates/app_generators/plugin/Rakefile +10 -0
  166. data/origen_app_generators/templates/app_generators/plugin/app/templates/web/index.md.erb +37 -0
  167. data/origen_app_generators/templates/app_generators/plugin/app/templates/web/partials/_navbar_external.html.erb +20 -0
  168. data/origen_app_generators/templates/app_generators/plugin/app/templates/web/partials/_navbar_internal.html.erb +20 -0
  169. data/origen_app_generators/templates/app_generators/plugin/config/boot.rb +24 -0
  170. data/origen_app_generators/templates/app_generators/plugin/gemspec.rb +43 -0
  171. data/origen_app_generators/templates/app_generators/test_engineering/environment/j750.rb +1 -0
  172. data/origen_app_generators/templates/app_generators/test_engineering/environment/uflex.rb +1 -0
  173. data/origen_app_generators/templates/app_generators/test_engineering/environment/v93k.rb +1 -0
  174. data/origen_app_generators/templates/app_generators/test_engineering/stand_alone_application/.keep +0 -0
  175. data/origen_app_generators/templates/app_generators/test_engineering/test_block/.keep +0 -0
  176. data/origen_site_config.yml +55 -5
  177. data/templates/code_generators/attributes.rb +20 -0
  178. data/templates/code_generators/class.rb +9 -0
  179. data/templates/code_generators/controller.rb +87 -0
  180. data/templates/code_generators/model.rb +21 -0
  181. data/templates/code_generators/module.rb +4 -0
  182. data/templates/code_generators/parameters.rb +19 -0
  183. data/templates/code_generators/pins.rb +28 -0
  184. data/templates/code_generators/registers.rb +20 -0
  185. data/templates/code_generators/sub_blocks.rb +24 -0
  186. data/templates/code_generators/timesets.rb +24 -0
  187. data/templates/code_generators/version.rb +0 -1
  188. data/templates/git/gitignore.erb +0 -1
  189. data/vendor/lib/models/origen/export1.rb +77 -0
  190. data/vendor/lib/models/origen/export1/block1.rb +13 -0
  191. data/vendor/lib/models/origen/export1/block1/x.rb +36 -0
  192. data/vendor/lib/models/origen/non_origen_meta_data.md +1 -0
  193. metadata +149 -68
  194. data/bin/fix_my_workspace +0 -100
  195. data/lib/c99/ate_interface.rb +0 -77
  196. data/lib/c99/nvm.rb +0 -110
  197. data/lib/c99/target/mock2.rb +0 -1
  198. data/lib/c99/target/subdir/mock3.rb +0 -1
  199. data/lib/origen/code_generators/bundler.rb +0 -17
  200. data/lib/origen/code_generators/gem_setup.rb +0 -49
  201. data/lib/origen/code_generators/rake.rb +0 -13
  202. data/lib/origen/code_generators/rspec.rb +0 -12
  203. data/lib/origen/commands/add.rb +0 -12
  204. data/lib/tasks/private/build.rake +0 -8
  205. data/templates/code_generators/gemfile_app.rb +0 -4
  206. data/templates/code_generators/gemfile_plugin.rb +0 -6
  207. data/templates/code_generators/gemspec.rb +0 -33
@@ -0,0 +1,13 @@
1
+ # Helper methods here and in the required files can be used by Origen during the bootup process.
2
+ # (e.g., in site config ERB files)
3
+ # This can be expanded as needed to provide more helpers.
4
+ module Origen
5
+ # NOTE: Gems are not allowed to be required here, only Ruby stlibs
6
+ require 'socket'
7
+ require_relative '../operating_systems'
8
+
9
+ # Platform independent means of retrieving the hostname
10
+ def self.hostname
11
+ Socket.gethostbyname(Socket.gethostname).first.downcase
12
+ end
13
+ end
@@ -0,0 +1,284 @@
1
+ require 'fileutils'
2
+ module Origen
3
+ # Provides methods for setting up, booting and
4
+ # archiving an Origen application
5
+ module Boot
6
+ # Gem executables that Origen depends on [bin name, gem name]
7
+ BIN_DEPS = [%w(rspec rspec-core), %w(nanoc nanoc), %w(yard yard),
8
+ %w(rubocop rubocop), %w(rake rake)]
9
+
10
+ BUNDLER_WARNING = '
11
+ From Origen 0.40.0 onwards, a new way of launching Origen is supported and
12
+ you are seeing this message because your application is still setup to run
13
+ the old way.
14
+
15
+ The main difference is that Origen is now launched via an Origen-owned binstub
16
+ (./lbin/origen) rather than a Bundler-owned binstub. This means that Origen can
17
+ no longer be prevented from running due to a Bundler configuration issue within
18
+ your workspace and it should mean that Origen invocation becomes more reliable.
19
+
20
+ It is recommended that you follow these instructions to upgrade your application
21
+ to the new system.
22
+
23
+ If have already done this and you are seeing this message again, then Bundler has
24
+ overwritten the binstub at ./lbin/origen and you should perform the upgrade again.
25
+
26
+ To upgrade, run the following command:
27
+
28
+ origen setup
29
+
30
+ If you ever run the `bundle` or `bundle install` commands manually, never use
31
+ the --binstubs option or it will roll you back to the old system.
32
+
33
+ Under the new system, you should check the `./lbin` directory into your source
34
+ control system, so remove it from your `.gitignore` (or equivalent) and check
35
+ it in.
36
+
37
+ When you install a new gem whose executable you want to use in your app,
38
+ generate a binstub for it via the following command:
39
+
40
+ origen new binstub some-gem-name
41
+
42
+ ______________________________________________________________________________________
43
+
44
+ '
45
+
46
+ BUNDLER_SETUP = %q(
47
+ if Origen.site_config.gem_manage_bundler
48
+ FileUtils.mkdir_p(File.join(origen_root, '.bundle'))
49
+ File.open(File.join(origen_root, '.bundle', 'config'), 'w') do |f|
50
+ f.puts '# Origen is managing this file, any local edits will be overwritten'
51
+ f.puts '# IT SHOULD NOT BE CHECKED INTO REVISION CONTROL!'
52
+ f.puts '---'
53
+ f.puts 'BUNDLE_BIN: false'
54
+ # If gems have been installed to the app, always use them
55
+ bundle_path = File.join(origen_root, 'vendor', 'gems')
56
+ if File.exist?(bundle_path)
57
+ # Only keep the gems we actually need when installing to the application, but
58
+ # don't do this when installing outside since other apps might use them
59
+ f.puts 'BUNDLE_CLEAN: true'
60
+ else
61
+ bundle_path = File.expand_path(Origen.site_config.gem_install_dir)
62
+ end
63
+ f.puts "BUNDLE_PATH: \"#{bundle_path}\""
64
+ Array(Origen.site_config.gem_build_switches).each do |build_switches|
65
+ switches = build_switches.strip.split(' ')
66
+ gem = switches.shift
67
+ f.puts "BUNDLE_BUILD__#{gem.upcase}: \"#{switches.join(' ')}\""
68
+ end
69
+ end
70
+ end
71
+ )
72
+
73
+ UPDATER_WARNING = '
74
+ The bin/fix_my_workspace script is not compatible with the new way that Origen is
75
+ launched and you should remove it from your application.
76
+
77
+ Do this by deleting bin/fix_my_workspace and also remove the origen_updater gem from
78
+ your application.
79
+
80
+ The command `origen setup` can be used in place of fix_my_workspace under the
81
+ new system, however the new system should be more robust and such workspace repairs
82
+ should no longer be required.
83
+
84
+ ______________________________________________________________________________________
85
+
86
+ '
87
+
88
+ BINSTUB =
89
+ "#!/usr/bin/env ruby
90
+ #
91
+ # This file was generated by Origen.
92
+ #
93
+
94
+ require 'rubygems'
95
+
96
+ origen_lib = File.expand_path('../../lib/origen', Gem.bin_path('origen', 'origen'))
97
+ boot = File.join(origen_lib, 'boot.rb')
98
+ ORIGEN_ROOT = File.expand_path('..', __dir__)
99
+ origen_root = ORIGEN_ROOT
100
+
101
+ # If the Origen version supports the new boot system then use it
102
+ if File.exist?(boot)
103
+ load boot
104
+
105
+ # Otherwise fall back to an (improved) old-style invocation via Bundler
106
+ else
107
+ require 'pathname'
108
+ require 'fileutils'
109
+ $_origen_invocation_pwd = Pathname.pwd
110
+ require File.join(origen_lib, 'site_config')
111
+ " + BUNDLER_SETUP + %q(
112
+ bundle_binstub = File.expand_path('../bundle', __FILE__)
113
+
114
+ if File.file?(bundle_binstub)
115
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
116
+ load(bundle_binstub)
117
+ else
118
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
119
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
120
+ end
121
+ end
122
+ require 'bundler/setup'
123
+
124
+ load Gem.bin_path('origen', 'origen')
125
+ end
126
+ )
127
+ class << self
128
+ # Boot the application at the given root
129
+ def app!(origen_root)
130
+ # This will be used to collect warnings about the user's application environment, however showing them
131
+ # will be deferred until it has been determined that the application is using Origen >= 0.40.0 - i.e. we
132
+ # don't want to start complaining to the user about existing apps until they have intentionally upgraded
133
+ # their Origen version.
134
+ warnings = []
135
+
136
+ exec_remote = ARGV.include?('--exec_remote') ? true : false
137
+ lbin_dir = File.join(origen_root, 'lbin')
138
+ origen_binstub = File.join(lbin_dir, 'origen')
139
+
140
+ unless exec_remote
141
+ if !File.exist?(origen_binstub) ||
142
+ (File.exist?(origen_binstub) && File.read(origen_binstub) !~ /This file was generated by Origen/)
143
+ warnings << BUNDLER_WARNING
144
+ elsif File.exist?(File.join(origen_root, 'bin', 'fix_my_workspace'))
145
+ warnings << UPDATER_WARNING
146
+ end
147
+
148
+ setup_bundler(origen_root)
149
+ end
150
+
151
+ boot_app = true
152
+
153
+ Dir.chdir origen_root do
154
+ # Overriding bundler here so that bundle install can be automated as required, otherwise if just call
155
+ # require 'bundler/setup' then it will exit in the event of errors
156
+ require 'bundler'
157
+ begin
158
+ Bundler.setup
159
+ rescue Gem::LoadError, Bundler::BundlerError => e
160
+ puts e
161
+ puts
162
+ if exec_remote
163
+ puts 'App failed to boot, run it locally so that this can be resolved before re-submitting to the LSF'
164
+ exit 1
165
+ end
166
+ puts 'Attempting to resolve this...'
167
+ puts
168
+
169
+ passed = false
170
+
171
+ Bundler.with_clean_env do
172
+ cmd = 'bundle install'
173
+ cmd += ' --local' if File.exist?('.origen_archive')
174
+ passed = system(cmd)
175
+ end
176
+
177
+ if passed
178
+ Bundler.with_clean_env do
179
+ exec "origen #{ARGV.join(' ')}"
180
+ end
181
+ exit 0
182
+ else
183
+ puts
184
+ puts "If you have just updated a gem version and are now getting an error that Bundler cannot find compatible versions for it then first try running 'bundle update <gemname>'."
185
+ puts "For example if you have just changed the version of origen run 'bundle update origen'."
186
+ exit 1
187
+ end
188
+ end
189
+ end
190
+ unless exec_remote
191
+ # The application's bundle is safely loaded, do a final check to make sure that Origen's
192
+ # required bin dependencies have binstubs
193
+ if BIN_DEPS.any? { |bin, gem| !File.exist?(File.join(lbin_dir, bin)) }
194
+ system "bundle binstubs #{BIN_DEPS.map { |bin, gem| gem }.join(' ')} --path #{lbin_dir} --force"
195
+ end
196
+ end
197
+ require 'origen'
198
+ warnings
199
+ end
200
+
201
+ def setup(origen_root)
202
+ create_origen_binstub(origen_root)
203
+ bundle_path = setup_bundler(origen_root)
204
+ unless File.exist?(File.join(origen_root, '.origen_archive'))
205
+ copy_system_gems(origen_root, bundle_path)
206
+ end
207
+ end
208
+
209
+ def create_origen_binstub(origen_root)
210
+ lbin_dir = File.join(origen_root, 'lbin')
211
+
212
+ FileUtils.mkdir_p(lbin_dir)
213
+ File.open(File.join(lbin_dir, 'origen'), 'w') do |f|
214
+ f.puts BINSTUB
215
+ end
216
+ FileUtils.chmod('+x', File.join(lbin_dir, 'origen'))
217
+
218
+ if Origen.os.windows?
219
+ Dir.glob("#{origen_root}/lbin/*").each do |bin|
220
+ unless bin =~ /.bat$/
221
+ bat = "#{bin}.bat"
222
+ unless File.exist?(bat)
223
+ File.open(bat, 'w') { |f| f.write('@"ruby.exe" "%~dpn0" %*') }
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ def setup_bundler(origen_root)
231
+ bundle_path = nil
232
+ eval BUNDLER_SETUP # Will update bundle_path
233
+ bundle_path
234
+ end
235
+
236
+ def copy_system_gems(origen_root, bundle_path)
237
+ if Origen.site_config.gem_use_from_system
238
+ local_gem_dir = "#{bundle_path}/ruby/#{Pathname.new(Gem.dir).basename}"
239
+ gem_dir = Pathname.new(Gem.dir)
240
+
241
+ Origen.site_config.gem_use_from_system.each do |gem, version|
242
+ begin
243
+ # This will raise an error if the system doesn't have this gem installed, that
244
+ # will be rescued below
245
+ spec = Gem::Specification.find_by_name(gem, version)
246
+
247
+ # If the spec has returned a handle to a system installed gem. If this script has been invoked through
248
+ # Bundler then it could point to some other gem dir. The only time this should occur is when switching
249
+ # from the old system to the new system, but can't work out how to fix it so just disabling in that case.
250
+ if spec.gem_dir =~ /#{gem_dir}/
251
+
252
+ local_dir = File.join(local_gem_dir, Pathname.new(spec.gem_dir).relative_path_from(gem_dir))
253
+ FileUtils.mkdir_p local_dir
254
+ FileUtils.cp_r("#{spec.gem_dir}/.", local_dir)
255
+
256
+ local_file = Pathname.new(File.join(local_gem_dir, Pathname.new(spec.cache_file).relative_path_from(gem_dir)))
257
+ FileUtils.mkdir_p local_file.dirname
258
+ FileUtils.cp(spec.cache_file, local_file)
259
+
260
+ if spec.extension_dir && File.exist?(spec.extension_dir)
261
+ local_dir = File.join(local_gem_dir, Pathname.new(spec.extension_dir).relative_path_from(gem_dir))
262
+ FileUtils.mkdir_p local_dir
263
+ FileUtils.cp_r("#{spec.extension_dir}/.", local_dir)
264
+ end
265
+
266
+ local_file = Pathname.new(File.join(local_gem_dir, Pathname.new(spec.spec_file).relative_path_from(gem_dir)))
267
+ FileUtils.mkdir_p local_file.dirname
268
+ FileUtils.cp(spec.spec_file, local_file)
269
+
270
+ puts "Copied #{gem} #{version} from the system into #{bundle_path}"
271
+
272
+ end
273
+
274
+ rescue Exception # Gem::LoadError # Rescue everything here, this is a try-our-best operation, better to
275
+ # continue and try and install the gem if this fails rather than crash
276
+ # This just means that one of the gems that should be copied from the system
277
+ # was not actually installed in the system, so nothing we can do about that here
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
283
+ end
284
+ end
@@ -29,13 +29,25 @@ module Origen
29
29
  def self.load_generators
30
30
  return if @generators_loaded
31
31
  # Load Origen's generators
32
- Dir.glob("#{Origen.top}/lib/origen/code_generators/**/*.rb").sort.each do |file|
33
- require file
34
- end
35
- # Load generators from plugins, TBD what the rules will be here
32
+ require_relative 'code_generators/block_common'
33
+ require_relative 'code_generators/dut'
34
+ require_relative 'code_generators/block'
35
+ require_relative 'code_generators/feature'
36
+ require_relative 'code_generators/model'
37
+ require_relative 'code_generators/klass'
38
+ require_relative 'code_generators/module'
39
+ # Load generators from plugins, TBD what the API will be here
36
40
  @generators_loaded = true
37
41
  end
38
42
 
43
+ # Loaded separately so as not to pollute the generated list of generators available to users
44
+ def self.load_internal_generators
45
+ return if @internal_generators_loaded
46
+ require_relative 'code_generators/semver'
47
+ require_relative 'code_generators/timever'
48
+ @internal_generators_loaded = true
49
+ end
50
+
39
51
  # Receives a namespace, arguments and the behavior to invoke the generator.
40
52
  # It's used as the default entry point for generate, destroy and update
41
53
  # commands.
@@ -47,6 +59,13 @@ module Origen
47
59
  end
48
60
  end
49
61
 
62
+ # Like invoke, but will also make internal-use only generators available
63
+ # commands.
64
+ def self.invoke_internal(name, args = ARGV, config = {})
65
+ load_internal_generators
66
+ invoke(name, args, config)
67
+ end
68
+
50
69
  def self.find_by_name(name)
51
70
  names = name.split(':')
52
71
  case names.size
@@ -61,20 +80,20 @@ module Origen
61
80
  end
62
81
  return gen if gen
63
82
  end
64
- puts "Couldn't find a feature generator named: #{name}"
83
+ puts "Couldn't find a code generator named: #{name}"
65
84
  puts
66
- puts 'This is the list of available features:'
85
+ puts 'This is the list of available generators:'
67
86
  puts
68
87
  print_generators
69
88
  puts
70
89
  end
71
90
 
72
91
  # Show help message with available generators.
73
- def self.help(command = 'add')
92
+ def self.help(command = 'new')
74
93
  puts <<-END
75
- Add pre-built features and code snippets.
94
+ Add pre-built features and code snippets to your application.
76
95
 
77
- This command will add pre-built code to your application to implement a given feature. In some
96
+ This command will generate code for your application to implement a given feature. In some
78
97
  cases this will be a complete feature and in others it will provide a starting point for you
79
98
  to further customize.
80
99
 
@@ -88,7 +107,7 @@ END
88
107
  puts ' -s, [--skip] # Skip files that already exist'
89
108
  puts ' -q, [--quiet] # Suppress status output'
90
109
  puts
91
- puts "The available features are listed below, run 'origen add <feature> -h' for more info."
110
+ puts "The available features are listed below, run 'origen new <feature> -h' for more info."
92
111
  puts
93
112
 
94
113
  print_generators
@@ -101,6 +120,7 @@ END
101
120
  puts name
102
121
  end
103
122
  plugin_generators.each do |namespace, generators|
123
+ next if namespace.to_s == 'origen_app_generators'
104
124
  puts
105
125
  generators.each do |_name, gen|
106
126
  puts "#{namespace}:#{gen}"
@@ -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