rails 2.0.5 → 2.1.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 (84) hide show
  1. data/CHANGELOG +115 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README +67 -14
  4. data/Rakefile +9 -19
  5. data/bin/dbconsole +3 -0
  6. data/bin/rails +0 -0
  7. data/builtin/rails_info/rails/info.rb +5 -5
  8. data/configs/apache.conf +0 -0
  9. data/configs/databases/frontbase.yml +2 -2
  10. data/configs/databases/mysql.yml +2 -2
  11. data/configs/databases/oracle.yml +3 -3
  12. data/configs/databases/postgresql.yml +2 -2
  13. data/configs/databases/sqlite2.yml +2 -2
  14. data/configs/databases/sqlite3.yml +2 -2
  15. data/configs/initializers/new_rails_defaults.rb +15 -0
  16. data/configs/routes.rb +6 -0
  17. data/dispatches/dispatch.fcgi +0 -0
  18. data/dispatches/dispatch.rb +0 -0
  19. data/environments/boot.rb +1 -0
  20. data/environments/development.rb +0 -1
  21. data/environments/environment.rb +15 -7
  22. data/environments/production.rb +3 -0
  23. data/environments/test.rb +1 -1
  24. data/fresh_rakefile +0 -0
  25. data/helpers/application.rb +5 -0
  26. data/html/images/rails.png +0 -0
  27. data/html/index.html +6 -9
  28. data/html/javascripts/controls.js +1 -1
  29. data/html/javascripts/dragdrop.js +1 -1
  30. data/html/javascripts/effects.js +1 -1
  31. data/lib/commands/console.rb +2 -2
  32. data/lib/commands/dbconsole.rb +65 -0
  33. data/lib/commands/generate.rb +0 -0
  34. data/lib/commands/performance/profiler.rb +1 -1
  35. data/lib/commands/performance/request.rb +0 -0
  36. data/lib/commands/plugin.rb +28 -1
  37. data/lib/commands/server.rb +2 -2
  38. data/lib/commands/servers/lighttpd.rb +1 -1
  39. data/lib/commands/servers/mongrel.rb +9 -9
  40. data/lib/commands/servers/new_mongrel.rb +16 -0
  41. data/lib/commands/servers/webrick.rb +1 -1
  42. data/lib/console_app.rb +2 -2
  43. data/lib/dispatcher.rb +1 -1
  44. data/lib/fcgi_handler.rb +32 -16
  45. data/lib/initializer.rb +273 -59
  46. data/lib/rails/gem_builder.rb +21 -0
  47. data/lib/rails/gem_dependency.rb +124 -0
  48. data/lib/rails/mongrel_server/commands.rb +342 -0
  49. data/lib/rails/mongrel_server/handler.rb +55 -0
  50. data/lib/rails/plugin.rb +42 -11
  51. data/lib/rails/plugin/loader.rb +3 -1
  52. data/lib/rails/plugin/locator.rb +22 -1
  53. data/lib/rails/version.rb +2 -2
  54. data/lib/rails_generator/base.rb +1 -1
  55. data/lib/rails_generator/commands.rb +63 -47
  56. data/lib/rails_generator/generators/applications/app/app_generator.rb +5 -7
  57. data/lib/rails_generator/generators/components/controller/templates/controller.rb +1 -4
  58. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +1 -1
  59. data/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb +1 -1
  60. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +2 -6
  61. data/lib/rails_generator/generators/components/mailer/templates/mailer.rb +8 -6
  62. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +1 -1
  63. data/lib/rails_generator/generators/components/migration/USAGE +4 -4
  64. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +1 -1
  65. data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +1 -1
  66. data/lib/rails_generator/generators/components/plugin/templates/Rakefile +0 -0
  67. data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +1 -1
  68. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +2 -1
  69. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +1 -1
  70. data/lib/rails_generator/generators/components/scaffold/templates/style.css +0 -20
  71. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb +3 -4
  72. data/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb +3 -4
  73. data/lib/rails_generator/lookup.rb +6 -2
  74. data/lib/rails_generator/options.rb +7 -0
  75. data/lib/rails_generator/scripts.rb +8 -5
  76. data/lib/rails_generator/secret_key_generator.rb +12 -8
  77. data/lib/source_annotation_extractor.rb +40 -0
  78. data/lib/tasks/databases.rake +52 -27
  79. data/lib/tasks/framework.rake +22 -29
  80. data/lib/tasks/gems.rake +64 -0
  81. data/lib/tasks/misc.rake +47 -0
  82. data/lib/tasks/testing.rake +1 -1
  83. data/lib/test_help.rb +8 -0
  84. metadata +19 -15
@@ -0,0 +1,55 @@
1
+ # Copyright (c) 2005 Zed A. Shaw
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
+ # for more information.
6
+
7
+ require 'mongrel'
8
+ require 'cgi'
9
+ require 'action_controller/dispatcher'
10
+
11
+
12
+ module Rails
13
+ module MongrelServer
14
+ # Implements a handler that can run Rails and serve files out of the
15
+ # Rails application's public directory. This lets you run your Rails
16
+ # application with Mongrel during development and testing, then use it
17
+ # also in production behind a server that's better at serving the
18
+ # static files.
19
+ #
20
+ # The RailsHandler takes a mime_map parameter which is a simple suffix=mimetype
21
+ # mapping that it should add to the list of valid mime types.
22
+ #
23
+ # It also supports page caching directly and will try to resolve a request
24
+ # in the following order:
25
+ #
26
+ # * If the requested exact PATH_INFO exists as a file then serve it.
27
+ # * If it exists at PATH_INFO+".html" exists then serve that.
28
+ # * Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispatch to have Rails go.
29
+ #
30
+ # This means that if you are using page caching it will actually work with Mongrel
31
+ # and you should see a decent speed boost (but not as fast as if you use a static
32
+ # server like Apache or Litespeed).
33
+ class RailsHandler < Mongrel::HttpHandler
34
+ # Construct a Mongrel::CGIWrapper and dispatch.
35
+ def process(request, response)
36
+ return if response.socket.closed?
37
+
38
+ cgi = Mongrel::CGIWrapper.new(request, response)
39
+ cgi.handler = self
40
+ # We don't want the output to be really final until we're out of the lock
41
+ cgi.default_really_final = false
42
+
43
+ ActionController::Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body)
44
+
45
+ # This finalizes the output using the proper HttpResponse way
46
+ cgi.out("text/html",true) {""}
47
+ rescue Errno::EPIPE
48
+ response.socket.close
49
+ rescue Object => rails_error
50
+ STDERR.puts "#{Time.now.httpdate}: Error dispatching #{rails_error.inspect}"
51
+ STDERR.puts rails_error.backtrace.join("\n")
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,16 +1,21 @@
1
1
  module Rails
2
-
3
2
  # The Plugin class should be an object which provides the following methods:
4
3
  #
5
- # * +name+ - used during initialisation to order the plugin (based on name and
6
- # the contents of <tt>config.plugins</tt>)
7
- # * +valid?+ - returns true if this plugin can be loaded
8
- # * +load_paths+ - each path within the returned array will be added to the $LOAD_PATH
9
- # * +load+ - finally 'load' the plugin.
4
+ # * +name+ - Used during initialisation to order the plugin (based on name and
5
+ # the contents of <tt>config.plugins</tt>).
6
+ # * +valid?+ - Returns true if this plugin can be loaded.
7
+ # * +load_paths+ - Each path within the returned array will be added to the <tt>$LOAD_PATH</tt>.
8
+ # * +load+ - Finally 'load' the plugin.
10
9
  #
11
10
  # These methods are expected by the Rails::Plugin::Locator and Rails::Plugin::Loader classes.
12
- # The default implementation returns the <tt>lib</tt> directory as its </tt>load_paths</tt>,
11
+ # The default implementation returns the <tt>lib</tt> directory as its <tt>load_paths</tt>,
13
12
  # and evaluates <tt>init.rb</tt> when <tt>load</tt> is called.
13
+ #
14
+ # You can also inspect the about.yml data programmatically:
15
+ #
16
+ # plugin = Rails::Plugin.new(path_to_my_plugin)
17
+ # plugin.about["author"] # => "James Adam"
18
+ # plugin.about["url"] # => "http://interblah.net"
14
19
  class Plugin
15
20
  include Comparable
16
21
 
@@ -18,21 +23,21 @@ module Rails
18
23
 
19
24
  def initialize(directory)
20
25
  @directory = directory
21
- @name = File.basename(@directory) rescue nil
22
- @loaded = false
26
+ @name = File.basename(@directory) rescue nil
27
+ @loaded = false
23
28
  end
24
29
 
25
30
  def valid?
26
31
  File.directory?(directory) && (has_lib_directory? || has_init_file?)
27
32
  end
28
33
 
29
- # Returns a list of paths this plugin wishes to make available in $LOAD_PATH
34
+ # Returns a list of paths this plugin wishes to make available in <tt>$LOAD_PATH</tt>.
30
35
  def load_paths
31
36
  report_nonexistant_or_empty_plugin! unless valid?
32
37
  has_lib_directory? ? [lib_path] : []
33
38
  end
34
39
 
35
- # Evaluates a plugin's init.rb file
40
+ # Evaluates a plugin's init.rb file.
36
41
  def load(initializer)
37
42
  return if loaded?
38
43
  report_nonexistant_or_empty_plugin! unless valid?
@@ -47,8 +52,19 @@ module Rails
47
52
  def <=>(other_plugin)
48
53
  name <=> other_plugin.name
49
54
  end
55
+
56
+ def about
57
+ @about ||= load_about_information
58
+ end
50
59
 
51
60
  private
61
+ def load_about_information
62
+ about_yml_path = File.join(@directory, "about.yml")
63
+ parsed_yml = File.exist?(about_yml_path) ? YAML.load(File.read(about_yml_path)) : {}
64
+ parsed_yml || {}
65
+ rescue Exception
66
+ {}
67
+ end
52
68
 
53
69
  def report_nonexistant_or_empty_plugin!
54
70
  raise LoadError, "Can not find the plugin named: #{name}"
@@ -81,4 +97,19 @@ module Rails
81
97
  end
82
98
  end
83
99
  end
100
+
101
+ # This Plugin subclass represents a Gem plugin. Although RubyGems has already
102
+ # taken care of $LOAD_PATHs, it exposes its load_paths to add them
103
+ # to Dependencies.load_paths.
104
+ class GemPlugin < Plugin
105
+ # Initialize this plugin from a Gem::Specification.
106
+ def initialize(spec)
107
+ super(File.join(spec.full_gem_path))
108
+ @name = spec.name
109
+ end
110
+
111
+ def init_path
112
+ File.join(directory, 'rails', 'init.rb')
113
+ end
114
+ end
84
115
  end
@@ -46,7 +46,9 @@ module Rails
46
46
  plugin.load_paths.each do |path|
47
47
  $LOAD_PATH.insert(application_lib_index + 1, path)
48
48
  Dependencies.load_paths << path
49
- Dependencies.load_once_paths << path
49
+ unless Rails.configuration.reload_plugins?
50
+ Dependencies.load_once_paths << path
51
+ end
50
52
  end
51
53
  end
52
54
  $LOAD_PATH.uniq!
@@ -72,7 +72,28 @@ module Rails
72
72
  plugins
73
73
  end
74
74
  end
75
-
75
+ end
76
+
77
+ # The GemLocator scans all the loaded RubyGems, looking for gems with
78
+ # a <tt>rails/init.rb</tt> file.
79
+ class GemLocator < Locator
80
+ def plugins
81
+ specs = initializer.configuration.gems.map(&:specification)
82
+ specs += Gem.loaded_specs.values.select do |spec|
83
+ spec.loaded_from && # prune stubs
84
+ File.exist?(File.join(spec.full_gem_path, "rails", "init.rb"))
85
+ end
86
+ specs.compact!
87
+
88
+ require "rubygems/dependency_list"
89
+
90
+ deps = Gem::DependencyList.new
91
+ deps.add(*specs) unless specs.empty?
92
+
93
+ deps.dependency_order.collect do |spec|
94
+ Rails::GemPlugin.new(spec)
95
+ end
96
+ end
76
97
  end
77
98
  end
78
99
  end
@@ -1,8 +1,8 @@
1
1
  module Rails
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 2
4
- MINOR = 0
5
- TINY = 5
4
+ MINOR = 1
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -36,7 +36,7 @@ module Rails
36
36
  # view.html.erb
37
37
  #
38
38
  # The directory name (+controller+) matches the name of the generator file
39
- # (controller_generator.rb) and class (+ControllerGenerator+). The files
39
+ # (controller_generator.rb) and class (ControllerGenerator). The files
40
40
  # that will be copied or used as templates are stored in the +templates+
41
41
  # directory.
42
42
  #
@@ -69,19 +69,8 @@ module Rails
69
69
  not existing_migrations(file_name).empty?
70
70
  end
71
71
 
72
- def current_migration_number
73
- Dir.glob("#{RAILS_ROOT}/#{@migration_directory}/[0-9]*_*.rb").inject(0) do |max, file_path|
74
- n = File.basename(file_path).split('_', 2).first.to_i
75
- if n > max then n else max end
76
- end
77
- end
78
-
79
- def next_migration_number
80
- current_migration_number + 1
81
- end
82
-
83
72
  def next_migration_string(padding = 3)
84
- "%.#{padding}d" % next_migration_number
73
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
85
74
  end
86
75
 
87
76
  def gsub_file(relative_destination, regexp, *args, &block)
@@ -165,28 +154,35 @@ HELP
165
154
  # Ruby or Rails. In the future, expand to check other namespaces
166
155
  # such as the rest of the user's app.
167
156
  def class_collisions(*class_names)
157
+
158
+ # Initialize some check varibles
159
+ last_class = Object
160
+ current_class = nil
161
+ name = nil
162
+
168
163
  class_names.flatten.each do |class_name|
169
164
  # Convert to string to allow symbol arguments.
170
165
  class_name = class_name.to_s
171
166
 
172
167
  # Skip empty strings.
173
- next if class_name.strip.empty?
168
+ class_name.strip.empty? ? next : current_class = class_name
174
169
 
175
170
  # Split the class from its module nesting.
176
171
  nesting = class_name.split('::')
177
172
  name = nesting.pop
178
173
 
179
174
  # Extract the last Module in the nesting.
180
- last = nesting.inject(Object) { |last, nest|
181
- break unless last.const_defined?(nest)
182
- last.const_get(nest)
175
+ last = nesting.inject(last_class) { |last, nest|
176
+ break unless last_class.const_defined?(nest)
177
+ last_class = last_class.const_get(nest)
183
178
  }
184
179
 
185
- # If the last Module exists, check whether the given
186
- # class exists and raise a collision if so.
187
- if last and last.const_defined?(name.camelize)
188
- raise_class_collision(class_name)
189
- end
180
+ end
181
+ # If the last Module exists, check whether the given
182
+ # class exists and raise a collision if so.
183
+
184
+ if last_class and last_class.const_defined?(name.camelize)
185
+ raise_class_collision(current_class)
190
186
  end
191
187
  end
192
188
 
@@ -197,7 +193,7 @@ HELP
197
193
  # file 'config/empty.log', 'log/test.log', :chmod => 0664
198
194
  # :shebang sets the #!/usr/bin/ruby line for scripts
199
195
  # file 'bin/generate.rb', 'script/generate', :chmod => 0755, :shebang => '/usr/bin/env ruby'
200
- # :collision sets the collision option only for the destination file:
196
+ # :collision sets the collision option only for the destination file:
201
197
  # file 'settings/server.yml', 'config/server.yml', :collision => :skip
202
198
  #
203
199
  # Collisions are handled by checking whether the destination file
@@ -211,7 +207,7 @@ HELP
211
207
 
212
208
  # If source and destination are identical then we're done.
213
209
  if destination_exists and identical?(source, destination, &block)
214
- return logger.identical(relative_destination)
210
+ return logger.identical(relative_destination)
215
211
  end
216
212
 
217
213
  # Check for and resolve file collisions.
@@ -255,8 +251,9 @@ HELP
255
251
  FileUtils.chmod(file_options[:chmod], destination)
256
252
  end
257
253
 
258
- # Optionally add file to subversion
254
+ # Optionally add file to subversion or git
259
255
  system("svn add #{destination}") if options[:svn]
256
+ system("git add -v #{relative_destination}") if options[:git]
260
257
  end
261
258
 
262
259
  # Checks if the source and the destination file are identical. If
@@ -303,30 +300,32 @@ HELP
303
300
  end
304
301
 
305
302
  # Create a directory including any missing parent directories.
306
- # Always directories which exist.
303
+ # Always skips directories which exist.
307
304
  def directory(relative_path)
308
305
  path = destination_path(relative_path)
309
306
  if File.exist?(path)
310
307
  logger.exists relative_path
311
308
  else
312
309
  logger.create relative_path
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
310
+ unless options[:pretend]
311
+ FileUtils.mkdir_p(path)
312
+ # git doesn't require adding the paths, adding the files later will
313
+ # automatically do a path add.
314
+
315
+ # Subversion doesn't do path adds, so we need to add
316
+ # each directory individually.
317
+ # So stack up the directory tree and add the paths to
318
+ # subversion in order without recursion.
319
+ if options[:svn]
320
+ stack = [relative_path]
321
+ until File.dirname(stack.last) == stack.last # dirname('.') == '.'
322
+ stack.push File.dirname(stack.last)
323
+ end
324
+ stack.reverse_each do |rel_path|
325
+ svn_path = destination_path(rel_path)
326
+ system("svn add -N #{svn_path}") unless File.directory?(File.join(svn_path, '.svn'))
327
+ end
328
+ end
330
329
  end
331
330
  end
332
331
  end
@@ -381,12 +380,14 @@ HELP
381
380
  # Thanks to Florian Gross (flgr).
382
381
  def raise_class_collision(class_name)
383
382
  message = <<end_message
384
- The name '#{class_name}' is reserved by Ruby on Rails.
383
+ The name '#{class_name}' is either already used in your application or reserved by Ruby on Rails.
385
384
  Please choose an alternative and run this generator again.
386
385
  end_message
387
386
  if suggest = find_synonyms(class_name)
388
- message << "\n Suggestions: \n\n"
389
- message << suggest.join("\n")
387
+ if suggest.any?
388
+ message << "\n Suggestions: \n\n"
389
+ message << suggest.join("\n")
390
+ end
390
391
  end
391
392
  raise UsageError, message
392
393
  end
@@ -428,7 +429,20 @@ end_message
428
429
  # If the directory is not in the status list, it
429
430
  # has no modifications so we can simply remove it
430
431
  system("svn rm #{destination}")
431
- end
432
+ end
433
+ elsif options[:git]
434
+ if options[:git][:new][relative_destination]
435
+ # file has been added, but not committed
436
+ system("git reset HEAD #{relative_destination}")
437
+ FileUtils.rm(destination)
438
+ elsif options[:git][:modified][relative_destination]
439
+ # file is committed and modified
440
+ system("git rm -f #{relative_destination}")
441
+ else
442
+ # If the directory is not in the status list, it
443
+ # has no modifications so we can simply remove it
444
+ system("git rm #{relative_destination}")
445
+ end
432
446
  else
433
447
  FileUtils.rm(destination)
434
448
  end
@@ -465,6 +479,8 @@ end_message
465
479
  # has no modifications so we can simply remove it
466
480
  system("svn rm #{path}")
467
481
  end
482
+ # I don't think git needs to remove directories?..
483
+ # or maybe they have special consideration...
468
484
  else
469
485
  FileUtils.rmdir(path)
470
486
  end
@@ -537,7 +553,7 @@ end_message
537
553
  def readme(*args)
538
554
  logger.readme args.join(', ')
539
555
  end
540
-
556
+
541
557
  def migration_template(relative_source, relative_destination, options = {})
542
558
  migration_directory relative_destination
543
559
  logger.migration_template file_name
@@ -52,17 +52,17 @@ class AppGenerator < Rails::Generator::Base
52
52
  m.template "helpers/application_helper.rb", "app/helpers/application_helper.rb"
53
53
  m.template "helpers/test_helper.rb", "test/test_helper.rb"
54
54
 
55
- # database.yml and .htaccess
55
+ # database.yml and routes.rb
56
56
  m.template "configs/databases/#{options[:db]}.yml", "config/database.yml", :assigns => {
57
57
  :app_name => @app_name,
58
58
  :socket => options[:db] == "mysql" ? mysql_socket_location : nil
59
59
  }
60
- m.template "configs/routes.rb", "config/routes.rb"
61
- m.template "configs/apache.conf", "public/.htaccess"
60
+ m.template "configs/routes.rb", "config/routes.rb"
62
61
 
63
62
  # Initializers
64
63
  m.template "configs/initializers/inflections.rb", "config/initializers/inflections.rb"
65
- m.template "configs/initializers/mime_types.rb", "config/initializers/mime_types.rb"
64
+ m.template "configs/initializers/mime_types.rb", "config/initializers/mime_types.rb"
65
+ m.template "configs/initializers/new_rails_defaults.rb", "config/initializers/new_rails_defaults.rb"
66
66
 
67
67
  # Environments
68
68
  m.file "environments/boot.rb", "config/boot.rb"
@@ -72,7 +72,7 @@ class AppGenerator < Rails::Generator::Base
72
72
  m.file "environments/test.rb", "config/environments/test.rb"
73
73
 
74
74
  # Scripts
75
- %w( about console destroy generate performance/benchmarker performance/profiler performance/request process/reaper process/spawner process/inspector runner server plugin ).each do |file|
75
+ %w( about console dbconsole destroy generate performance/benchmarker performance/profiler performance/request process/reaper process/spawner process/inspector runner server plugin ).each do |file|
76
76
  m.file "bin/#{file}", "script/#{file}", script_options
77
77
  end
78
78
 
@@ -155,8 +155,6 @@ class AppGenerator < Rails::Generator::Base
155
155
  test/fixtures
156
156
  test/functional
157
157
  test/integration
158
- test/mocks/development
159
- test/mocks/test
160
158
  test/unit
161
159
  vendor
162
160
  vendor/plugins