padrino-gen 0.11.3 → 0.11.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/README.rdoc +1 -1
  3. data/lib/padrino-gen.rb +14 -22
  4. data/lib/padrino-gen/command.rb +4 -5
  5. data/lib/padrino-gen/generators/actions.rb +63 -48
  6. data/lib/padrino-gen/generators/app.rb +15 -17
  7. data/lib/padrino-gen/generators/app/app.rb.tt +2 -2
  8. data/lib/padrino-gen/generators/cli.rb +9 -9
  9. data/lib/padrino-gen/generators/component.rb +62 -0
  10. data/lib/padrino-gen/generators/components/actions.rb +48 -57
  11. data/lib/padrino-gen/generators/components/mocks/mocha.rb +2 -1
  12. data/lib/padrino-gen/generators/components/mocks/rr.rb +1 -1
  13. data/lib/padrino-gen/generators/components/orms/minirecord.rb +2 -2
  14. data/lib/padrino-gen/generators/components/orms/mongoid.rb +7 -7
  15. data/lib/padrino-gen/generators/components/orms/ohm.rb +3 -3
  16. data/lib/padrino-gen/generators/components/stylesheets/compass.rb +1 -1
  17. data/lib/padrino-gen/generators/components/stylesheets/compass/partials/_base.scss +5 -3
  18. data/lib/padrino-gen/generators/components/stylesheets/less.rb +1 -1
  19. data/lib/padrino-gen/generators/components/stylesheets/sass.rb +1 -1
  20. data/lib/padrino-gen/generators/components/stylesheets/scss.rb +1 -1
  21. data/lib/padrino-gen/generators/controller.rb +6 -10
  22. data/lib/padrino-gen/generators/mailer.rb +7 -11
  23. data/lib/padrino-gen/generators/migration.rb +4 -9
  24. data/lib/padrino-gen/generators/model.rb +6 -12
  25. data/lib/padrino-gen/generators/plugin.rb +9 -12
  26. data/lib/padrino-gen/generators/project.rb +18 -28
  27. data/lib/padrino-gen/generators/runner.rb +25 -25
  28. data/lib/padrino-gen/padrino-tasks/activerecord.rb +11 -12
  29. data/lib/padrino-gen/padrino-tasks/datamapper.rb +3 -3
  30. data/lib/padrino-gen/padrino-tasks/mongoid.rb +9 -9
  31. data/lib/padrino-gen/padrino-tasks/mongomapper.rb +4 -5
  32. data/lib/padrino-gen/padrino-tasks/sequel.rb +1 -2
  33. data/test/helper.rb +1 -1
  34. data/test/test_component_generator.rb +85 -0
  35. data/test/test_generator.rb +1 -1
  36. data/test/test_plugin_generator.rb +1 -1
  37. data/test/test_project_generator.rb +11 -4
  38. metadata +12 -15
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8ab4eea6e67ab8f8b201278704e124704844cade
4
+ data.tar.gz: ed5c452b5c97cd8c00475e6d30956df6962b7de4
5
+ SHA512:
6
+ metadata.gz: 01b7c42188cd0c6c3b79e2ef15d530d1b81159fa1098764a19199062a46a4a42044deb8534d9890cedd60ad1f7718cf7ea6bdfc95f6ab3581bd0db674ea4d964
7
+ data.tar.gz: 44b6c205f8ff6e69bdd0a1088567e15cece7be98b1c1bf9c5433330d310dcb58bc94cfe0b65df94070adb8da8e821b6b99211c9e0f645946845530215770ddda
data/README.rdoc CHANGED
@@ -160,4 +160,4 @@ To learn more about the mailer generator, check out the guide to
160
160
 
161
161
  == Copyright
162
162
 
163
- Copyright (c) 2011 Padrino. See LICENSE for details.
163
+ Copyright (c) 2011-2013 Padrino. See LICENSE for details.
data/lib/padrino-gen.rb CHANGED
@@ -1,11 +1,11 @@
1
+ require 'active_support/ordered_hash'
1
2
  require 'padrino-core/support_lite'
2
3
  require 'padrino-core/tasks'
3
4
  require 'padrino-gen/command'
4
- require 'active_support/ordered_hash'
5
5
 
6
6
  module Padrino
7
7
  ##
8
- # This module it's used for register generators
8
+ # This module it's used for register generators.
9
9
  #
10
10
  # Can be useful for 3rd party generators:
11
11
  #
@@ -14,45 +14,42 @@ module Padrino
14
14
  # Padrino::Generators.add_generator(:custom_generator, self)
15
15
  # end
16
16
  #
17
- # Now for handle generators in padrino you need to add it to into +load_paths+
17
+ # Now for handle generators in padrino you need to add it to into +load_paths+.
18
18
  #
19
19
  # Padrino::Generators.load_paths << "custom_generator.rb"
20
20
  #
21
21
  module Generators
22
- # Defines the absolute path to the padrino source folder
22
+ # Defines the absolute path to the padrino source folder.
23
23
  DEV_PATH = File.expand_path("../../", File.dirname(__FILE__))
24
24
 
25
25
  class << self
26
26
  ##
27
- # Here we store our generators paths
27
+ # Store our generators paths.
28
28
  #
29
- # @api semipublic
30
29
  def load_paths
31
30
  @_files ||= []
32
31
  end
33
32
 
34
33
  ##
35
- # Return a ordered list of task with their class
34
+ # Return an ordered list of task with their class.
36
35
  #
37
- # @api semipublic
38
36
  def mappings
39
37
  @_mappings ||= ActiveSupport::OrderedHash.new
40
38
  end
41
39
 
42
40
  ##
43
- # Global add a new generator class to +padrino-gen+
41
+ # Global add a new generator class to +padrino-gen+.
44
42
  #
45
43
  # @param [Symbol] name
46
- # key name for generator mapping
44
+ # Key name for generator mapping.
47
45
  # @param [Class] klass
48
- # class of generator
46
+ # Class of generator.
49
47
  #
50
48
  # @return [Hash] generator mappings
51
49
  #
52
50
  # @example
53
51
  # Padrino::Generators.add_generator(:controller, Controller)
54
52
  #
55
- # @api semipublic
56
53
  def add_generator(name, klass)
57
54
  mappings[name] = klass
58
55
  end
@@ -60,7 +57,6 @@ module Padrino
60
57
  ##
61
58
  # Load Global Actions and Component Actions then all files in +load_path+.
62
59
  #
63
- # @api private
64
60
  def load_components!
65
61
  require 'padrino-gen/generators/actions'
66
62
  require 'padrino-gen/generators/components/actions'
@@ -68,15 +64,11 @@ module Padrino
68
64
  load_paths.flatten.each { |file| require file }
69
65
  end
70
66
  end
71
- end # Generators
72
- end # Padrino
67
+ end
68
+ end
73
69
 
74
- ##
75
- # We add our generators to Padrino::Generators
76
- #
77
- Padrino::Generators.load_paths << Dir[File.dirname(__FILE__) + '/padrino-gen/generators/{project,app,mailer,controller,model,migration,plugin}.rb']
70
+ # Add our generators to Padrino::Generators.
71
+ Padrino::Generators.load_paths << Dir[File.dirname(__FILE__) + '/padrino-gen/generators/{project,app,mailer,controller,model,migration,plugin,component}.rb']
78
72
 
79
- ##
80
- # We add our tasks to padrino-core
81
- #
73
+ # Add our tasks to padrino-core.
82
74
  Padrino::Tasks.files << Dir[File.dirname(__FILE__) + "/padrino-gen/padrino-tasks/**/*.rb"]
@@ -3,17 +3,16 @@ require 'padrino-core/command'
3
3
  module Padrino
4
4
  ##
5
5
  # This method return the correct location of padrino-gen bin or
6
- # exec it using Kernel#system with the given args
6
+ # exec it using Kernel#system with the given args.
7
7
  #
8
- # @param [Array<String>] args
9
- # Splat of arguments to pass to padrino-gen
8
+ # @param [Array<String>] args.
9
+ # Splat of arguments to pass to padrino-gen.
10
10
  #
11
11
  # @example
12
12
  # Padrino.bin_gen(:app, name.to_s, "-r=#{destination_root}")
13
13
  #
14
- # @api semipublic
15
14
  def self.bin_gen(*args)
16
15
  @_padrino_gen_bin ||= [Padrino.ruby_command, File.expand_path("../../../bin/padrino-gen", __FILE__)]
17
16
  system args.unshift(@_padrino_gen_bin).join(" ")
18
17
  end
19
- end # Padrino
18
+ end
@@ -6,11 +6,11 @@ module Padrino
6
6
  # Common actions needed to support project and component generation.
7
7
  #
8
8
  module Actions
9
-
10
9
  def self.included(base)
11
10
  base.extend(ClassMethods)
12
11
  end
13
12
 
13
+ ##
14
14
  # Performs the necessary generator for a given component choice.
15
15
  #
16
16
  # @param [Symbol] component
@@ -21,7 +21,6 @@ module Padrino
21
21
  # @example
22
22
  # execute_component_setup(:mock, 'rr')
23
23
  #
24
- # @api private
25
24
  def execute_component_setup(component, choice)
26
25
  return true && say_status(:skipping, "#{component} component...") if choice.to_s == 'none'
27
26
  say_status(:applying, "#{choice} (#{component})...")
@@ -29,6 +28,7 @@ module Padrino
29
28
  send("setup_#{component}") if respond_to?("setup_#{component}")
30
29
  end
31
30
 
31
+ ##
32
32
  # Returns the related module for a given component and option.
33
33
  #
34
34
  # @param [String] choice
@@ -39,7 +39,6 @@ module Padrino
39
39
  # @example
40
40
  # generator_module_for('rr', :mock)
41
41
  #
42
- # @api private
43
42
  def apply_component_for(choice, component)
44
43
  # I need to override Thor#apply because for unknow reason :verbose => false break tasks.
45
44
  path = File.expand_path(File.dirname(__FILE__) + "/components/#{component.to_s.pluralize}/#{choice}.rb")
@@ -49,6 +48,7 @@ module Padrino
49
48
  shell.padding -= 1
50
49
  end
51
50
 
51
+ ##
52
52
  # Includes the component module for the given component and choice.
53
53
  # It determines the choice using .components file.
54
54
  #
@@ -61,13 +61,13 @@ module Padrino
61
61
  # include_component_module_for(:mock)
62
62
  # include_component_module_for(:mock, 'rr')
63
63
  #
64
- # @api private
65
64
  def include_component_module_for(component, choice=nil)
66
65
  choice = fetch_component_choice(component) unless choice
67
66
  return false if choice.to_s == 'none'
68
67
  apply_component_for(choice, component)
69
68
  end
70
69
 
70
+ ##
71
71
  # Returns the component choice stored within the .component file of an application.
72
72
  #
73
73
  # @param [Symbol] component
@@ -78,11 +78,11 @@ module Padrino
78
78
  # @example
79
79
  # fetch_component_choice(:mock)
80
80
  #
81
- # @api public
82
81
  def fetch_component_choice(component)
83
82
  retrieve_component_config(destination_root('.components'))[component]
84
83
  end
85
84
 
85
+ ##
86
86
  # Set the component choice in the .component file of the application.
87
87
  #
88
88
  # @param [Symbol] key
@@ -95,7 +95,6 @@ module Padrino
95
95
  # @example
96
96
  # store_component_choice(:renderer, :haml)
97
97
  #
98
- # @api semipublic
99
98
  def store_component_choice(key, value)
100
99
  path = destination_root('.components')
101
100
  config = retrieve_component_config(path)
@@ -104,6 +103,7 @@ module Padrino
104
103
  value
105
104
  end
106
105
 
106
+ ##
107
107
  # Loads the component config back into a hash.
108
108
  #
109
109
  # @param [String] target
@@ -115,11 +115,11 @@ module Padrino
115
115
  # retrieve_component_config(...)
116
116
  # # => { :mock => 'rr', :test => 'riot', ... }
117
117
  #
118
- # @api private
119
118
  def retrieve_component_config(target)
120
119
  YAML.load_file(target)
121
120
  end
122
121
 
122
+ ##
123
123
  # Prompts the user if necessary until a valid choice is returned for the component.
124
124
  #
125
125
  # @param [Symbol] component
@@ -130,7 +130,6 @@ module Padrino
130
130
  # @example
131
131
  # resolve_valid_choice(:mock)
132
132
  #
133
- # @api private
134
133
  def resolve_valid_choice(component)
135
134
  available_string = self.class.available_choices_for(component).join(", ")
136
135
  choice = options[component]
@@ -141,6 +140,7 @@ module Padrino
141
140
  choice
142
141
  end
143
142
 
143
+ ##
144
144
  # Returns true if the option passed is a valid choice for component.
145
145
  #
146
146
  # @param [Symbol] component
@@ -153,11 +153,11 @@ module Padrino
153
153
  # @example
154
154
  # valid_choice?(:mock, 'rr')
155
155
  #
156
- # @api public
157
156
  def valid_choice?(component, choice)
158
157
  choice.present? && self.class.available_choices_for(component).include?(choice.to_sym)
159
158
  end
160
159
 
160
+ ##
161
161
  # Creates a component_config file at the destination containing all component options.
162
162
  # Content is a YAMLized version of a hash containing component name mapping to chosen value.
163
163
  #
@@ -167,7 +167,6 @@ module Padrino
167
167
  # @example
168
168
  # store_component_config('/foo/bar')
169
169
  #
170
- # @api private
171
170
  def store_component_config(destination)
172
171
  components = @_components || options
173
172
  create_file(destination) do
@@ -177,52 +176,52 @@ module Padrino
177
176
  end
178
177
  end
179
178
 
180
- # Returns the root for this thor class (also aliased as destination root).
179
+ ##
180
+ # Returns the root for this Thor class (also aliased as destination root).
181
181
  #
182
182
  # @param [Array<String>] paths
183
- # The relative path from destination rooot
183
+ # The relative path from destination root.
184
184
  #
185
185
  # @return [String] The full path
186
186
  #
187
187
  # @example
188
188
  # destination_root('config/boot.rb')
189
189
  #
190
- # @api public
191
190
  def destination_root(*paths)
192
191
  File.expand_path(File.join(@destination_stack.last, paths))
193
192
  end
194
193
 
194
+ ##
195
195
  # Returns true if inside a Padrino application.
196
196
  #
197
- # @api public
198
197
  def in_app_root?
199
198
  File.exist?(destination_root('config/boot.rb'))
200
199
  end
201
200
 
201
+ ##
202
202
  # Returns the field with an unacceptable name(for symbol) else returns nil.
203
203
  #
204
204
  # @param [Array<String>] fields
205
- # Field names for generators
205
+ # Field names for generators.
206
206
  #
207
207
  # @return [Array<String>] array of invalid fields
208
208
  #
209
209
  # @example
210
210
  # invalid_fields ['foo:bar', 'hello:world']
211
211
  #
212
- # @api semipublic
213
212
  def invalid_fields(fields)
214
213
  results = fields.select { |field| field.split(":").first =~ /\W/ }
215
214
  results.empty? ? nil : results
216
215
  end
217
216
 
217
+ ##
218
218
  # Apply default field types.
219
219
  #
220
220
  # @param [Array<String>] fields
221
- # Field names for generators
221
+ # Field names for generators.
222
222
  #
223
223
  # @return [Array<String>] fields with default types
224
224
  #
225
- # @api semipublic
226
225
  def apply_default_fields(fields)
227
226
  fields.map! { |field| field =~ /:/ ? field : "#{field}:string" }
228
227
  end
@@ -237,7 +236,6 @@ module Padrino
237
236
  # @example
238
237
  # fetch_project_name
239
238
  #
240
- # @api public
241
239
  def fetch_project_name(app='app')
242
240
  app_path = destination_root(app, 'app.rb')
243
241
  @project_name = fetch_component_choice(:namespace) if @project_name.empty?
@@ -257,6 +255,7 @@ WARNING
257
255
  end
258
256
  end
259
257
 
258
+ ##
260
259
  # Returns the app_name for the application at root.
261
260
  #
262
261
  # @param [String] app
@@ -267,12 +266,12 @@ WARNING
267
266
  # @example
268
267
  # fetch_app_name('subapp')
269
268
  #
270
- # @api public
271
269
  def fetch_app_name(app='app')
272
270
  app_path = destination_root(app, 'app.rb')
273
271
  @app_name ||= File.read(app_path).scan(/class\s(.*?)\s</).flatten[0]
274
272
  end
275
273
 
274
+ ##
276
275
  # Adds all the specified gems into the Gemfile for bundler.
277
276
  #
278
277
  # @param [Array<String>] gem_names
@@ -285,12 +284,12 @@ WARNING
285
284
  # require_dependencies('mocha', 'bacon', :group => 'test')
286
285
  # require_dependencies('json', :version => ">=1.2.3")
287
286
  #
288
- # @api public
289
287
  def require_dependencies(*gem_names)
290
288
  options = gem_names.extract_options!
291
289
  gem_names.reverse.each { |lib| insert_into_gemfile(lib, options) }
292
290
  end
293
291
 
292
+ ##
294
293
  # Inserts a required gem into the Gemfile to add the bundler dependency.
295
294
  #
296
295
  # @param [String] name
@@ -303,17 +302,17 @@ WARNING
303
302
  # insert_into_gemfile(name, :group => 'test', :require => 'foo')
304
303
  # insert_into_gemfile(name, :group => 'test', :version => ">1.2.3")
305
304
  #
306
- # @api public
307
305
  def insert_into_gemfile(name, options={})
308
306
  after_pattern = options[:group] ? "#{options[:group].to_s.capitalize} requirements\n" : "Component requirements\n"
309
307
  version = options.delete(:version)
310
- gem_options = options.map { |k, v| ":#{k} => '#{v.to_s}'" }.join(", ")
308
+ gem_options = options.map { |k, v| k.to_s == 'require' && [true,false].include?(v) ? ":#{k} => #{v}" : ":#{k} => '#{v}'" }.join(", ")
311
309
  write_option = gem_options.present? ? ", #{gem_options}" : ''
312
- write_version = version.present? ? ", '#{version.to_s}'" : ''
310
+ write_version = version.present? ? ", '#{version}'" : ''
313
311
  include_text = "gem '#{name}'" << write_version << write_option << "\n"
314
312
  inject_into_file('Gemfile', include_text, :after => after_pattern)
315
313
  end
316
314
 
315
+ ##
317
316
  # Inserts an hook before or after load in our boot.rb.
318
317
  #
319
318
  # @param [String] include_text
@@ -324,11 +323,11 @@ WARNING
324
323
  # @example
325
324
  # insert_hook("DataMapper.finalize", :after_load)
326
325
  #
327
- # @api public
328
326
  def insert_hook(include_text, where)
329
327
  inject_into_file('config/boot.rb', " #{include_text}\n", :after => "Padrino.#{where} do\n")
330
328
  end
331
329
 
330
+ ##
332
331
  # Inserts a middleware inside app.rb.
333
332
  #
334
333
  # @param [String] include_text
@@ -337,12 +336,12 @@ WARNING
337
336
  # @example
338
337
  # insert_middleware(ActiveRecord::ConnectionAdapters::ConnectionManagement)
339
338
  #
340
- # @api public
341
339
  def insert_middleware(include_text, app=nil)
342
340
  name = app || (options[:name].present? ? @app_name.downcase : 'app')
343
341
  inject_into_file("#{name}/app.rb", " use #{include_text}\n", :after => "Padrino::Application\n")
344
342
  end
345
343
 
344
+ ##
346
345
  # Registers and creates initializer.
347
346
  #
348
347
  # @param [Symbol] name
@@ -354,14 +353,14 @@ WARNING
354
353
  # initializer(:test, "some stuff here")
355
354
  # #=> generates 'lib/test_init.rb'
356
355
  #
357
- # @api public
358
356
  def initializer(name, data=nil)
359
357
  @_init_name, @_init_data = name, data
360
358
  register = data.present? ? " register #{name.to_s.underscore.camelize}Initializer\n" : " register #{name}\n"
361
359
  inject_into_file destination_root("/app/app.rb"), register, :after => "Padrino::Application\n"
362
- template "templates/initializer.rb.tt", destination_root("/lib/#{name}_init.rb") if data.present?
360
+ template "templates/initializer.rb.tt", destination_root("/lib/#{name}_initializer.rb") if data.present?
363
361
  end
364
362
 
363
+ ##
365
364
  # Insert the regired gem and add in boot.rb custom contribs.
366
365
  #
367
366
  # @param [String] contrib
@@ -370,35 +369,35 @@ WARNING
370
369
  # @example
371
370
  # require_contrib('auto_locale')
372
371
  #
373
- # @api public
374
372
  def require_contrib(contrib)
375
373
  insert_into_gemfile 'padrino-contrib'
376
374
  contrib = "require '" + File.join("padrino-contrib", contrib) + "'\n"
377
375
  inject_into_file destination_root("/config/boot.rb"), contrib, :before => "\nPadrino.load!"
378
376
  end
379
377
 
378
+ ##
380
379
  # Return true if our project has test component.
381
380
  #
382
- # @api public
383
381
  def test?
384
382
  fetch_component_choice(:test).to_s != 'none'
385
383
  end
386
384
 
385
+ ##
387
386
  # Return true if we have a tiny skeleton.
388
387
  #
389
- # @api public
390
388
  def tiny?
391
389
  File.exist?(destination_root('app/controllers.rb'))
392
390
  end
393
391
 
392
+ ##
394
393
  # Run the bundler.
395
394
  #
396
- # @api semipublic
397
395
  def run_bundler
398
396
  say 'Bundling application dependencies using bundler...', :yellow
399
397
  in_root { run 'bundle install' }
400
398
  end
401
399
 
400
+ ##
402
401
  # Ask something to the user and receives a response.
403
402
  #
404
403
  # @param [String] statement
@@ -414,7 +413,6 @@ WARNING
414
413
  # ask("What is your name?")
415
414
  # ask("Path for ruby", "/usr/local/bin/ruby") => "Path for ruby (leave blank for /usr/local/bin/ruby):"
416
415
  #
417
- # @api public
418
416
  def ask(statement, default=nil, color=nil)
419
417
  default_text = default ? " (leave blank for #{default}):" : nil
420
418
  say("#{statement}#{default_text} ", color)
@@ -422,6 +420,7 @@ WARNING
422
420
  result.blank? ? default : result
423
421
  end
424
422
 
423
+ ##
425
424
  # Raise SystemExit if the app does not exist.
426
425
  #
427
426
  # @param [String] app
@@ -430,7 +429,6 @@ WARNING
430
429
  # @example
431
430
  # check_app_existence 'app'
432
431
  #
433
- # @api semipublic
434
432
  def check_app_existence(app)
435
433
  unless File.exist?(destination_root(app))
436
434
  say
@@ -442,6 +440,7 @@ WARNING
442
440
  end
443
441
  end
444
442
 
443
+ ##
445
444
  # Generates standard and tiny applications within a project.
446
445
  #
447
446
  # @param [String] app
@@ -453,15 +452,14 @@ WARNING
453
452
  # app_skeleton 'some_app'
454
453
  # app_skeleton 'sub_app', true
455
454
  #
456
- # @api private
457
455
  def app_skeleton(app, tiny=false)
458
456
  directory('app/', destination_root(app))
459
- if tiny # generate tiny structure
457
+ if tiny
460
458
  template 'templates/controller.rb.tt', destination_root(app, 'controllers.rb')
461
459
  template 'templates/helper.rb.tt', destination_root(app, 'helpers.rb')
462
460
  @short_name = 'notifier'
463
461
  template 'templates/mailer.rb.tt', destination_root(app, 'mailers.rb')
464
- else # generate standard folders
462
+ else
465
463
  empty_directory destination_root(app, 'controllers')
466
464
  empty_directory destination_root(app, 'helpers')
467
465
  empty_directory destination_root(app, 'views')
@@ -469,10 +467,11 @@ WARNING
469
467
  end
470
468
  end
471
469
 
470
+ ##
472
471
  # Ensure that project name is valid, else raise an NameError.
473
472
  #
474
473
  # @param [String] name
475
- # name of project
474
+ # Name of project.
476
475
  #
477
476
  # @return [Exception] Exception with error message if not valid.
478
477
  #
@@ -480,7 +479,6 @@ WARNING
480
479
  # valid_constant '1235Stuff'
481
480
  # valid_constant '#Abc'
482
481
  #
483
- # @api private
484
482
  def valid_constant?(name)
485
483
  if name =~ /^\d/
486
484
  raise ::NameError, "Project name #{name} cannot start with numbers"
@@ -491,6 +489,7 @@ WARNING
491
489
 
492
490
  # Class methods for Thor generators to support the generators and component choices.
493
491
  module ClassMethods
492
+ ##
494
493
  # Defines a class option to allow a component to be chosen and add to component type list.
495
494
  # Also builds the available_choices hash of which component choices are supported.
496
495
  #
@@ -504,7 +503,6 @@ WARNING
504
503
  # @example
505
504
  # component_option :test, "Testing framework", :aliases => '-t', :choices => [:bacon, :shoulda]
506
505
  #
507
- # @api private
508
506
  def component_option(name, caption, options = {})
509
507
  (@component_types ||= []) << name # TODO use ordered hash and combine with choices below
510
508
  (@available_choices ||= Hash.new)[name] = options[:choices]
@@ -512,27 +510,45 @@ WARNING
512
510
  class_option name, :default => options[:default] || options[:choices].first, :aliases => options[:aliases], :desc => description
513
511
  end
514
512
 
513
+ ##
514
+ # Definitions for the available customizable components.
515
+ #
516
+ def defines_component_options(options = {})
517
+ [
518
+ [ :orm, 'database engine', { :aliases => '-d', :default => :none }],
519
+ [ :test, 'testing framework', { :aliases => '-t', :default => :none }],
520
+ [ :mock, 'mocking library', { :aliases => '-m', :default => :none }],
521
+ [ :script, 'javascript library', { :aliases => '-s', :default => :none }],
522
+ [ :renderer, 'template engine', { :aliases => '-e', :default => :slim }],
523
+ [ :stylesheet, 'stylesheet engine', { :aliases => '-c', :default => :none }]
524
+ ].each do |name, caption, opts|
525
+ opts[:default] = '' if options[:default] == false
526
+ component_option name, caption, opts.merge(:choices => Dir["#{File.dirname(__FILE__)}/components/#{name.to_s.pluralize}/*.rb"].map{|lib| File.basename(lib, '.rb').to_sym})
527
+ end
528
+ end
529
+
530
+ ##
515
531
  # Tell Padrino that for this Thor::Group it is a necessary task to run.
516
532
  #
517
- # @api private
518
533
  def require_arguments!
519
534
  @require_arguments = true
520
535
  end
521
536
 
537
+ ##
522
538
  # Return true if we need an arguments for our Thor::Group.
523
539
  #
524
- # @api private
525
540
  def require_arguments?
526
541
  @require_arguments
527
542
  end
528
543
 
544
+ ##
529
545
  # Returns the compiled list of component types which can be specified.
530
546
  #
531
- # @api private
532
547
  def component_types
533
548
  @component_types
534
549
  end
535
550
 
551
+ ##
536
552
  # Returns the list of available choices for the given component (including none).
537
553
  #
538
554
  # @param [Symbol] component
@@ -544,11 +560,10 @@ WARNING
544
560
  # available_choices_for :test
545
561
  # => [:shoulda, :bacon, :riot, :minitest]
546
562
  #
547
- # @api semipublic
548
563
  def available_choices_for(component)
549
564
  @available_choices[component] + [:none]
550
565
  end
551
- end # ClassMethods
552
- end # Actions
553
- end # Generators
554
- end # Padrino
566
+ end
567
+ end
568
+ end
569
+ end