rails 1.0.0 → 2.0.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 (177) hide show
  1. data/CHANGELOG +1020 -10
  2. data/MIT-LICENSE +1 -1
  3. data/README +110 -60
  4. data/Rakefile +74 -139
  5. data/bin/about +1 -1
  6. data/bin/console +1 -1
  7. data/bin/destroy +1 -1
  8. data/bin/generate +1 -1
  9. data/bin/performance/request +3 -0
  10. data/bin/plugin +1 -1
  11. data/bin/process/{spinner → inspector} +1 -1
  12. data/bin/rails +10 -12
  13. data/bin/runner +1 -1
  14. data/bin/server +1 -1
  15. data/{lib/rails_info.rb → builtin/rails_info/rails/info.rb} +33 -14
  16. data/builtin/rails_info/rails/info_controller.rb +9 -0
  17. data/builtin/rails_info/rails/info_helper.rb +2 -0
  18. data/builtin/rails_info/rails_info_controller.rb +2 -0
  19. data/configs/apache.conf +1 -1
  20. data/configs/databases/frontbase.yml +28 -0
  21. data/configs/databases/mysql.yml +54 -0
  22. data/configs/databases/oracle.yml +39 -0
  23. data/configs/databases/postgresql.yml +48 -0
  24. data/configs/databases/sqlite2.yml +16 -0
  25. data/configs/databases/sqlite3.yml +19 -0
  26. data/configs/initializers/inflections.rb +10 -0
  27. data/configs/initializers/mime_types.rb +5 -0
  28. data/configs/lighttpd.conf +29 -15
  29. data/configs/routes.rb +27 -11
  30. data/doc/README_FOR_APP +1 -1
  31. data/environments/boot.rb +103 -14
  32. data/environments/development.rb +5 -6
  33. data/environments/environment.rb +36 -30
  34. data/environments/production.rb +2 -3
  35. data/environments/test.rb +5 -2
  36. data/fresh_rakefile +2 -2
  37. data/helpers/application.rb +8 -2
  38. data/helpers/test_helper.rb +10 -0
  39. data/html/404.html +27 -5
  40. data/html/422.html +30 -0
  41. data/html/500.html +27 -5
  42. data/html/index.html +6 -6
  43. data/html/javascripts/application.js +2 -0
  44. data/html/javascripts/controls.js +532 -319
  45. data/html/javascripts/dragdrop.js +521 -133
  46. data/html/javascripts/effects.js +708 -442
  47. data/html/javascripts/prototype.js +3393 -953
  48. data/html/robots.txt +5 -1
  49. data/lib/code_statistics.rb +2 -2
  50. data/lib/commands/console.rb +18 -9
  51. data/lib/commands/performance/profiler.rb +25 -9
  52. data/lib/commands/performance/request.rb +6 -0
  53. data/lib/commands/plugin.rb +196 -96
  54. data/lib/commands/process/inspector.rb +68 -0
  55. data/lib/commands/process/reaper.rb +90 -71
  56. data/lib/commands/process/spawner.rb +188 -21
  57. data/lib/commands/process/spinner.rb +3 -3
  58. data/lib/commands/runner.rb +28 -7
  59. data/lib/commands/server.rb +20 -9
  60. data/lib/commands/servers/base.rb +31 -0
  61. data/lib/commands/servers/lighttpd.rb +60 -26
  62. data/lib/commands/servers/mongrel.rb +69 -0
  63. data/lib/commands/servers/webrick.rb +18 -11
  64. data/lib/console_app.rb +30 -0
  65. data/lib/console_sandbox.rb +2 -2
  66. data/lib/console_with_helpers.rb +26 -0
  67. data/lib/dispatcher.rb +3 -78
  68. data/lib/fcgi_handler.rb +98 -64
  69. data/lib/initializer.rb +323 -194
  70. data/lib/rails/plugin/loader.rb +150 -0
  71. data/lib/rails/plugin/locator.rb +78 -0
  72. data/lib/rails/plugin.rb +84 -0
  73. data/lib/{rails_version.rb → rails/version.rb} +1 -1
  74. data/lib/rails_generator/base.rb +85 -25
  75. data/lib/rails_generator/commands.rb +122 -40
  76. data/lib/rails_generator/generated_attribute.rb +42 -0
  77. data/lib/rails_generator/generators/applications/app/USAGE +0 -7
  78. data/lib/rails_generator/generators/applications/app/app_generator.rb +67 -28
  79. data/lib/rails_generator/generators/components/controller/USAGE +11 -12
  80. data/lib/rails_generator/generators/components/controller/controller_generator.rb +2 -3
  81. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +1 -11
  82. data/lib/rails_generator/generators/components/controller/templates/{view.rhtml → view.html.erb} +0 -0
  83. data/lib/rails_generator/generators/components/integration_test/USAGE +8 -0
  84. data/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb +16 -0
  85. data/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb +10 -0
  86. data/lib/rails_generator/generators/components/mailer/USAGE +9 -11
  87. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +10 -8
  88. data/lib/rails_generator/generators/components/mailer/templates/fixture.erb +3 -0
  89. data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +0 -3
  90. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +9 -25
  91. data/lib/rails_generator/generators/components/mailer/templates/view.erb +3 -0
  92. data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +0 -3
  93. data/lib/rails_generator/generators/components/migration/USAGE +23 -8
  94. data/lib/rails_generator/generators/components/migration/migration_generator.rb +15 -2
  95. data/lib/rails_generator/generators/components/migration/templates/migration.rb +7 -3
  96. data/lib/rails_generator/generators/components/model/USAGE +21 -11
  97. data/lib/rails_generator/generators/components/model/model_generator.rb +28 -1
  98. data/lib/rails_generator/generators/components/model/templates/fixtures.yml +18 -4
  99. data/lib/rails_generator/generators/components/model/templates/migration.rb +16 -0
  100. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +2 -4
  101. data/lib/rails_generator/generators/components/observer/USAGE +13 -0
  102. data/lib/rails_generator/generators/components/observer/observer_generator.rb +16 -0
  103. data/lib/rails_generator/generators/components/observer/templates/observer.rb +2 -0
  104. data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +8 -0
  105. data/lib/rails_generator/generators/components/plugin/USAGE +10 -18
  106. data/lib/rails_generator/generators/components/plugin/plugin_generator.rb +6 -0
  107. data/lib/rails_generator/generators/components/plugin/templates/MIT-LICENSE +20 -0
  108. data/lib/rails_generator/generators/components/plugin/templates/README +10 -1
  109. data/lib/rails_generator/generators/components/plugin/templates/Rakefile +1 -1
  110. data/lib/rails_generator/generators/components/plugin/templates/USAGE +1 -1
  111. data/lib/rails_generator/generators/components/plugin/templates/init.rb +1 -1
  112. data/lib/rails_generator/generators/components/plugin/templates/install.rb +1 -0
  113. data/lib/rails_generator/generators/components/plugin/templates/plugin.rb +1 -1
  114. data/lib/rails_generator/generators/components/plugin/templates/tasks.rake +1 -1
  115. data/lib/rails_generator/generators/components/plugin/templates/uninstall.rb +1 -0
  116. data/lib/rails_generator/generators/components/resource/USAGE +23 -0
  117. data/lib/rails_generator/generators/components/resource/resource_generator.rb +74 -0
  118. data/lib/rails_generator/generators/components/resource/templates/controller.rb +2 -0
  119. data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +8 -0
  120. data/lib/rails_generator/generators/components/resource/templates/helper.rb +2 -0
  121. data/lib/rails_generator/generators/components/scaffold/USAGE +24 -31
  122. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +45 -137
  123. data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +65 -34
  124. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +23 -76
  125. data/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb +17 -0
  126. data/lib/rails_generator/generators/components/scaffold/templates/style.css +5 -5
  127. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb +19 -0
  128. data/lib/rails_generator/generators/components/scaffold/templates/view_index.html.erb +24 -0
  129. data/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb +18 -0
  130. data/lib/rails_generator/generators/components/scaffold/templates/view_show.html.erb +10 -0
  131. data/lib/rails_generator/generators/components/session_migration/USAGE +6 -11
  132. data/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb +7 -1
  133. data/lib/rails_generator/generators/components/session_migration/templates/migration.rb +8 -7
  134. data/lib/rails_generator/lookup.rb +46 -12
  135. data/lib/rails_generator/options.rb +11 -8
  136. data/lib/rails_generator/scripts/destroy.rb +23 -0
  137. data/lib/rails_generator/scripts.rb +7 -4
  138. data/lib/rails_generator/secret_key_generator.rb +160 -0
  139. data/lib/rails_generator/spec.rb +1 -1
  140. data/lib/rails_generator.rb +1 -1
  141. data/lib/railties_path.rb +1 -1
  142. data/lib/ruby_version_check.rb +17 -0
  143. data/lib/source_annotation_extractor.rb +62 -0
  144. data/lib/tasks/annotations.rake +23 -0
  145. data/lib/tasks/databases.rake +328 -133
  146. data/lib/tasks/documentation.rake +72 -68
  147. data/lib/tasks/framework.rake +99 -58
  148. data/lib/tasks/log.rake +9 -0
  149. data/lib/tasks/misc.rake +2 -17
  150. data/lib/tasks/rails.rb +2 -2
  151. data/lib/tasks/routes.rake +17 -0
  152. data/lib/tasks/statistics.rake +10 -8
  153. data/lib/tasks/testing.rake +99 -31
  154. data/lib/tasks/tmp.rake +37 -0
  155. data/lib/test_help.rb +8 -5
  156. data/lib/webrick_server.rb +11 -16
  157. metadata +312 -272
  158. data/bin/breakpointer +0 -3
  159. data/builtin/controllers/rails_info_controller.rb +0 -11
  160. data/configs/database.yml +0 -85
  161. data/lib/binding_of_caller.rb +0 -85
  162. data/lib/breakpoint.rb +0 -523
  163. data/lib/breakpoint_client.rb +0 -196
  164. data/lib/commands/breakpointer.rb +0 -1
  165. data/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +0 -3
  166. data/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml +0 -1
  167. data/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml +0 -13
  168. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +0 -9
  169. data/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +0 -27
  170. data/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +0 -8
  171. data/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml +0 -8
  172. data/lib/rails_generator/generators/components/web_service/USAGE +0 -28
  173. data/lib/rails_generator/generators/components/web_service/templates/api_definition.rb +0 -5
  174. data/lib/rails_generator/generators/components/web_service/templates/controller.rb +0 -8
  175. data/lib/rails_generator/generators/components/web_service/templates/functional_test.rb +0 -19
  176. data/lib/rails_generator/generators/components/web_service/web_service_generator.rb +0 -29
  177. data/lib/tasks/javascripts.rake +0 -6
@@ -1,6 +1,7 @@
1
1
  require 'delegate'
2
2
  require 'optparse'
3
3
  require 'fileutils'
4
+ require 'tempfile'
4
5
  require 'erb'
5
6
 
6
7
  module Rails
@@ -16,7 +17,7 @@ module Rails
16
17
  # Even more convenient access to commands. Include Commands in
17
18
  # the generator Base class to get a nice #command instance method
18
19
  # which returns a delegate for the requested command.
19
- def self.append_features(base)
20
+ def self.included(base)
20
21
  base.send(:define_method, :command) do |command|
21
22
  Commands.instance(command, self)
22
23
  end
@@ -61,7 +62,7 @@ module Rails
61
62
  end
62
63
 
63
64
  def existing_migrations(file_name)
64
- Dir.glob("#{@migration_directory}/[0-9]*_#{file_name}.rb")
65
+ Dir.glob("#{@migration_directory}/[0-9]*_*.rb").grep(/[0-9]+_#{file_name}.rb$/)
65
66
  end
66
67
 
67
68
  def migration_exists?(file_name)
@@ -69,7 +70,7 @@ module Rails
69
70
  end
70
71
 
71
72
  def current_migration_number
72
- Dir.glob("#{@migration_directory}/[0-9]*.rb").inject(0) do |max, file_path|
73
+ Dir.glob("#{RAILS_ROOT}/#{@migration_directory}/[0-9]*_*.rb").inject(0) do |max, file_path|
73
74
  n = File.basename(file_path).split('_', 2).first.to_i
74
75
  if n > max then n else max end
75
76
  end
@@ -83,24 +84,52 @@ module Rails
83
84
  "%.#{padding}d" % next_migration_number
84
85
  end
85
86
 
87
+ def gsub_file(relative_destination, regexp, *args, &block)
88
+ path = destination_path(relative_destination)
89
+ content = File.read(path).gsub(regexp, *args, &block)
90
+ File.open(path, 'wb') { |file| file.write(content) }
91
+ end
92
+
86
93
  private
87
94
  # Ask the user interactively whether to force collision.
88
- def force_file_collision?(destination)
89
- $stdout.print "overwrite #{destination}? [Ynaq] "
90
- case $stdin.gets
91
- when /a/i
95
+ def force_file_collision?(destination, src, dst, file_options = {}, &block)
96
+ $stdout.print "overwrite #{destination}? (enter \"h\" for help) [Ynaqdh] "
97
+ case $stdin.gets.chomp
98
+ when /\Ad\z/i
99
+ Tempfile.open(File.basename(destination), File.dirname(dst)) do |temp|
100
+ temp.write render_file(src, file_options, &block)
101
+ temp.rewind
102
+ $stdout.puts `#{diff_cmd} #{dst} #{temp.path}`
103
+ end
104
+ puts "retrying"
105
+ raise 'retry diff'
106
+ when /\Aa\z/i
92
107
  $stdout.puts "forcing #{spec.name}"
93
108
  options[:collision] = :force
94
- when /q/i
109
+ when /\Aq\z/i
95
110
  $stdout.puts "aborting #{spec.name}"
96
111
  raise SystemExit
97
- when /n/i then :skip
98
- else :force
112
+ when /\An\z/i then :skip
113
+ when /\Ay\z/i then :force
114
+ else
115
+ $stdout.puts <<-HELP
116
+ Y - yes, overwrite
117
+ n - no, do not overwrite
118
+ a - all, overwrite this and all others
119
+ q - quit, abort
120
+ d - diff, show the differences between the old and the new
121
+ h - help, show this help
122
+ HELP
123
+ raise 'retry'
99
124
  end
100
125
  rescue
101
126
  retry
102
127
  end
103
128
 
129
+ def diff_cmd
130
+ ENV['RAILS_DIFF'] || 'diff -u'
131
+ end
132
+
104
133
  def render_template_part(template_options)
105
134
  # Getting Sandbox to evaluate part template in it
106
135
  part_binding = template_options[:sandbox].call.sandbox_binding
@@ -163,11 +192,13 @@ module Rails
163
192
 
164
193
  # Copy a file from source to destination with collision checking.
165
194
  #
166
- # The file_options hash accepts :chmod and :shebang options.
195
+ # The file_options hash accepts :chmod and :shebang and :collision options.
167
196
  # :chmod sets the permissions of the destination file:
168
197
  # file 'config/empty.log', 'log/test.log', :chmod => 0664
169
198
  # :shebang sets the #!/usr/bin/ruby line for scripts
170
199
  # file 'bin/generate.rb', 'script/generate', :chmod => 0755, :shebang => '/usr/bin/env ruby'
200
+ # :collision sets the collision option only for the destination file:
201
+ # file 'settings/server.yml', 'config/server.yml', :collision => :skip
171
202
  #
172
203
  # Collisions are handled by checking whether the destination file
173
204
  # exists and either skipping the file, forcing overwrite, or asking
@@ -188,8 +219,8 @@ module Rails
188
219
 
189
220
  # Make a choice whether to overwrite the file. :force and
190
221
  # :skip already have their mind made up, but give :ask a shot.
191
- choice = case options[:collision].to_sym #|| :ask
192
- when :ask then force_file_collision?(relative_destination)
222
+ choice = case (file_options[:collision] || options[:collision]).to_sym #|| :ask
223
+ when :ask then force_file_collision?(relative_destination, source, destination, file_options, &block)
193
224
  when :force then :force
194
225
  when :skip then :skip
195
226
  else raise "Invalid collision option: #{options[:collision].inspect}"
@@ -215,27 +246,15 @@ module Rails
215
246
  # if block given so templaters may render the source file. If a
216
247
  # shebang is requested, replace the existing shebang or insert a
217
248
  # new one.
218
- File.open(destination, 'wb') do |df|
219
- File.open(source, 'rb') do |sf|
220
- if block_given?
221
- df.write(yield(sf))
222
- else
223
- if file_options[:shebang]
224
- df.puts("#!#{file_options[:shebang]}")
225
- if line = sf.gets
226
- df.puts(line) if line !~ /^#!/
227
- end
228
- end
229
- df.write(sf.read)
230
- end
231
- end
249
+ File.open(destination, 'wb') do |dest|
250
+ dest.write render_file(source, file_options, &block)
232
251
  end
233
252
 
234
253
  # Optionally change permissions.
235
254
  if file_options[:chmod]
236
255
  FileUtils.chmod(file_options[:chmod], destination)
237
256
  end
238
-
257
+
239
258
  # Optionally add file to subversion
240
259
  system("svn add #{destination}") if options[:svn]
241
260
  end
@@ -251,7 +270,7 @@ module Rails
251
270
  end
252
271
 
253
272
  # Generate a file for a Rails application using an ERuby template.
254
- # Looks up and evalutes a template by name and writes the result.
273
+ # Looks up and evaluates a template by name and writes the result.
255
274
  #
256
275
  # The ERB template uses explicit trim mode to best control the
257
276
  # proliferation of whitespace in generated code. <%- trims leading
@@ -291,12 +310,26 @@ module Rails
291
310
  logger.exists relative_path
292
311
  else
293
312
  logger.create relative_path
294
- FileUtils.mkdir_p(path) unless options[:pretend]
295
-
296
- # Optionally add file to subversion
297
- system("svn add #{path}") if options[:svn]
298
- end
299
- end
313
+ unless options[:pretend]
314
+ FileUtils.mkdir_p(path)
315
+
316
+ # Subversion doesn't do path adds, so we need to add
317
+ # each directory individually.
318
+ # So stack up the directory tree and add the paths to
319
+ # subversion in order without recursion.
320
+ if options[:svn]
321
+ stack=[relative_path]
322
+ until File.dirname(stack.last) == stack.last # dirname('.') == '.'
323
+ stack.push File.dirname(stack.last)
324
+ end
325
+ stack.reverse_each do |rel_path|
326
+ svn_path = destination_path(rel_path)
327
+ system("svn add -N #{svn_path}") unless File.directory?(File.join(svn_path, '.svn'))
328
+ end
329
+ end
330
+ end
331
+ end
332
+ end
300
333
 
301
334
  # Display a README.
302
335
  def readme(*relative_sources)
@@ -309,11 +342,41 @@ module Rails
309
342
  # When creating a migration, it knows to find the first available file in db/migrate and use the migration.rb template.
310
343
  def migration_template(relative_source, relative_destination, template_options = {})
311
344
  migration_directory relative_destination
312
- raise "Another migration is already named #{file_name}: #{existing_migrations(file_name).first}" if migration_exists?(file_name)
313
- template(relative_source, "#{relative_destination}/#{next_migration_string}_#{file_name}.rb", template_options)
345
+ migration_file_name = template_options[:migration_file_name] || file_name
346
+ raise "Another migration is already named #{migration_file_name}: #{existing_migrations(migration_file_name).first}" if migration_exists?(migration_file_name)
347
+ template(relative_source, "#{relative_destination}/#{next_migration_string}_#{migration_file_name}.rb", template_options)
348
+ end
349
+
350
+ def route_resources(*resources)
351
+ resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
352
+ sentinel = 'ActionController::Routing::Routes.draw do |map|'
353
+
354
+ logger.route "map.resources #{resource_list}"
355
+ unless options[:pretend]
356
+ gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
357
+ "#{match}\n map.resources #{resource_list}\n"
358
+ end
359
+ end
314
360
  end
315
361
 
316
362
  private
363
+ def render_file(path, options = {})
364
+ File.open(path, 'rb') do |file|
365
+ if block_given?
366
+ yield file
367
+ else
368
+ content = ''
369
+ if shebang = options[:shebang]
370
+ content << "#!#{shebang}\n"
371
+ if line = file.gets
372
+ content << "line\n" if line !~ /^#!/
373
+ end
374
+ end
375
+ content << file.read
376
+ end
377
+ end
378
+ end
379
+
317
380
  # Raise a usage error with an informative WordNet suggestion.
318
381
  # Thanks to Florian Gross (flgr).
319
382
  def raise_class_collision(class_name)
@@ -423,11 +486,25 @@ end_message
423
486
  # When deleting a migration, it knows to delete every file named "[0-9]*_#{file_name}".
424
487
  def migration_template(relative_source, relative_destination, template_options = {})
425
488
  migration_directory relative_destination
426
- raise "There is no migration named #{file_name}" unless migration_exists?(file_name)
427
- existing_migrations(file_name).each do |file_path|
489
+
490
+ migration_file_name = template_options[:migration_file_name] || file_name
491
+ unless migration_exists?(migration_file_name)
492
+ puts "There is no migration named #{migration_file_name}"
493
+ return
494
+ end
495
+
496
+
497
+ existing_migrations(migration_file_name).each do |file_path|
428
498
  file(relative_source, file_path, template_options)
429
499
  end
430
500
  end
501
+
502
+ def route_resources(*resources)
503
+ resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
504
+ look_for = "\n map.resources #{resource_list}\n"
505
+ logger.route "map.resources #{resource_list}"
506
+ gsub_file 'config/routes.rb', /(#{look_for})/mi, ''
507
+ end
431
508
  end
432
509
 
433
510
 
@@ -465,6 +542,11 @@ end_message
465
542
  migration_directory relative_destination
466
543
  logger.migration_template file_name
467
544
  end
545
+
546
+ def route_resources(*resources)
547
+ resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
548
+ logger.route "map.resources #{resource_list}"
549
+ end
468
550
  end
469
551
 
470
552
  # Update generator's action manifest.
@@ -487,7 +569,7 @@ end_message
487
569
  return
488
570
  end
489
571
 
490
- logger.refreshing "#{template_options[:insert].gsub(/\.rhtml/,'')} inside #{relative_destination}"
572
+ logger.refreshing "#{template_options[:insert].gsub(/\.erb/,'')} inside #{relative_destination}"
491
573
 
492
574
  begin_mark = Regexp.quote(template_part_mark(template_options[:begin_mark], template_options[:mark_id]))
493
575
  end_mark = Regexp.quote(template_part_mark(template_options[:end_mark], template_options[:mark_id]))
@@ -0,0 +1,42 @@
1
+ require 'optparse'
2
+
3
+ module Rails
4
+ module Generator
5
+ class GeneratedAttribute
6
+ attr_accessor :name, :type, :column
7
+
8
+ def initialize(name, type)
9
+ @name, @type = name, type.to_sym
10
+ @column = ActiveRecord::ConnectionAdapters::Column.new(name, nil, @type)
11
+ end
12
+
13
+ def field_type
14
+ @field_type ||= case type
15
+ when :integer, :float, :decimal then :text_field
16
+ when :datetime, :timestamp, :time then :datetime_select
17
+ when :date then :date_select
18
+ when :string then :text_field
19
+ when :text then :text_area
20
+ when :boolean then :check_box
21
+ else
22
+ :text_field
23
+ end
24
+ end
25
+
26
+ def default
27
+ @default ||= case type
28
+ when :integer then 1
29
+ when :float then 1.5
30
+ when :decimal then "9.99"
31
+ when :datetime, :timestamp, :time then Time.now.to_s(:db)
32
+ when :date then Date.today.to_s(:db)
33
+ when :string then "MyString"
34
+ when :text then "MyText"
35
+ when :boolean then false
36
+ else
37
+ ""
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -7,10 +7,3 @@ Example:
7
7
 
8
8
  This generates a skeletal Rails installation in ~/Code/Ruby/weblog.
9
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
@@ -1,24 +1,42 @@
1
1
  require 'rbconfig'
2
+ require 'digest/md5'
3
+ require 'rails_generator/secret_key_generator'
2
4
 
3
5
  class AppGenerator < Rails::Generator::Base
4
6
  DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
5
7
  Config::CONFIG['ruby_install_name'])
6
-
7
- default_options :gem => true, :shebang => DEFAULT_SHEBANG
8
- mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.."
8
+
9
+ DATABASES = %w(mysql oracle postgresql sqlite2 sqlite3 frontbase)
10
+
11
+ default_options :db => (ENV["RAILS_DEFAULT_DATABASE"] || "mysql"),
12
+ :shebang => DEFAULT_SHEBANG, :freeze => false
13
+ mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.."
9
14
 
10
15
  def initialize(runtime_args, runtime_options = {})
11
16
  super
12
17
  usage if args.empty?
18
+ usage("Databases supported for preconfiguration are: #{DATABASES.join(", ")}") if (options[:db] && !DATABASES.include?(options[:db]))
13
19
  @destination_root = args.shift
14
- @socket = MYSQL_SOCKET_LOCATIONS.find { |f| File.exists?(f) }
15
- @socket = '/path/to/your/mysql.sock' if @socket.blank?
20
+ @app_name = File.basename(File.expand_path(@destination_root))
16
21
  end
17
22
 
18
23
  def manifest
19
- script_options = { :chmod => 0755 }
24
+ # Use /usr/bin/env if no special shebang was specified
25
+ script_options = { :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang] }
20
26
  dispatcher_options = { :chmod => 0755, :shebang => options[:shebang] }
21
27
 
28
+ # duplicate CGI::Session#generate_unique_id
29
+ md5 = Digest::MD5.new
30
+ now = Time.now
31
+ md5 << now.to_s
32
+ md5 << String(now.usec)
33
+ md5 << String(rand(0))
34
+ md5 << String($$)
35
+ md5 << @app_name
36
+
37
+ # Do our best to generate a secure secret key for CookieStore
38
+ secret = Rails::SecretKeyGenerator.new(@app_name).generate_secret
39
+
22
40
  record do |m|
23
41
  # Root directory and all subdirectories.
24
42
  m.directory ''
@@ -29,27 +47,31 @@ class AppGenerator < Rails::Generator::Base
29
47
  m.file "README", "README"
30
48
 
31
49
  # Application
32
- m.template "helpers/application.rb", "app/controllers/application.rb"
50
+ m.template "helpers/application.rb", "app/controllers/application.rb", :assigns => { :app_name => @app_name, :app_secret => md5.hexdigest }
33
51
  m.template "helpers/application_helper.rb", "app/helpers/application_helper.rb"
34
52
  m.template "helpers/test_helper.rb", "test/test_helper.rb"
35
53
 
36
54
  # database.yml and .htaccess
37
- m.template "configs/database.yml", "config/database.yml", :assigns => {
38
- :app_name => File.basename(File.expand_path(@destination_root)),
39
- :socket => @socket
55
+ m.template "configs/databases/#{options[:db]}.yml", "config/database.yml", :assigns => {
56
+ :app_name => @app_name,
57
+ :socket => options[:db] == "mysql" ? mysql_socket_location : nil
40
58
  }
41
59
  m.template "configs/routes.rb", "config/routes.rb"
42
60
  m.template "configs/apache.conf", "public/.htaccess"
43
61
 
62
+ # Initializers
63
+ m.template "configs/initializers/inflections.rb", "config/initializers/inflections.rb"
64
+ m.template "configs/initializers/mime_types.rb", "config/initializers/mime_types.rb"
65
+
44
66
  # Environments
45
- m.file "environments/boot.rb", "config/boot.rb"
46
- m.file "environments/environment.rb", "config/environment.rb"
67
+ m.file "environments/boot.rb", "config/boot.rb"
68
+ m.template "environments/environment.rb", "config/environment.rb", :assigns => { :freeze => options[:freeze], :app_name => @app_name, :app_secret => secret }
47
69
  m.file "environments/production.rb", "config/environments/production.rb"
48
70
  m.file "environments/development.rb", "config/environments/development.rb"
49
71
  m.file "environments/test.rb", "config/environments/test.rb"
50
72
 
51
73
  # Scripts
52
- %w( about breakpointer console destroy generate performance/benchmarker performance/profiler process/reaper process/spawner process/spinner runner server plugin ).each do |file|
74
+ %w( about console destroy generate performance/benchmarker performance/profiler performance/request process/reaper process/spawner process/inspector runner server plugin ).each do |file|
53
75
  m.file "bin/#{file}", "script/#{file}", script_options
54
76
  end
55
77
 
@@ -59,19 +81,20 @@ class AppGenerator < Rails::Generator::Base
59
81
  m.file "dispatches/dispatch.fcgi", "public/dispatch.fcgi", dispatcher_options
60
82
 
61
83
  # HTML files
62
- %w(404 500 index).each do |file|
84
+ %w(404 422 500 index).each do |file|
63
85
  m.template "html/#{file}.html", "public/#{file}.html"
64
86
  end
65
-
66
- m.template "html/favicon.ico", "public/favicon.ico"
67
- m.template "html/robots.txt", "public/robots.txt"
87
+
88
+ m.template "html/favicon.ico", "public/favicon.ico"
89
+ m.template "html/robots.txt", "public/robots.txt"
68
90
  m.file "html/images/rails.png", "public/images/rails.png"
69
91
 
70
92
  # Javascripts
71
- m.file "html/javascripts/prototype.js", "public/javascripts/prototype.js"
72
- m.file "html/javascripts/effects.js", "public/javascripts/effects.js"
73
- m.file "html/javascripts/dragdrop.js", "public/javascripts/dragdrop.js"
74
- m.file "html/javascripts/controls.js", "public/javascripts/controls.js"
93
+ m.file "html/javascripts/prototype.js", "public/javascripts/prototype.js"
94
+ m.file "html/javascripts/effects.js", "public/javascripts/effects.js"
95
+ m.file "html/javascripts/dragdrop.js", "public/javascripts/dragdrop.js"
96
+ m.file "html/javascripts/controls.js", "public/javascripts/controls.js"
97
+ m.file "html/javascripts/application.js", "public/javascripts/application.js"
75
98
 
76
99
  # Docs
77
100
  m.file "doc/README_FOR_APP", "doc/README_FOR_APP"
@@ -91,11 +114,21 @@ class AppGenerator < Rails::Generator::Base
91
114
  def add_options!(opt)
92
115
  opt.separator ''
93
116
  opt.separator 'Options:'
94
- opt.on("--ruby [#{DEFAULT_SHEBANG}]",
95
- "Path to the Ruby binary of your choice.") { |options[:shebang]| }
96
- opt.on("--without-gems",
97
- "Don't use the Rails gems for your app.",
98
- "WARNING: see note below.") { |options[:gem]| }
117
+ opt.on("-r", "--ruby=path", String,
118
+ "Path to the Ruby binary of your choice (otherwise scripts use env, dispatchers current path).",
119
+ "Default: #{DEFAULT_SHEBANG}") { |v| options[:shebang] = v }
120
+
121
+ opt.on("-d", "--database=name", String,
122
+ "Preconfigure for selected database (options: mysql/oracle/postgresql/sqlite2/sqlite3).",
123
+ "Default: mysql") { |v| options[:db] = v }
124
+
125
+ opt.on("-f", "--freeze",
126
+ "Freeze Rails in vendor/rails from the gems generating the skeleton",
127
+ "Default: false") { |v| options[:freeze] = v }
128
+ end
129
+
130
+ def mysql_socket_location
131
+ MYSQL_SOCKET_LOCATIONS.find { |f| File.exists?(f) } unless RUBY_PLATFORM =~ /(:?mswin|mingw)/
99
132
  end
100
133
 
101
134
 
@@ -107,7 +140,7 @@ class AppGenerator < Rails::Generator::Base
107
140
  app/models
108
141
  app/views/layouts
109
142
  config/environments
110
- components
143
+ config/initializers
111
144
  db
112
145
  doc
113
146
  lib
@@ -120,11 +153,16 @@ class AppGenerator < Rails::Generator::Base
120
153
  script/process
121
154
  test/fixtures
122
155
  test/functional
156
+ test/integration
123
157
  test/mocks/development
124
158
  test/mocks/test
125
159
  test/unit
126
160
  vendor
127
161
  vendor/plugins
162
+ tmp/sessions
163
+ tmp/sockets
164
+ tmp/cache
165
+ tmp/pids
128
166
  )
129
167
 
130
168
  MYSQL_SOCKET_LOCATIONS = [
@@ -135,6 +173,7 @@ class AppGenerator < Rails::Generator::Base
135
173
  "/opt/local/lib/mysql/mysql.sock", # fedora
136
174
  "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
137
175
  "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
138
- "/opt/local/var/run/mysql5/mysqld.sock" # mac + darwinports + mysql5
176
+ "/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
177
+ "/opt/lampp/var/mysql/mysql.sock" # xampp for linux
139
178
  ]
140
179
  end
@@ -1,30 +1,29 @@
1
1
  Description:
2
- The controller generator creates stubs for a new controller and its views.
2
+ Stubs out a new controller and its views. Pass the controller name, either
3
+ CamelCased or under_scored, and a list of views as arguments.
3
4
 
4
- The generator takes a controller name and a list of views as arguments.
5
- The controller name may be given in CamelCase or under_score and should
6
- not be suffixed with 'Controller'. To create a controller within a
7
- module, specify the controller name as 'module/controller'.
5
+ To create a controller within a module, specify the controller name as a
6
+ path like 'parent_module/controller_name'.
8
7
 
9
- The generator creates a controller class in app/controllers with view
10
- templates in app/views/controller_name, a helper class in app/helpers,
11
- and a functional test suite in test/functional.
8
+ This generates a controller class in app/controllers, view templates in
9
+ app/views/controller_name, a helper class in app/helpers, and a functional
10
+ test suite in test/functional.
12
11
 
13
12
  Example:
14
- ./script/generate controller CreditCard open debit credit close
13
+ `./script/generate controller CreditCard open debit credit close`
15
14
 
16
15
  Credit card controller with URLs like /credit_card/debit.
17
16
  Controller: app/controllers/credit_card_controller.rb
18
- Views: app/views/credit_card/debit.rhtml [...]
17
+ Views: app/views/credit_card/debit.html.erb [...]
19
18
  Helper: app/helpers/credit_card_helper.rb
20
19
  Test: test/functional/credit_card_controller_test.rb
21
20
 
22
21
  Modules Example:
23
- ./script/generate controller 'admin/credit_card' suspend late_fee
22
+ `./script/generate controller 'admin/credit_card' suspend late_fee`
24
23
 
25
24
  Credit card admin controller with URLs /admin/credit_card/suspend.
26
25
  Controller: app/controllers/admin/credit_card_controller.rb
27
- Views: app/views/admin/credit_card/debit.rhtml [...]
26
+ Views: app/views/admin/credit_card/debit.html.erb [...]
28
27
  Helper: app/helpers/admin/credit_card_helper.rb
29
28
  Test: test/functional/admin/credit_card_controller_test.rb
30
29
 
@@ -28,9 +28,8 @@ class ControllerGenerator < Rails::Generator::NamedBase
28
28
 
29
29
  # View template for each action.
30
30
  actions.each do |action|
31
- path = File.join('app/views', class_path, file_name, "#{action}.rhtml")
32
- m.template 'view.rhtml',
33
- path,
31
+ path = File.join('app/views', class_path, file_name, "#{action}.html.erb")
32
+ m.template 'view.html.erb', path,
34
33
  :assigns => { :action => action, :path => path }
35
34
  end
36
35
  end
@@ -1,16 +1,6 @@
1
1
  require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
- require '<%= file_path %>_controller'
3
-
4
- # Re-raise errors caught by the controller.
5
- class <%= class_name %>Controller; def rescue_action(e) raise e end; end
6
-
7
- class <%= class_name %>ControllerTest < Test::Unit::TestCase
8
- def setup
9
- @controller = <%= class_name %>Controller.new
10
- @request = ActionController::TestRequest.new
11
- @response = ActionController::TestResponse.new
12
- end
13
2
 
3
+ class <%= class_name %>ControllerTest < ActionController::TestCase
14
4
  # Replace this with your real tests.
15
5
  def test_truth
16
6
  assert true
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Stubs out a new integration test. Pass the name of the test, either
3
+ CamelCased or under_scored, as an argument. The new test class is
4
+ generated in test/integration/testname_test.rb
5
+
6
+ Example:
7
+ `./script/generate integration_test GeneralStories` creates a GeneralStories
8
+ integration test in test/integration/general_stories_test.rb
@@ -0,0 +1,16 @@
1
+ class IntegrationTestGenerator < Rails::Generator::NamedBase
2
+ default_options :skip_migration => false
3
+
4
+ def manifest
5
+ record do |m|
6
+ # Check for class naming collisions.
7
+ m.class_collisions class_path, class_name, "#{class_name}Test"
8
+
9
+ # integration test directory
10
+ m.directory File.join('test/integration', class_path)
11
+
12
+ # integration test stub
13
+ m.template 'integration_test.rb', File.join('test/integration', class_path, "#{file_name}_test.rb")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ require "#{File.dirname(__FILE__)}<%= '/..' * class_nesting_depth %>/../test_helper"
2
+
3
+ class <%= class_name %>Test < ActionController::IntegrationTest
4
+ # fixtures :your, :models
5
+
6
+ # Replace this with your real tests.
7
+ def test_truth
8
+ assert true
9
+ end
10
+ end
@@ -1,18 +1,16 @@
1
1
  Description:
2
- The mailer generator creates stubs for a new mailer and its views.
2
+ Stubs out a new mailer and its views. Pass the mailer name, either
3
+ CamelCased or under_scored, and an optional list of emails as arguments.
3
4
 
4
- The generator takes a mailer name and a list of views as arguments.
5
- The mailer name may be given in CamelCase or under_score.
6
-
7
- The generator creates a mailer class in app/models with view templates
8
- in app/views/mailer_name, and a test suite with fixtures in test/unit.
5
+ This generates a mailer class in app/models, view templates in
6
+ app/views/mailer_name, a unit test in test/unit, and fixtures in
7
+ test/fixtures.
9
8
 
10
9
  Example:
11
- ./script/generate mailer Notifications signup forgot_password invoice
10
+ `./script/generate mailer Notifications signup forgot_password invoice`
12
11
 
13
- This will create a Notifications mailer class:
12
+ creates a Notifications mailer class, views, test, and fixtures:
14
13
  Mailer: app/models/notifications.rb
15
- Views: app/views/notifications/signup.rhtml [...]
16
- Test: test/unit/credit_card_controller_test.rb
14
+ Views: app/views/notifications/signup.erb [...]
15
+ Test: test/unit/test/unit/notifications_test.rb
17
16
  Fixtures: test/fixtures/notifications/signup [...]
18
-