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