padrino-gen 0.10.2 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +3 -3
- data/.yardopts +1 -0
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.rdoc +1 -1
- data/lib/padrino-gen/command.rb +7 -0
- data/lib/padrino-gen/generators/actions.rb +264 -24
- data/lib/padrino-gen/generators/app/app.rb.tt +11 -11
- data/lib/padrino-gen/generators/app.rb +10 -9
- data/lib/padrino-gen/generators/cli.rb +3 -0
- data/lib/padrino-gen/generators/components/actions.rb +86 -11
- data/lib/padrino-gen/generators/components/mocks/rr.rb +3 -1
- data/lib/padrino-gen/generators/components/orms/mongoid.rb +1 -1
- data/lib/padrino-gen/generators/components/orms/mongomapper.rb +1 -1
- data/lib/padrino-gen/generators/components/orms/mongomatic.rb +1 -1
- data/lib/padrino-gen/generators/components/stylesheets/less.rb +1 -1
- data/lib/padrino-gen/generators/components/tests/minitest.rb +78 -0
- data/lib/padrino-gen/generators/controller.rb +3 -0
- data/lib/padrino-gen/generators/mailer.rb +3 -0
- data/lib/padrino-gen/generators/model.rb +3 -0
- data/lib/padrino-gen/generators/plugin.rb +2 -0
- data/lib/padrino-gen/generators/project.rb +11 -3
- data/lib/padrino-gen/generators/runner.rb +85 -34
- data/lib/padrino-gen/generators/templates/Gemfile.tt +12 -21
- data/lib/padrino-gen/padrino-tasks/activerecord.rb +0 -194
- data/lib/padrino-gen.rb +21 -0
- data/test/helper.rb +2 -20
- data/test/test_app_generator.rb +17 -17
- data/test/test_cli.rb +6 -5
- data/test/test_controller_generator.rb +52 -44
- data/test/test_generator.rb +1 -1
- data/test/test_mailer_generator.rb +18 -18
- data/test/test_migration_generator.rb +44 -44
- data/test/test_model_generator.rb +140 -123
- data/test/test_plugin_generator.rb +21 -33
- data/test/test_project_generator.rb +125 -103
- metadata +10 -8
data/.document
CHANGED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--title 'Padrino Gen Documentation' --protected
|
data/{LICENSE → LICENSE.txt}
RENAMED
File without changes
|
data/README.rdoc
CHANGED
@@ -38,7 +38,7 @@ You can also instruct the generator to skip a certain component to avoid using o
|
|
38
38
|
|
39
39
|
The available components and their default options are listed below:
|
40
40
|
|
41
|
-
test:: rspec (default), bacon, shoulda, cucumber, testspec, riot
|
41
|
+
test:: rspec (default), bacon, shoulda, cucumber, testspec, riot, minitest
|
42
42
|
renderer:: haml (default), erb, erubis, liquid, slim
|
43
43
|
stylesheet:: sass (default), less, compass
|
44
44
|
mock:: none (default), mocha, rr
|
data/lib/padrino-gen/command.rb
CHANGED
@@ -5,6 +5,13 @@ module Padrino
|
|
5
5
|
# This method return the correct location of padrino-gen bin or
|
6
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
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# Padrino.bin_gen(:app, name.to_s, "-r=#{destination_root}")
|
13
|
+
#
|
14
|
+
# @api semipublic
|
8
15
|
def self.bin_gen(*args)
|
9
16
|
@_padrino_gen_bin ||= [Padrino.ruby_command, File.expand_path("../../../bin/padrino-gen", __FILE__)]
|
10
17
|
args.empty? ? @_padrino_gen_bin : system(args.unshift(@_padrino_gen_bin).join(" "))
|
@@ -9,16 +9,34 @@ module Padrino
|
|
9
9
|
end
|
10
10
|
|
11
11
|
# Performs the necessary generator for a given component choice
|
12
|
-
#
|
12
|
+
#
|
13
|
+
# @param [Symbol] component
|
14
|
+
# The type of component module
|
15
|
+
# @param [String] choice
|
16
|
+
# The name of the component module choice
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# execute_component_setup(:mock, 'rr')
|
20
|
+
#
|
21
|
+
# @api private
|
13
22
|
def execute_component_setup(component, choice)
|
14
|
-
return true &&
|
15
|
-
|
23
|
+
return true && say_status(:skipping, "#{component} component...") if choice.to_s == 'none'
|
24
|
+
say_status(:applying, "#{choice} (#{component})...")
|
16
25
|
apply_component_for(choice, component)
|
17
26
|
send("setup_#{component}") if respond_to?("setup_#{component}")
|
18
27
|
end
|
19
28
|
|
20
29
|
# Returns the related module for a given component and option
|
21
|
-
#
|
30
|
+
#
|
31
|
+
# @param [String] choice
|
32
|
+
# The name of the component module
|
33
|
+
# @param [Symbol] component
|
34
|
+
# The type of the component module
|
35
|
+
#
|
36
|
+
# @example
|
37
|
+
# generator_module_for('rr', :mock)
|
38
|
+
#
|
39
|
+
# @api private
|
22
40
|
def apply_component_for(choice, component)
|
23
41
|
# I need to override Thor#apply because for unknow reason :verobse => false break tasks.
|
24
42
|
path = File.expand_path(File.dirname(__FILE__) + "/components/#{component.to_s.pluralize}/#{choice}.rb")
|
@@ -30,8 +48,17 @@ module Padrino
|
|
30
48
|
|
31
49
|
# Includes the component module for the given component and choice
|
32
50
|
# Determines the choice using .components file
|
33
|
-
#
|
34
|
-
#
|
51
|
+
#
|
52
|
+
# @param [Symbol] component
|
53
|
+
# The type of component module
|
54
|
+
# @param [String] choice
|
55
|
+
# The name of the component module
|
56
|
+
#
|
57
|
+
# @example
|
58
|
+
# include_component_module_for(:mock)
|
59
|
+
# include_component_module_for(:mock, 'rr')
|
60
|
+
#
|
61
|
+
# @api private
|
35
62
|
def include_component_module_for(component, choice=nil)
|
36
63
|
choice = fetch_component_choice(component) unless choice
|
37
64
|
return false if choice.to_s == 'none'
|
@@ -39,13 +66,33 @@ module Padrino
|
|
39
66
|
end
|
40
67
|
|
41
68
|
# Returns the component choice stored within the .component file of an application
|
42
|
-
#
|
69
|
+
#
|
70
|
+
# @param [Symbol] component
|
71
|
+
# The type of component module
|
72
|
+
#
|
73
|
+
# @return [String] Name of the component module
|
74
|
+
#
|
75
|
+
# @example
|
76
|
+
# fetch_component_choice(:mock)
|
77
|
+
#
|
78
|
+
# @api public
|
43
79
|
def fetch_component_choice(component)
|
44
80
|
retrieve_component_config(destination_root('.components'))[component]
|
45
81
|
end
|
46
82
|
|
47
|
-
# Set the component choice
|
48
|
-
#
|
83
|
+
# Set the component choice aeleopteryxnd store it in the .component file of the application
|
84
|
+
#
|
85
|
+
# @param [Symbol] key
|
86
|
+
# The type of component module
|
87
|
+
# @param [Symbol] value
|
88
|
+
# The name of the component module
|
89
|
+
#
|
90
|
+
# @return [Symbol] the name of the component module
|
91
|
+
#
|
92
|
+
# @example
|
93
|
+
# store_component_choice(:renderer, :haml)
|
94
|
+
#
|
95
|
+
# @api semipublic
|
49
96
|
def store_component_choice(key, value)
|
50
97
|
path = destination_root('.components')
|
51
98
|
config = retrieve_component_config(path)
|
@@ -55,13 +102,32 @@ module Padrino
|
|
55
102
|
end
|
56
103
|
|
57
104
|
# Loads the component config back into a hash
|
58
|
-
#
|
105
|
+
#
|
106
|
+
# @param [String] target
|
107
|
+
# Path to component config file
|
108
|
+
#
|
109
|
+
# @return [Hash] Loaded YAML file
|
110
|
+
#
|
111
|
+
# @example
|
112
|
+
# retrieve_component_config(...)
|
113
|
+
# # => { :mock => 'rr', :test => 'riot', ... }
|
114
|
+
#
|
115
|
+
# @api private
|
59
116
|
def retrieve_component_config(target)
|
60
117
|
YAML.load_file(target)
|
61
118
|
end
|
62
119
|
|
63
120
|
# Prompts the user if necessary until a valid choice is returned for the component
|
64
|
-
#
|
121
|
+
#
|
122
|
+
# @param [Symbol] component
|
123
|
+
# The type of component module
|
124
|
+
#
|
125
|
+
# @return [String] Name of component if valid, otherwise ask for valid choice.
|
126
|
+
#
|
127
|
+
# @example
|
128
|
+
# resolve_valid_choice(:mock) => 'rr'
|
129
|
+
#
|
130
|
+
# @api private
|
65
131
|
def resolve_valid_choice(component)
|
66
132
|
available_string = self.class.available_choices_for(component).join(", ")
|
67
133
|
choice = options[component]
|
@@ -73,13 +139,32 @@ module Padrino
|
|
73
139
|
end
|
74
140
|
|
75
141
|
# Returns true if the option passed is a valid choice for component
|
76
|
-
#
|
142
|
+
#
|
143
|
+
# @param [Symbol] component
|
144
|
+
# The type of component module
|
145
|
+
# @param [String] choice
|
146
|
+
# The name of the component module
|
147
|
+
#
|
148
|
+
# @return [Boolean] Boolean of whether the choice is valid.
|
149
|
+
#
|
150
|
+
# @example
|
151
|
+
# valid_choice?(:mock, 'rr') => true
|
152
|
+
#
|
153
|
+
# @api public
|
77
154
|
def valid_choice?(component, choice)
|
78
155
|
choice.present? && self.class.available_choices_for(component).include?(choice.to_sym)
|
79
156
|
end
|
80
157
|
|
81
158
|
# Creates a component_config file at the destination containing all component options
|
82
159
|
# Content is a yamlized version of a hash containing component name mapping to chosen value
|
160
|
+
#
|
161
|
+
# @param [String] destination
|
162
|
+
# The file path to store the component config.
|
163
|
+
#
|
164
|
+
# @example
|
165
|
+
# store_component_config '/foo/bar'
|
166
|
+
#
|
167
|
+
# @api private
|
83
168
|
def store_component_config(destination)
|
84
169
|
components = @_components || options
|
85
170
|
create_file(destination) do
|
@@ -90,40 +175,96 @@ module Padrino
|
|
90
175
|
end
|
91
176
|
|
92
177
|
# Returns the root for this thor class (also aliased as destination root).
|
178
|
+
#
|
179
|
+
# @param [Array<String>] paths
|
180
|
+
# The relative path from destination rooot
|
181
|
+
#
|
182
|
+
# @return [String] The full path
|
183
|
+
#
|
184
|
+
# @example
|
185
|
+
# destination_root 'config/boot.rb'
|
186
|
+
#
|
187
|
+
# @api public
|
93
188
|
def destination_root(*paths)
|
94
189
|
File.expand_path(File.join(@destination_stack.last, paths))
|
95
190
|
end
|
96
191
|
|
97
192
|
# Returns true if inside a Padrino application
|
193
|
+
#
|
194
|
+
# @return [Boolean] Boolean if in app root
|
195
|
+
#
|
196
|
+
# @example
|
197
|
+
# in_app_root? => true
|
198
|
+
#
|
199
|
+
# @api public
|
98
200
|
def in_app_root?
|
99
201
|
File.exist?(destination_root('config/boot.rb'))
|
100
202
|
end
|
101
203
|
|
102
204
|
# Returns the field with an unacceptable name(for symbol) else returns nil
|
205
|
+
#
|
206
|
+
# @param [Array<String>] fields
|
207
|
+
# Field names for generators
|
208
|
+
#
|
209
|
+
# @return [Array<String>] array of invalid fields
|
210
|
+
#
|
211
|
+
# @example
|
212
|
+
# invalid_fields ['foo:bar', 'hello:world']
|
213
|
+
#
|
214
|
+
# @api semipublic
|
103
215
|
def invalid_fields(fields)
|
104
216
|
results = fields.select { |field| field.split(":").first =~ /\W/ }
|
105
217
|
results.empty? ? nil : results
|
106
218
|
end
|
107
219
|
|
108
220
|
# Returns the app_name for the application at root
|
221
|
+
#
|
222
|
+
# @param [String] app
|
223
|
+
# folder name of application
|
224
|
+
#
|
225
|
+
# @return [String] class name for application
|
226
|
+
#
|
227
|
+
# @example
|
228
|
+
# fetch_app_name 'subapp'
|
229
|
+
# #=> SubApp
|
230
|
+
#
|
231
|
+
# @api public
|
109
232
|
def fetch_app_name(app='app')
|
110
233
|
app_path = destination_root(app, 'app.rb')
|
111
234
|
@app_name ||= File.read(app_path).scan(/class\s(.*?)\s</).flatten[0]
|
112
235
|
end
|
113
236
|
|
114
237
|
# Adds all the specified gems into the Gemfile for bundler
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
238
|
+
#
|
239
|
+
# @param [Array<String>] gem_names
|
240
|
+
# Splat of gems to require in gemfile
|
241
|
+
# @param [Hash] options
|
242
|
+
# The options to pass to gem in gemfile
|
243
|
+
#
|
244
|
+
# @example
|
245
|
+
# require_dependencies 'active_record'
|
246
|
+
# require_dependencies 'mocha', 'bacon', :group => 'test'
|
247
|
+
# require_dependencies 'json', :version => ">=1.2.3"
|
248
|
+
#
|
249
|
+
# @api public
|
118
250
|
def require_dependencies(*gem_names)
|
119
251
|
options = gem_names.extract_options!
|
120
252
|
gem_names.reverse.each { |lib| insert_into_gemfile(lib, options) }
|
121
253
|
end
|
122
254
|
|
123
255
|
# Inserts a required gem into the Gemfile to add the bundler dependency
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
256
|
+
#
|
257
|
+
# @param [String] name
|
258
|
+
# Name of gem to insert into Gemfile
|
259
|
+
# @param [Hash] options
|
260
|
+
# Options to generate into Gemfile for gem
|
261
|
+
#
|
262
|
+
# @example
|
263
|
+
# insert_into_gemfile(name)
|
264
|
+
# insert_into_gemfile(name, :group => 'test', :require => 'foo')
|
265
|
+
# insert_into_gemfile(name, :group => 'test', :version => ">1.2.3")
|
266
|
+
#
|
267
|
+
# @api public
|
127
268
|
def insert_into_gemfile(name, options={})
|
128
269
|
after_pattern = options[:group] ? "#{options[:group].to_s.capitalize} requirements\n" : "Component requirements\n"
|
129
270
|
version = options.delete(:version)
|
@@ -135,13 +276,31 @@ module Padrino
|
|
135
276
|
end
|
136
277
|
|
137
278
|
# Inserts an hook before or after load in our boot.rb
|
138
|
-
#
|
279
|
+
#
|
280
|
+
# @param [String] include_text
|
281
|
+
# Text to include into hooks in boot.rb
|
282
|
+
# @param [Symbol] where
|
283
|
+
# method hook to call from Padrino, i.e :after_load, :before_load
|
284
|
+
#
|
285
|
+
# @example
|
286
|
+
# insert_hook("DataMapper.finalize", :after_load)
|
287
|
+
#
|
288
|
+
# @api public
|
139
289
|
def insert_hook(include_text, where)
|
140
290
|
inject_into_file('config/boot.rb', " #{include_text}\n", :after => "Padrino.#{where} do\n")
|
141
291
|
end
|
142
292
|
|
143
293
|
# Registers and Creates Initializer.
|
144
|
-
#
|
294
|
+
#
|
295
|
+
# @param [Symbol] name
|
296
|
+
# Name of the initializer
|
297
|
+
# @param [String] data
|
298
|
+
# Text to generate into the initializer file
|
299
|
+
#
|
300
|
+
# @example
|
301
|
+
# initializer :test, "some stuff here" # generates 'lib/test_init.rb'
|
302
|
+
#
|
303
|
+
# @api public
|
145
304
|
def initializer(name, data=nil)
|
146
305
|
@_init_name, @_init_data = name, data
|
147
306
|
register = data.present? ? " register #{name.to_s.camelize}Initializer\n" : " register #{name}\n"
|
@@ -150,6 +309,14 @@ module Padrino
|
|
150
309
|
end
|
151
310
|
|
152
311
|
# Insert the regired gem and add in boot.rb custom contribs.
|
312
|
+
#
|
313
|
+
# @param [String] contrib
|
314
|
+
# name of library from padrino-contrib
|
315
|
+
#
|
316
|
+
# @example
|
317
|
+
# require_contrib 'auto_locale'
|
318
|
+
#
|
319
|
+
# @api public
|
153
320
|
def require_contrib(contrib)
|
154
321
|
insert_into_gemfile 'padrino-contrib'
|
155
322
|
contrib = "require '" + File.join("padrino-contrib", contrib) + "'\n"
|
@@ -157,16 +324,22 @@ module Padrino
|
|
157
324
|
end
|
158
325
|
|
159
326
|
# Return true if our project has test component
|
327
|
+
#
|
328
|
+
# @api public
|
160
329
|
def test?
|
161
330
|
fetch_component_choice(:test).to_s != 'none'
|
162
331
|
end
|
163
332
|
|
164
333
|
# Return true if we have a tiny skeleton
|
334
|
+
#
|
335
|
+
# @api public
|
165
336
|
def tiny?
|
166
337
|
File.exist?(destination_root("app/controllers.rb"))
|
167
338
|
end
|
168
339
|
|
169
340
|
# Run the bundler
|
341
|
+
#
|
342
|
+
# @api semipublic
|
170
343
|
def run_bundler
|
171
344
|
say "Bundling application dependencies using bundler...", :yellow
|
172
345
|
in_root { run 'bundle install' }
|
@@ -174,11 +347,20 @@ module Padrino
|
|
174
347
|
|
175
348
|
# Ask something to the user and receives a response.
|
176
349
|
#
|
177
|
-
#
|
350
|
+
# @param [String] statement
|
351
|
+
# String of statement to display for input
|
352
|
+
# @param [String] default
|
353
|
+
# Default value for input
|
354
|
+
# @param [String] color
|
355
|
+
# Name of color to display input
|
356
|
+
#auto_locale
|
357
|
+
# @return [String] Input value
|
178
358
|
#
|
359
|
+
# @example
|
179
360
|
# ask("What is your name?")
|
180
361
|
# ask("Path for ruby", "/usr/local/bin/ruby") => "Path for ruby (leave blank for /usr/local/bin/ruby):"
|
181
362
|
#
|
363
|
+
# @api public
|
182
364
|
def ask(statement, default=nil, color=nil)
|
183
365
|
default_text = default ? " (leave blank for #{default}):" : nil
|
184
366
|
say("#{statement}#{default_text} ", color)
|
@@ -187,11 +369,19 @@ module Padrino
|
|
187
369
|
end
|
188
370
|
|
189
371
|
# Raise SystemExit if the app is inexistent
|
372
|
+
#
|
373
|
+
# @param [String] app
|
374
|
+
# Directoy name of application
|
375
|
+
#
|
376
|
+
# @example
|
377
|
+
# check_app_existence 'app'
|
378
|
+
#
|
379
|
+
# @api semipublic
|
190
380
|
def check_app_existence(app)
|
191
381
|
unless File.exist?(destination_root(app))
|
192
382
|
say
|
193
383
|
say "================================================================="
|
194
|
-
say "
|
384
|
+
say "Unable to locate '#{app.underscore.camelize}' application "
|
195
385
|
say "================================================================="
|
196
386
|
say
|
197
387
|
# raise SystemExit
|
@@ -199,6 +389,17 @@ module Padrino
|
|
199
389
|
end
|
200
390
|
|
201
391
|
# Generates standard and tiny applications within a project
|
392
|
+
#
|
393
|
+
# @param [String] app
|
394
|
+
# name of application
|
395
|
+
# @param [Boolean] tiny
|
396
|
+
# Boolean to generate a tiny structure
|
397
|
+
#
|
398
|
+
# @example
|
399
|
+
# app_skeleton 'some_app'
|
400
|
+
# app_skeleton 'sub_app', true
|
401
|
+
#
|
402
|
+
# @api private
|
202
403
|
def app_skeleton(app, tiny=false)
|
203
404
|
directory("app/", destination_root(app))
|
204
405
|
if tiny # generate tiny structure
|
@@ -215,6 +416,17 @@ module Padrino
|
|
215
416
|
end
|
216
417
|
|
217
418
|
# Ensure that project name is valid, else raise an NameError
|
419
|
+
#
|
420
|
+
# @param [String] name
|
421
|
+
# name of project
|
422
|
+
#
|
423
|
+
# @return [Exception] Exception with error messsage if not valid
|
424
|
+
#
|
425
|
+
# @example
|
426
|
+
# valid_constant '1235Stuff'
|
427
|
+
# valid_constant '#Abc'
|
428
|
+
#
|
429
|
+
# @api private
|
218
430
|
def valid_constant?(name)
|
219
431
|
if name =~ /^\d/
|
220
432
|
raise ::NameError, "Project name #{name} cannot start with numbers"
|
@@ -226,7 +438,18 @@ module Padrino
|
|
226
438
|
module ClassMethods
|
227
439
|
# Defines a class option to allow a component to be chosen and add to component type list
|
228
440
|
# Also builds the available_choices hash of which component choices are supported
|
229
|
-
#
|
441
|
+
#
|
442
|
+
# @param [Symbol] name
|
443
|
+
# Name of component
|
444
|
+
# @param [String] caption
|
445
|
+
# Description of the component
|
446
|
+
# @param [Hash] options
|
447
|
+
# Additional parameters for component choice
|
448
|
+
#
|
449
|
+
# @example
|
450
|
+
# component_option :test, "Testing framework", :aliases => '-t', :choices => [:bacon, :shoulda]
|
451
|
+
#
|
452
|
+
# @api private
|
230
453
|
def component_option(name, caption, options = {})
|
231
454
|
(@component_types ||= []) << name # TODO use ordered hash and combine with choices below
|
232
455
|
(@available_choices ||= Hash.new)[name] = options[:choices]
|
@@ -234,22 +457,39 @@ module Padrino
|
|
234
457
|
class_option name, :default => options[:default] || options[:choices].first, :aliases => options[:aliases], :desc => description
|
235
458
|
end
|
236
459
|
|
237
|
-
# Tell
|
460
|
+
# Tell padrino that for this Thor::Group it is a necessary task to run
|
461
|
+
#
|
462
|
+
# @api private
|
238
463
|
def require_arguments!
|
239
464
|
@require_arguments = true
|
240
465
|
end
|
241
466
|
|
242
467
|
# Return true if we need an arguments for our Thor::Group
|
468
|
+
#
|
469
|
+
# @api private
|
243
470
|
def require_arguments?
|
244
471
|
@require_arguments
|
245
472
|
end
|
246
473
|
|
247
474
|
# Returns the compiled list of component types which can be specified
|
475
|
+
#
|
476
|
+
# @api private
|
248
477
|
def component_types
|
249
478
|
@component_types
|
250
479
|
end
|
251
480
|
|
252
481
|
# Returns the list of available choices for the given component (including none)
|
482
|
+
#
|
483
|
+
# @param [Symbol] component
|
484
|
+
# The type of the component module
|
485
|
+
#
|
486
|
+
# @return [Array<Symbol>] Array of component choices
|
487
|
+
#
|
488
|
+
# @example
|
489
|
+
# available_choices_for :test
|
490
|
+
# => [:shoulda, :bacon, :riot, :minitest]
|
491
|
+
#
|
492
|
+
# @api semipublic
|
253
493
|
def available_choices_for(component)
|
254
494
|
@available_choices[component] + [:none]
|
255
495
|
end
|