rails 0.9.5 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rails might be problematic. Click here for more details.

Files changed (77) hide show
  1. data/CHANGELOG +46 -0
  2. data/README +36 -8
  3. data/Rakefile +18 -25
  4. data/bin/console +17 -30
  5. data/bin/console_sandbox.rb +6 -0
  6. data/bin/destroy +5 -0
  7. data/bin/generate +2 -70
  8. data/bin/rails +4 -28
  9. data/bin/server +4 -2
  10. data/bin/update +5 -0
  11. data/configs/apache.conf +7 -54
  12. data/configs/empty.log +0 -0
  13. data/configs/routes.rb +15 -0
  14. data/environments/shared.rb +14 -6
  15. data/environments/shared_for_gem.rb +12 -6
  16. data/fresh_rakefile +40 -8
  17. data/html/index.html +70 -1
  18. data/lib/breakpoint.rb +6 -1
  19. data/lib/breakpoint_client.rb +196 -193
  20. data/lib/dispatcher.rb +16 -38
  21. data/lib/rails_generator.rb +39 -198
  22. data/lib/rails_generator/base.rb +203 -0
  23. data/lib/rails_generator/commands.rb +409 -0
  24. data/lib/rails_generator/generators/applications/app/USAGE +16 -0
  25. data/lib/rails_generator/generators/applications/app/app_generator.rb +120 -0
  26. data/lib/rails_generator/generators/components/controller/USAGE +30 -0
  27. data/lib/rails_generator/generators/components/controller/controller_generator.rb +37 -0
  28. data/{generators → lib/rails_generator/generators/components}/controller/templates/controller.rb +1 -1
  29. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +18 -0
  30. data/{generators → lib/rails_generator/generators/components}/controller/templates/helper.rb +0 -0
  31. data/{generators → lib/rails_generator/generators/components}/controller/templates/view.rhtml +0 -0
  32. data/lib/rails_generator/generators/components/mailer/USAGE +19 -0
  33. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +32 -0
  34. data/{generators → lib/rails_generator/generators/components}/mailer/templates/fixture.rhtml +0 -0
  35. data/{generators → lib/rails_generator/generators/components}/mailer/templates/mailer.rb +0 -0
  36. data/{generators → lib/rails_generator/generators/components}/mailer/templates/unit_test.rb +7 -1
  37. data/{generators → lib/rails_generator/generators/components}/mailer/templates/view.rhtml +0 -0
  38. data/lib/rails_generator/generators/components/model/USAGE +17 -0
  39. data/lib/rails_generator/generators/components/model/model_generator.rb +18 -0
  40. data/{generators/scaffold → lib/rails_generator/generators/components/model}/templates/fixtures.yml +0 -2
  41. data/{generators → lib/rails_generator/generators/components}/model/templates/model.rb +0 -0
  42. data/{generators → lib/rails_generator/generators/components}/model/templates/unit_test.rb +5 -1
  43. data/lib/rails_generator/generators/components/scaffold/USAGE +32 -0
  44. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +178 -0
  45. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/controller.rb +1 -1
  46. data/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +5 -0
  47. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/functional_test.rb +7 -6
  48. data/lib/rails_generator/generators/components/scaffold/templates/helper.rb +2 -0
  49. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/layout.rhtml +1 -1
  50. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/style.css +17 -17
  51. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/view_edit.rhtml +1 -1
  52. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/view_list.rhtml +1 -1
  53. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/view_new.rhtml +1 -1
  54. data/{generators → lib/rails_generator/generators/components}/scaffold/templates/view_show.rhtml +0 -0
  55. data/lib/rails_generator/lookup.rb +200 -0
  56. data/lib/rails_generator/manifest.rb +53 -0
  57. data/lib/rails_generator/options.rb +134 -0
  58. data/lib/rails_generator/scripts.rb +83 -0
  59. data/lib/rails_generator/scripts/destroy.rb +7 -0
  60. data/lib/rails_generator/scripts/generate.rb +7 -0
  61. data/lib/rails_generator/scripts/update.rb +12 -0
  62. data/lib/rails_generator/simple_logger.rb +46 -0
  63. data/lib/rails_generator/spec.rb +44 -0
  64. data/lib/webrick_server.rb +15 -65
  65. metadata +92 -48
  66. data/doc/apache_protection +0 -3
  67. data/doc/index.html +0 -70
  68. data/generators/controller/USAGE +0 -28
  69. data/generators/controller/controller_generator.rb +0 -26
  70. data/generators/controller/templates/functional_test.rb +0 -17
  71. data/generators/mailer/USAGE +0 -27
  72. data/generators/mailer/mailer_generator.rb +0 -22
  73. data/generators/model/USAGE +0 -17
  74. data/generators/model/model_generator.rb +0 -10
  75. data/generators/model/templates/fixtures.yml +0 -1
  76. data/generators/scaffold/USAGE +0 -27
  77. data/generators/scaffold/scaffold_generator.rb +0 -60
@@ -0,0 +1,409 @@
1
+ require 'delegate'
2
+ require 'optparse'
3
+ require 'fileutils'
4
+ require 'erb'
5
+
6
+ module Rails
7
+ module Generator
8
+ module Commands
9
+ # Here's a convenient way to get a handle on generator commands.
10
+ # Command.instance('destroy', my_generator) instantiates a Destroy
11
+ # delegate of my_generator ready to do your dirty work.
12
+ def self.instance(command, generator)
13
+ const_get(command.to_s.camelize).new(generator)
14
+ end
15
+
16
+ # Even more convenient access to commands. Include Commands in
17
+ # the generator Base class to get a nice #command instance method
18
+ # which returns a delegate for the requested command.
19
+ def self.append_features(base)
20
+ base.send(:define_method, :command) do |command|
21
+ Commands.instance(command, self)
22
+ end
23
+ end
24
+
25
+
26
+ # Generator commands delegate Rails::Generator::Base and implement
27
+ # a standard set of actions. Their behavior is defined by the way
28
+ # they respond to these actions: Create brings life; Destroy brings
29
+ # death; List passively observes.
30
+ #
31
+ # Commands are invoked by replaying (or rewinding) the generator's
32
+ # manifest of actions. See Rails::Generator::Manifest and
33
+ # Rails::Generator::Base#manifest method that generator subclasses
34
+ # are required to override.
35
+ #
36
+ # Commands allows generators to "plug in" invocation behavior, which
37
+ # corresponds to the GoF Strategy pattern.
38
+ class Base < DelegateClass(Rails::Generator::Base)
39
+ # Replay action manifest. RewindBase subclass rewinds manifest.
40
+ def invoke!
41
+ manifest.replay(self)
42
+ end
43
+
44
+ def dependency(generator_name, args, runtime_options = {})
45
+ logger.dependency(generator_name) do
46
+ self.class.new(instance(generator_name, args, full_options(runtime_options))).invoke!
47
+ end
48
+ end
49
+
50
+ # Does nothing for all commands except Create.
51
+ def class_collisions(*class_names)
52
+ end
53
+
54
+ # Does nothing for all commands except Create.
55
+ def readme(*args)
56
+ end
57
+
58
+ private
59
+ # Ask the user interactively whether to force collision.
60
+ def force_file_collision?(destination)
61
+ $stdout.print "overwrite #{destination}? [Ynaq] "
62
+ case $stdin.gets
63
+ when /a/i
64
+ $stdout.puts "forcing #{spec.name}"
65
+ options[:collision] = :force
66
+ when /q/i
67
+ $stdout.puts "aborting #{spec.name}"
68
+ raise SystemExit
69
+ when /n/i then :skip
70
+ else :force
71
+ end
72
+ rescue
73
+ retry
74
+ end
75
+
76
+ def render_template_part(template_options)
77
+ # Getting Sandbox to evaluate part template in it
78
+ part_binding = template_options[:sandbox].call.sandbox_binding
79
+ part_rel_path = template_options[:insert]
80
+ part_path = source_path(part_rel_path)
81
+
82
+ # Render inner template within Sandbox binding
83
+ rendered_part = ERB.new(File.readlines(part_path).join, nil, '-').result(part_binding)
84
+ begin_mark = template_part_mark(template_options[:begin_mark], template_options[:mark_id])
85
+ end_mark = template_part_mark(template_options[:end_mark], template_options[:mark_id])
86
+ begin_mark + rendered_part + end_mark
87
+ end
88
+
89
+ def template_part_mark(name, id)
90
+ "<!--[#{name}:#{id}]-->\n"
91
+ end
92
+ end
93
+
94
+ # Base class for commands which handle generator actions in reverse, such as Destroy.
95
+ class RewindBase < Base
96
+ # Rewind action manifest.
97
+ def invoke!
98
+ manifest.rewind(self)
99
+ end
100
+ end
101
+
102
+
103
+ # Create is the premier generator command. It copies files, creates
104
+ # directories, renders templates, and more.
105
+ class Create < Base
106
+
107
+ # Check whether the given class names are already taken by
108
+ # Ruby or Rails. In the future, expand to check other namespaces
109
+ # such as the rest of the user's app.
110
+ def class_collisions(*class_names)
111
+ class_names.flatten.each do |class_name|
112
+ # Convert to string to allow symbol arguments.
113
+ class_name = class_name.to_s
114
+
115
+ # Skip empty strings.
116
+ next if class_name.strip.empty?
117
+
118
+ # Split the class from its module nesting.
119
+ nesting = class_name.split('::')
120
+ name = nesting.pop
121
+
122
+ # Extract the last Module in the nesting.
123
+ last = nesting.inject(Object) { |last, nest|
124
+ break unless last.const_defined?(nest)
125
+ last.const_get(nest)
126
+ }
127
+
128
+ # If the last Module exists, check whether the given
129
+ # class exists and raise a collision if so.
130
+ if last and last.const_defined?(name.camelize)
131
+ raise_class_collision(class_name)
132
+ end
133
+ end
134
+ end
135
+
136
+ # Copy a file from source to destination with collision checking.
137
+ #
138
+ # The file_options hash accepts :chmod and :shebang options.
139
+ # :chmod sets the permissions of the destination file:
140
+ # file 'config/empty.log', 'log/test.log', :chmod => 0664
141
+ # :shebang sets the #!/usr/bin/ruby line for scripts
142
+ # file 'bin/generate.rb', 'script/generate', :chmod => 0755, :shebang => '/usr/bin/env ruby'
143
+ #
144
+ # Collisions are handled by checking whether the destination file
145
+ # exists and either skipping the file, forcing overwrite, or asking
146
+ # the user what to do.
147
+ def file(relative_source, relative_destination, file_options = {})
148
+ # Determine full paths for source and destination files.
149
+ source = source_path(relative_source)
150
+ destination = destination_path(relative_destination)
151
+
152
+ # Check for and resolve file collisions.
153
+ if File.exists?(destination)
154
+
155
+ # Make a choice whether to overwrite the file. :force and
156
+ # :skip already have their mind made up, but give :ask a shot.
157
+ choice = case options[:collision].to_sym #|| :ask
158
+ when :ask then force_file_collision?(relative_destination)
159
+ when :force then :force
160
+ when :skip then :skip
161
+ else raise "Invalid collision option: #{options[:collision].inspect}"
162
+ end
163
+
164
+ # Take action based on our choice. Bail out if we chose to
165
+ # skip the file; otherwise, log our transgression and continue.
166
+ case choice
167
+ when :force then logger.force(relative_destination)
168
+ when :skip then return(logger.skip(relative_destination))
169
+ else raise "Invalid collision choice: #{choice}.inspect"
170
+ end
171
+
172
+ # File doesn't exist so log its unbesmirched creation.
173
+ else
174
+ logger.create relative_destination
175
+ end
176
+
177
+ # If we're pretending, back off now.
178
+ return if options[:pretend]
179
+
180
+ # Write destination file with optional shebang. Yield for content
181
+ # if block given so templaters may render the source file. If a
182
+ # shebang is requested, replace the existing shebang or insert a
183
+ # new one.
184
+ File.open(destination, 'w') do |df|
185
+ File.open(source) do |sf|
186
+ if block_given?
187
+ df.write(yield(sf))
188
+ else
189
+ line = sf.gets
190
+ if file_options[:shebang]
191
+ df.puts("#!#{file_options[:shebang]}")
192
+ df.puts(line) if line !~ /^#!/
193
+ else
194
+ df.puts(line)
195
+ end
196
+ df.write(sf.read)
197
+ end
198
+ end
199
+ end
200
+
201
+ # Optionally change permissions.
202
+ if file_options[:chmod]
203
+ FileUtils.chmod(file_options[:chmod], destination)
204
+ end
205
+ end
206
+
207
+ # Generate a file for a Rails application using an ERuby template.
208
+ # Looks up and evalutes a template by name and writes the result.
209
+ #
210
+ # The ERB template uses explicit trim mode to best control the
211
+ # proliferation of whitespace in generated code. <%- trims leading
212
+ # whitespace; -%> trims trailing whitespace including one newline.
213
+ #
214
+ # A hash of template options may be passed as the last argument.
215
+ # The options accepted by the file are accepted as well as :assigns,
216
+ # a hash of variable bindings. Example:
217
+ # template 'foo', 'bar', :assigns => { :action => 'view' }
218
+ #
219
+ # Template is implemented in terms of file. It calls file with a
220
+ # block which takes a file handle and returns its rendered contents.
221
+ def template(relative_source, relative_destination, template_options = {})
222
+ file(relative_source, relative_destination, template_options) do |file|
223
+ # Evaluate any assignments in a temporary, throwaway binding.
224
+ vars = template_options[:assigns] || {}
225
+ b = binding
226
+ vars.each { |k,v| eval "#{k} = vars[:#{k}] || vars['#{k}']", b }
227
+
228
+ # Render the source file with the temporary binding.
229
+ ERB.new(file.read, nil, '-').result(b)
230
+ end
231
+ end
232
+
233
+ def complex_template(relative_source, relative_destination, template_options = {})
234
+ options = template_options.dup
235
+ options[:assigns] ||= {}
236
+ options[:assigns]['template_for_inclusion'] = render_template_part(template_options)
237
+ template(relative_source, relative_destination, options)
238
+ end
239
+
240
+ # Create a directory including any missing parent directories.
241
+ # Always directories which exist.
242
+ def directory(relative_path)
243
+ path = destination_path(relative_path)
244
+ if File.exists?(path)
245
+ logger.exists relative_path
246
+ else
247
+ logger.create relative_path
248
+ FileUtils.mkdir_p(path) unless options[:pretend]
249
+ end
250
+ end
251
+
252
+ # Display a README.
253
+ def readme(*relative_sources)
254
+ relative_sources.flatten.each do |relative_source|
255
+ logger.readme relative_source
256
+ puts File.read(source_path(relative_source)) unless options[:pretend]
257
+ end
258
+ end
259
+
260
+ private
261
+ # Raise a usage error with an informative WordNet suggestion.
262
+ # Thanks to Florian Gross (flgr).
263
+ def raise_class_collision(class_name)
264
+ message = <<end_message
265
+ The name '#{class_name}' is reserved by Ruby on Rails.
266
+ Please choose an alternative and run this generator again.
267
+ end_message
268
+ if suggest = find_synonyms(class_name)
269
+ message << "\n Suggestions: \n\n"
270
+ message << suggest.join("\n")
271
+ end
272
+ raise UsageError, message
273
+ end
274
+
275
+ SYNONYM_LOOKUP_URI = "http://wordnet.princeton.edu/cgi-bin/webwn2.0?stage=2&word=%s&posnumber=1&searchtypenumber=2&senses=&showglosses=1"
276
+
277
+ # Look up synonyms on WordNet. Thanks to Florian Gross (flgr).
278
+ def find_synonyms(word)
279
+ require 'open-uri'
280
+ require 'timeout'
281
+ timeout(5) do
282
+ open(SYNONYM_LOOKUP_URI % word) do |stream|
283
+ data = stream.read.gsub("&nbsp;", " ").gsub("<BR>", "")
284
+ data.scan(/^Sense \d+\n.+?\n\n/m)
285
+ end
286
+ end
287
+ rescue Exception
288
+ return nil
289
+ end
290
+ end
291
+
292
+
293
+ # Undo the actions performed by a generator. Rewind the action
294
+ # manifest and attempt to completely erase the results of each action.
295
+ class Destroy < RewindBase
296
+ # Remove a file if it exists and is a file.
297
+ def file(relative_source, relative_destination, options = {})
298
+ destination = destination_path(relative_destination)
299
+ if File.exists?(destination)
300
+ logger.rm relative_destination
301
+ FileUtils.rm(destination) unless options[:pretend]
302
+ else
303
+ logger.missing relative_destination
304
+ return
305
+ end
306
+ end
307
+
308
+ # Templates are deleted just like files and the actions take the
309
+ # same parameters, so simply alias the file method.
310
+ alias_method :template, :file
311
+
312
+ # Remove each directory in the given path from right to left.
313
+ # Remove each subdirectory if it exists and is a directory.
314
+ def directory(relative_path)
315
+ parts = relative_path.split('/')
316
+ until parts.empty?
317
+ partial = File.join(parts)
318
+ path = destination_path(partial)
319
+ if File.exists?(path)
320
+ if Dir[File.join(path, '*')].empty?
321
+ logger.rmdir partial
322
+ FileUtils.rmdir(path) unless options[:pretend]
323
+ else
324
+ logger.notempty partial
325
+ end
326
+ else
327
+ logger.missing partial
328
+ end
329
+ parts.pop
330
+ end
331
+ end
332
+
333
+ def complex_template(*args)
334
+ # nothing should be done here
335
+ end
336
+ end
337
+
338
+
339
+ # List a generator's action manifest.
340
+ class List < Base
341
+ def dependency(generator_name, args, options = {})
342
+ logger.dependency "#{generator_name}(#{args.join(', ')}, #{options.inspect})"
343
+ end
344
+
345
+ def class_collisions(*class_names)
346
+ logger.class_collisions class_names.join(', ')
347
+ end
348
+
349
+ def file(relative_source, relative_destination, options = {})
350
+ logger.file relative_destination
351
+ end
352
+
353
+ def template(relative_source, relative_destination, options = {})
354
+ logger.template relative_destination
355
+ end
356
+
357
+ def complex_template(relative_source, relative_destination, options = {})
358
+ logger.template "#{options[:insert]} inside #{relative_destination}"
359
+ end
360
+
361
+ def directory(relative_path)
362
+ logger.directory "#{destination_path(relative_path)}/"
363
+ end
364
+
365
+ def readme(*args)
366
+ logger.readme args.join(', ')
367
+ end
368
+ end
369
+
370
+ # Update generator's action manifest.
371
+ class Update < Create
372
+ def file(relative_source, relative_destination, options = {})
373
+ # logger.file relative_destination
374
+ end
375
+
376
+ def template(relative_source, relative_destination, options = {})
377
+ # logger.template relative_destination
378
+ end
379
+
380
+ def complex_template(relative_source, relative_destination, template_options = {})
381
+
382
+ begin
383
+ dest_file = destination_path(relative_destination)
384
+ source_to_update = File.readlines(dest_file).join
385
+ rescue Errno::ENOENT
386
+ logger.missing relative_destination
387
+ return
388
+ end
389
+
390
+ logger.refreshing "#{template_options[:insert].gsub(/\.rhtml/,'')} inside #{relative_destination}"
391
+
392
+ begin_mark = Regexp.quote(template_part_mark(template_options[:begin_mark], template_options[:mark_id]))
393
+ end_mark = Regexp.quote(template_part_mark(template_options[:end_mark], template_options[:mark_id]))
394
+
395
+ # Refreshing inner part of the template with freshly rendered part.
396
+ rendered_part = render_template_part(template_options)
397
+ source_to_update.gsub!(/#{begin_mark}.*?#{end_mark}/m, rendered_part)
398
+
399
+ File.open(dest_file, 'w') { |file| file.write(source_to_update) }
400
+ end
401
+
402
+ def directory(relative_path)
403
+ # logger.directory "#{destination_path(relative_path)}/"
404
+ end
405
+ end
406
+
407
+ end
408
+ end
409
+ end
@@ -0,0 +1,16 @@
1
+ Description:
2
+ The 'rails' command creates a new Rails application with a default
3
+ directory structure and configuration at the path you specify.
4
+
5
+ Example:
6
+ rails ~/Code/Ruby/weblog
7
+
8
+ This generates a skeletal Rails installation in ~/Code/Ruby/weblog.
9
+ See the README in the newly created application to get going.
10
+
11
+ WARNING:
12
+ Only specify --without-gems if you did not use gems to install Rails.
13
+ Your application will expect to find activerecord, actionpack, and
14
+ actionmailer directories in the vendor directory. A popular way to track
15
+ the bleeding edge of Rails development is to checkout from source control
16
+ directly to the vendor directory. See http://dev.rubyonrails.com
@@ -0,0 +1,120 @@
1
+ require 'rbconfig'
2
+
3
+ class AppGenerator < Rails::Generator::Base
4
+ DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
5
+ Config::CONFIG['ruby_install_name'])
6
+
7
+ default_options :gem => true, :shebang => DEFAULT_SHEBANG
8
+ mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.."
9
+
10
+ def initialize(runtime_args, runtime_options = {})
11
+ super
12
+ usage if args.empty?
13
+ @destination_root = args.shift
14
+ end
15
+
16
+ def manifest
17
+ script_options = { :chmod => 0755, :shebang => options[:shebang] }
18
+
19
+ record do |m|
20
+ # Root directory and all subdirectories.
21
+ m.directory ''
22
+ BASEDIRS.each { |path| m.directory path }
23
+
24
+ # Root
25
+ m.file "fresh_rakefile", "Rakefile"
26
+ m.file "README", "README"
27
+ m.file "CHANGELOG", "CHANGELOG"
28
+
29
+ # Application
30
+ m.template "helpers/application.rb", "app/controllers/application.rb"
31
+ m.template "helpers/application_helper.rb", "app/helpers/application_helper.rb"
32
+ m.template "helpers/test_helper.rb", "test/test_helper.rb"
33
+
34
+ # database.yml and .htaccess
35
+ m.template "configs/database.yml", "config/database.yml"
36
+ m.template "configs/routes.rb", "config/routes.rb"
37
+ m.template "configs/apache.conf", "public/.htaccess"
38
+
39
+ # Environments
40
+ if options[:gem]
41
+ m.file "environments/shared_for_gem.rb", "config/environment.rb"
42
+ else
43
+ m.file "environments/shared.rb", "config/environment.rb"
44
+ end
45
+ m.file "environments/production.rb", "config/environments/production.rb"
46
+ m.file "environments/development.rb", "config/environments/development.rb"
47
+ m.file "environments/test.rb", "config/environments/test.rb"
48
+
49
+ # Scripts
50
+ %w(console console_sandbox.rb destroy generate server).each do |file|
51
+ m.file "bin/#{file}", "script/#{file}", script_options
52
+ end
53
+ if options[:gem]
54
+ m.file "bin/breakpointer_for_gem", "script/breakpointer", script_options
55
+ else
56
+ m.file "bin/breakpointer", "script/breakpointer", script_options
57
+ end
58
+
59
+ # Dispatches
60
+ m.file "dispatches/dispatch.rb", "public/dispatch.rb", script_options
61
+ m.file "dispatches/dispatch.rb", "public/dispatch.cgi", script_options
62
+ m.file "dispatches/dispatch.fcgi", "public/dispatch.fcgi", script_options
63
+
64
+ # HTML files
65
+ %w(404 500 index).each do |file|
66
+ m.template "html/#{file}.html", "public/#{file}.html"
67
+ end
68
+
69
+ # Docs
70
+ m.file "doc/README_FOR_APP", "doc/README_FOR_APP"
71
+
72
+ # Logs
73
+ %w(server production development test).each { |file|
74
+ m.file "configs/empty.log", "log/#{file}.log", :chmod => 0666
75
+ }
76
+ end
77
+ end
78
+
79
+ protected
80
+ def banner
81
+ "Usage: #{$0} /path/to/your/app [options]"
82
+ end
83
+
84
+ def add_options!(opt)
85
+ opt.separator ''
86
+ opt.separator 'Options:'
87
+ opt.on("--ruby [#{DEFAULT_SHEBANG}]",
88
+ "Path to the Ruby binary of your choice.") { |options[:shebang]| }
89
+ opt.on("--without-gems",
90
+ "Don't use the Rails gems for your app.",
91
+ "WARNING: see note below.") { |options[:gem]| }
92
+ end
93
+
94
+
95
+ # Installation skeleton. Intermediate directories are automatically
96
+ # created so don't sweat their absence here.
97
+ BASEDIRS = %w(
98
+ app/apis
99
+ app/controllers
100
+ app/helpers
101
+ app/models
102
+ app/views/layouts
103
+ config/environments
104
+ components
105
+ db
106
+ doc
107
+ lib
108
+ log
109
+ public/images
110
+ public/javascripts
111
+ public/stylesheets
112
+ script
113
+ test/fixtures
114
+ test/functional
115
+ test/mocks/development
116
+ test/mocks/testing
117
+ test/unit
118
+ vendor
119
+ )
120
+ end