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,21 @@
1
+ require 'rubygems'
2
+ require 'rubygems/installer'
3
+
4
+ module Rails
5
+
6
+ # this class hijacks the functionality of Gem::Installer by overloading its
7
+ # initializer to only provide the information needed by
8
+ # Gem::Installer#build_extensions (which happens to be what we have)
9
+ class GemBuilder < Gem::Installer
10
+
11
+ def initialize(spec, gem_dir)
12
+ @spec = spec
13
+ @gem_dir = gem_dir
14
+ end
15
+
16
+ # silence the underlying builder
17
+ def say(message)
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,124 @@
1
+ module Rails
2
+ class GemDependency
3
+ attr_accessor :name, :requirement, :version, :lib, :source
4
+
5
+ def self.unpacked_path
6
+ @unpacked_path ||= File.join(RAILS_ROOT, 'vendor', 'gems')
7
+ end
8
+
9
+ def initialize(name, options = {})
10
+ require 'rubygems' unless Object.const_defined?(:Gem)
11
+
12
+ if options[:requirement]
13
+ @requirement = options[:requirement]
14
+ elsif options[:version]
15
+ @requirement = Gem::Requirement.create(options[:version])
16
+ end
17
+
18
+ @version = @requirement.instance_variable_get("@requirements").first.last if @requirement
19
+ @name = name.to_s
20
+ @lib = options[:lib]
21
+ @source = options[:source]
22
+ @loaded = @frozen = @load_paths_added = false
23
+ @unpack_directory = nil
24
+ end
25
+
26
+ def add_load_paths
27
+ return if @loaded || @load_paths_added
28
+ unpacked_paths = Dir[File.join(self.class.unpacked_path, "#{@name}-#{@version || "*"}")]
29
+ if unpacked_paths.empty?
30
+ args = [@name]
31
+ args << @requirement.to_s if @requirement
32
+ gem *args
33
+ else
34
+ $LOAD_PATH.unshift File.join(unpacked_paths.first, 'lib')
35
+ ext = File.join(unpacked_paths.first, 'ext')
36
+ $LOAD_PATH.unshift(ext) if File.exist?(ext)
37
+ @frozen = true
38
+ end
39
+ @load_paths_added = true
40
+ rescue Gem::LoadError
41
+ end
42
+
43
+ def dependencies
44
+ all_dependencies = specification.dependencies.map do |dependency|
45
+ GemDependency.new(dependency.name, :requirement => dependency.version_requirements)
46
+ end
47
+ all_dependencies += all_dependencies.map(&:dependencies).flatten
48
+ all_dependencies.uniq
49
+ end
50
+
51
+ def gem_dir(base_directory)
52
+ File.join(base_directory, specification.full_name)
53
+ end
54
+
55
+ def load
56
+ return if @loaded || @load_paths_added == false
57
+ require(@lib || @name)
58
+ @loaded = true
59
+ rescue LoadError
60
+ puts $!.to_s
61
+ $!.backtrace.each { |b| puts b }
62
+ end
63
+
64
+ def frozen?
65
+ @frozen
66
+ end
67
+
68
+ def loaded?
69
+ @loaded
70
+ end
71
+
72
+ def load_paths_added?
73
+ @load_paths_added
74
+ end
75
+
76
+ def install
77
+ cmd = "#{gem_command} #{install_command.join(' ')}"
78
+ puts cmd
79
+ puts %x(#{cmd})
80
+ end
81
+
82
+ def unpack_to(directory)
83
+ FileUtils.mkdir_p directory
84
+ Dir.chdir directory do
85
+ Gem::GemRunner.new.run(unpack_command)
86
+ end
87
+
88
+ # copy the gem's specification into GEMDIR/.specification so that
89
+ # we can access information about the gem on deployment systems
90
+ # without having the gem installed
91
+ spec_filename = File.join(gem_dir(directory), '.specification')
92
+ File.open(spec_filename, 'w') do |file|
93
+ file.puts specification.to_yaml
94
+ end
95
+ end
96
+
97
+ def ==(other)
98
+ self.name == other.name && self.requirement == other.requirement
99
+ end
100
+
101
+ private ###################################################################
102
+
103
+ def specification
104
+ @spec ||= Gem.source_index.search(Gem::Dependency.new(@name, @requirement)).sort_by { |s| s.version }.last
105
+ end
106
+
107
+ def gem_command
108
+ RUBY_PLATFORM =~ /win32/ ? 'gem.bat' : 'gem'
109
+ end
110
+
111
+ def install_command
112
+ cmd = %w(install) << @name
113
+ cmd << "--version" << %("#{@requirement.to_s}") if @requirement
114
+ cmd << "--source" << @source if @source
115
+ cmd
116
+ end
117
+
118
+ def unpack_command
119
+ cmd = %w(unpack) << @name
120
+ cmd << "--version" << "#{@requirement.to_s}" if @requirement
121
+ cmd
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,342 @@
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 'optparse'
8
+ require 'yaml'
9
+ require 'etc'
10
+
11
+ require 'mongrel'
12
+ require 'rails/mongrel_server/handler'
13
+
14
+ module Rails
15
+ module MongrelServer
16
+ def self.send_signal(signal, pid_file)
17
+ pid = open(pid_file).read.to_i
18
+ print "Sending #{signal} to Mongrel at PID #{pid}..."
19
+ begin
20
+ Process.kill(signal, pid)
21
+ rescue Errno::ESRCH
22
+ puts "Process does not exist. Not running."
23
+ end
24
+
25
+ puts "Done."
26
+ end
27
+
28
+ class RailsConfigurator < Mongrel::Configurator
29
+ def setup_mime_types
30
+ mime = {}
31
+
32
+ if defaults[:mime_map]
33
+ Mongrel.log("Loading additional MIME types from #{defaults[:mime_map]}")
34
+ mime = load_mime_map(defaults[:mime_map], mime)
35
+ end
36
+
37
+ mime.each {|k,v| Mongrel::DirHandler::add_mime_type(k,v) }
38
+ end
39
+
40
+ def mount_rails(prefix)
41
+ ENV['RAILS_ENV'] = defaults[:environment]
42
+ ::RAILS_ENV.replace(defaults[:environment]) if defined?(::RAILS_ENV)
43
+
44
+ env_location = "#{defaults[:cwd]}/config/environment"
45
+ require env_location
46
+
47
+ ActionController::AbstractRequest.relative_url_root = defaults[:prefix]
48
+ uri prefix, :handler => Rails::MongrelServer::RailsHandler.new
49
+ end
50
+ end
51
+
52
+ class Start < GemPlugin::Plugin "/commands"
53
+ include Mongrel::Command::Base
54
+
55
+ def configure
56
+ options [
57
+ ["-e", "--environment ENV", "Rails environment to run as", :@environment, ENV['RAILS_ENV'] || "development"],
58
+ ["-d", "--daemonize", "Run daemonized in the background", :@daemon, false],
59
+ ['-p', '--port PORT', "Which port to bind to", :@port, 3000],
60
+ ['-a', '--address ADDR', "Address to bind to", :@address, "0.0.0.0"],
61
+ ['-l', '--log FILE', "Where to write log messages", :@log_file, "log/mongrel.log"],
62
+ ['-P', '--pid FILE', "Where to write the PID", :@pid_file, "tmp/pids/mongrel.pid"],
63
+ ['-n', '--num-procs INT', "Number of processors active before clients denied", :@num_procs, 1024],
64
+ ['-o', '--timeout TIME', "Time to wait (in seconds) before killing a stalled thread", :@timeout, 60],
65
+ ['-t', '--throttle TIME', "Time to pause (in hundredths of a second) between accepting clients", :@throttle, 0],
66
+ ['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil],
67
+ ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, RAILS_ROOT],
68
+ ['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
69
+ ['-B', '--debug', "Enable debugging mode", :@debug, false],
70
+ ['-C', '--config PATH', "Use a config file", :@config_file, nil],
71
+ ['-S', '--script PATH', "Load the given file as an extra config script", :@config_script, nil],
72
+ ['-G', '--generate PATH', "Generate a config file for use with -C", :@generate, nil],
73
+ ['', '--user USER', "User to run as", :@user, nil],
74
+ ['', '--group GROUP', "Group to run as", :@group, nil],
75
+ ['', '--prefix PATH', "URL prefix for Rails app", :@prefix, nil],
76
+
77
+ ['-b', '--binding ADDR', "Address to bind to (deprecated, use -a)", :@address, "0.0.0.0"],
78
+ ['-u', '--debugger', "Enable debugging mode (deprecated, use -B)", :@debug, false]
79
+ ]
80
+ end
81
+
82
+ def validate
83
+ if @config_file
84
+ valid_exists?(@config_file, "Config file not there: #@config_file")
85
+ return false unless @valid
86
+ @config_file = File.expand_path(@config_file)
87
+ load_config
88
+ return false unless @valid
89
+ end
90
+
91
+ @cwd = File.expand_path(@cwd)
92
+ valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
93
+
94
+ # Change there to start, then we'll have to come back after daemonize
95
+ Dir.chdir(@cwd)
96
+
97
+ valid?(@prefix[0] == ?/ && @prefix[-1] != ?/, "Prefix must begin with / and not end in /") if @prefix
98
+ valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file"
99
+ valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file"
100
+ valid_dir? @docroot, "Path to docroot not valid: #@docroot"
101
+ valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
102
+ valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
103
+ valid_dir? File.dirname(@generate), "Problem accessing directory to #@generate" if @generate
104
+ valid_user? @user if @user
105
+ valid_group? @group if @group
106
+
107
+ return @valid
108
+ end
109
+
110
+ def run
111
+ if @generate
112
+ @generate = File.expand_path(@generate)
113
+ Mongrel.log(:error, "** Writing config to \"#@generate\".")
114
+ open(@generate, "w") {|f| f.write(settings.to_yaml) }
115
+ Mongrel.log(:error, "** Finished. Run \"mongrel_rails start -C #@generate\" to use the config file.")
116
+ exit 0
117
+ end
118
+
119
+ config = RailsConfigurator.new(settings) do
120
+ defaults[:log] = $stdout if defaults[:environment] == 'development'
121
+
122
+ Mongrel.log("=> Rails #{Rails.version} application starting on http://#{defaults[:host]}:#{defaults[:port]}")
123
+
124
+ unless defaults[:daemon]
125
+ Mongrel.log("=> Call with -d to detach")
126
+ Mongrel.log("=> Ctrl-C to shutdown server")
127
+ start_debugger if defaults[:debug]
128
+ end
129
+
130
+ if defaults[:daemon]
131
+ if File.exist? defaults[:pid_file]
132
+ Mongrel.log(:error, "!!! PID file #{defaults[:pid_file]} already exists. Mongrel could be running already. Check your #{defaults[:log_file]} for errors.")
133
+ Mongrel.log(:error, "!!! Exiting with error. You must stop mongrel and clear the .pid before I'll attempt a start.")
134
+ exit 1
135
+ end
136
+
137
+ daemonize
138
+
139
+ Mongrel.log("Daemonized, any open files are closed. Look at #{defaults[:pid_file]} and #{defaults[:log_file]} for info.")
140
+ Mongrel.log("Settings loaded from #{@config_file} (they override command line).") if @config_file
141
+ end
142
+
143
+ Mongrel.log("Starting Mongrel listening at #{defaults[:host]}:#{defaults[:port]}, further information can be found in log/mongrel-#{defaults[:host]}-#{defaults[:port]}.log")
144
+
145
+ listener do
146
+ prefix = defaults[:prefix] || '/'
147
+
148
+ if defaults[:debug]
149
+ Mongrel.log("Installing debugging prefixed filters. Look in log/mongrel_debug for the files.")
150
+ debug(prefix)
151
+ end
152
+
153
+ setup_mime_types
154
+ dir_handler = Mongrel::DirHandler.new(defaults[:docroot], false)
155
+ dir_handler.passthrough_missing_files = true
156
+
157
+ unless defaults[:environment] == 'production'
158
+ Mongrel.log("Mounting DirHandler at #{prefix}...")
159
+ uri prefix, :handler => dir_handler
160
+ end
161
+
162
+
163
+ Mongrel.log("Starting Rails with #{defaults[:environment]} environment...")
164
+ Mongrel.log("Mounting Rails at #{prefix}...")
165
+ mount_rails(prefix)
166
+ Mongrel.log("Rails loaded.")
167
+
168
+
169
+ Mongrel.log("Loading any Rails specific GemPlugins" )
170
+ load_plugins
171
+
172
+ if defaults[:config_script]
173
+ Mongrel.log("Loading #{defaults[:config_script]} external config script")
174
+ run_config(defaults[:config_script])
175
+ end
176
+
177
+ setup_signals
178
+ end
179
+ end
180
+
181
+ config.run
182
+ Mongrel.log("Mongrel #{Mongrel::Const::MONGREL_VERSION} available at #{@address}:#{@port}")
183
+
184
+ if config.defaults[:daemon]
185
+ config.write_pid_file
186
+ else
187
+ Mongrel.log("Use CTRL-C to stop.")
188
+ tail "log/#{config.defaults[:environment]}.log"
189
+ end
190
+
191
+ config.join
192
+
193
+ if config.needs_restart
194
+ unless RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw/
195
+ cmd = "ruby #{__FILE__} start #{original_args.join(' ')}"
196
+ Mongrel.log("Restarting with arguments: #{cmd}")
197
+ config.stop(false, true)
198
+ config.remove_pid_file
199
+
200
+ if config.defaults[:daemon]
201
+ system cmd
202
+ else
203
+ Mongrel.log(:error, "Can't restart unless in daemon mode.")
204
+ exit 1
205
+ end
206
+ else
207
+ Mongrel.log("Win32 does not support restarts. Exiting.")
208
+ end
209
+ end
210
+ end
211
+
212
+ def load_config
213
+ settings = {}
214
+ begin
215
+ settings = YAML.load_file(@config_file)
216
+ ensure
217
+ Mongrel.log(:error, "** Loading settings from #{@config_file} (they override command line).") unless @daemon || settings[:daemon]
218
+ end
219
+
220
+ settings[:includes] ||= ["mongrel"]
221
+
222
+ # Config file settings will override command line settings
223
+ settings.each do |key, value|
224
+ key = key.to_s
225
+ if config_keys.include?(key)
226
+ key = 'address' if key == 'host'
227
+ self.instance_variable_set("@#{key}", value)
228
+ else
229
+ failure "Unknown configuration setting: #{key}"
230
+ @valid = false
231
+ end
232
+ end
233
+ end
234
+
235
+ def config_keys
236
+ @config_keys ||=
237
+ %w(address host port cwd log_file pid_file environment docroot mime_map daemon debug includes config_script num_processors timeout throttle user group prefix)
238
+ end
239
+
240
+ def settings
241
+ config_keys.inject({}) do |hash, key|
242
+ value = self.instance_variable_get("@#{key}")
243
+ key = 'host' if key == 'address'
244
+ hash[key.to_sym] ||= value
245
+ hash
246
+ end
247
+ end
248
+
249
+ def start_debugger
250
+ require_library_or_gem 'ruby-debug'
251
+ Debugger.start
252
+ Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
253
+ Mongrel.log("=> Debugger enabled")
254
+ rescue Exception
255
+ Mongrel.log(:error, "You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'")
256
+ exit
257
+ end
258
+
259
+ def tail(log_file)
260
+ cursor = File.size(log_file)
261
+ last_checked = Time.now
262
+ tail_thread = Thread.new do
263
+ File.open(log_file, 'r') do |f|
264
+ loop do
265
+ f.seek cursor
266
+ if f.mtime > last_checked
267
+ last_checked = f.mtime
268
+ contents = f.read
269
+ cursor += contents.length
270
+ print contents
271
+ end
272
+ sleep 1
273
+ end
274
+ end
275
+ end
276
+ tail_thread
277
+ end
278
+ end
279
+
280
+ class Stop < GemPlugin::Plugin "/commands"
281
+ include Mongrel::Command::Base
282
+
283
+ def configure
284
+ options [
285
+ ['-c', '--chdir PATH', "Change to dir before starting (will be expanded).", :@cwd, "."],
286
+ ['-f', '--force', "Force the shutdown (kill -9).", :@force, false],
287
+ ['-w', '--wait SECONDS', "Wait SECONDS before forcing shutdown", :@wait, "0"],
288
+ ['-P', '--pid FILE', "Where the PID file is located.", :@pid_file, "log/mongrel.pid"]
289
+ ]
290
+ end
291
+
292
+ def validate
293
+ @cwd = File.expand_path(@cwd)
294
+ valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
295
+
296
+ Dir.chdir @cwd
297
+
298
+ valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
299
+ return @valid
300
+ end
301
+
302
+ def run
303
+ if @force
304
+ @wait.to_i.times do |waiting|
305
+ exit(0) if not File.exist? @pid_file
306
+ sleep 1
307
+ end
308
+
309
+ Mongrel::send_signal("KILL", @pid_file) if File.exist? @pid_file
310
+ else
311
+ Mongrel::send_signal("TERM", @pid_file)
312
+ end
313
+ end
314
+ end
315
+
316
+
317
+ class Restart < GemPlugin::Plugin "/commands"
318
+ include Mongrel::Command::Base
319
+
320
+ def configure
321
+ options [
322
+ ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, '.'],
323
+ ['-P', '--pid FILE', "Where the PID file is located", :@pid_file, "log/mongrel.pid"]
324
+ ]
325
+ end
326
+
327
+ def validate
328
+ @cwd = File.expand_path(@cwd)
329
+ valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
330
+
331
+ Dir.chdir @cwd
332
+
333
+ valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
334
+ return @valid
335
+ end
336
+
337
+ def run
338
+ MongrelServer::send_signal("USR2", @pid_file)
339
+ end
340
+ end
341
+ end
342
+ end