aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib')
-rw-r--r--railties/lib/commands/process/inspector.rb68
-rw-r--r--railties/lib/commands/process/reaper.rb149
-rw-r--r--railties/lib/commands/process/spawner.rb219
-rw-r--r--railties/lib/commands/process/spinner.rb57
-rw-r--r--railties/lib/commands/runner.rb18
-rw-r--r--railties/lib/commands/server.rb122
-rw-r--r--railties/lib/commands/servers/base.rb31
-rw-r--r--railties/lib/commands/servers/lighttpd.rb94
-rw-r--r--railties/lib/commands/servers/mongrel.rb69
-rw-r--r--railties/lib/commands/servers/new_mongrel.rb16
-rw-r--r--railties/lib/commands/servers/thin.rb25
-rw-r--r--railties/lib/commands/servers/webrick.rb66
-rw-r--r--railties/lib/console_app.rb3
-rw-r--r--railties/lib/console_with_helpers.rb25
-rw-r--r--railties/lib/fcgi_handler.rb2
-rw-r--r--railties/lib/initializer.rb112
-rw-r--r--railties/lib/rails/backtrace_cleaner.rb33
-rw-r--r--railties/lib/rails/gem_dependency.rb1
-rw-r--r--railties/lib/rails/mongrel_server/commands.rb342
-rw-r--r--railties/lib/rails/mongrel_server/handler.rb55
-rw-r--r--railties/lib/rails/plugin.rb49
-rw-r--r--railties/lib/rails/plugin/loader.rb42
-rw-r--r--railties/lib/rails/rack.rb1
-rw-r--r--railties/lib/rails/rack/debugger.rb21
-rw-r--r--railties/lib/rails/rack/static.rb2
-rw-r--r--railties/lib/rails/vendor_gem_source_index.rb4
-rw-r--r--railties/lib/rails/version.rb2
-rw-r--r--railties/lib/rails_generator/base.rb3
-rw-r--r--railties/lib/rails_generator/commands.rb1
-rw-r--r--railties/lib/rails_generator/generators/applications/app/app_generator.rb347
-rw-r--r--railties/lib/rails_generator/generators/applications/app/scm/git.rb16
-rw-r--r--railties/lib/rails_generator/generators/applications/app/scm/scm.rb8
-rw-r--r--railties/lib/rails_generator/generators/applications/app/scm/svn.rb7
-rw-r--r--railties/lib/rails_generator/generators/applications/app/template_runner.rb363
-rw-r--r--railties/lib/rails_generator/generators/components/controller/USAGE23
-rw-r--r--railties/lib/rails_generator/generators/components/controller/controller_generator.rb8
-rw-r--r--railties/lib/rails_generator/generators/components/controller/templates/helper_test.rb4
-rw-r--r--railties/lib/rails_generator/generators/components/helper/USAGE24
-rw-r--r--railties/lib/rails_generator/generators/components/helper/helper_generator.rb25
-rw-r--r--railties/lib/rails_generator/generators/components/helper/templates/helper.rb2
-rw-r--r--railties/lib/rails_generator/generators/components/helper/templates/helper_test.rb4
-rw-r--r--railties/lib/rails_generator/generators/components/resource/USAGE4
-rw-r--r--railties/lib/rails_generator/generators/components/resource/resource_generator.rb2
-rw-r--r--railties/lib/rails_generator/generators/components/resource/templates/helper_test.rb4
-rw-r--r--railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb2
-rw-r--r--railties/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb4
-rw-r--r--railties/lib/rails_generator/secret_key_generator.rb2
-rw-r--r--railties/lib/tasks/databases.rake14
-rw-r--r--railties/lib/tasks/framework.rake22
-rw-r--r--railties/lib/tasks/middleware.rake7
-rw-r--r--railties/lib/tasks/misc.rake6
-rw-r--r--railties/lib/tasks/statistics.rake1
-rw-r--r--railties/lib/tasks/testing.rake8
-rw-r--r--railties/lib/test_help.rb23
54 files changed, 1103 insertions, 1459 deletions
diff --git a/railties/lib/commands/process/inspector.rb b/railties/lib/commands/process/inspector.rb
deleted file mode 100644
index 8a6437e715..0000000000
--- a/railties/lib/commands/process/inspector.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-require 'optparse'
-
-if RUBY_PLATFORM =~ /(:?mswin|mingw)/ then abort("Inspector is only for Unix") end
-
-OPTIONS = {
- :pid_path => File.expand_path(RAILS_ROOT + '/tmp/pids'),
- :pattern => "dispatch.*.pid",
- :ps => "ps -o pid,state,user,start,time,pcpu,vsz,majflt,command -p %s"
-}
-
-class Inspector
- def self.inspect(pid_path, pattern)
- new(pid_path, pattern).inspect
- end
-
- def initialize(pid_path, pattern)
- @pid_path, @pattern = pid_path, pattern
- end
-
- def inspect
- header = `#{OPTIONS[:ps] % 1}`.split("\n")[0] + "\n"
- lines = pids.collect { |pid| `#{OPTIONS[:ps] % pid}`.split("\n")[1] }
-
- puts(header + lines.join("\n"))
- end
-
- private
- def pids
- pid_files.collect do |pid_file|
- File.read(pid_file).to_i
- end
- end
-
- def pid_files
- Dir.glob(@pid_path + "/" + @pattern)
- end
-end
-
-
-ARGV.options do |opts|
- opts.banner = "Usage: inspector [options]"
-
- opts.separator ""
-
- opts.on <<-EOF
- Description:
- Displays system information about Rails dispatchers (or other processes that use pid files) through
- the ps command.
-
- Examples:
- inspector # default ps on all tmp/pids/dispatch.*.pid files
- inspector -s 'ps -o user,start,majflt,pcpu,vsz -p %s' # custom ps, %s is where the pid is interleaved
- EOF
-
- opts.on(" Options:")
-
- opts.on("-s", "--ps=command", "default: #{OPTIONS[:ps]}", String) { |v| OPTIONS[:ps] = v }
- opts.on("-p", "--pidpath=path", "default: #{OPTIONS[:pid_path]}", String) { |v| OPTIONS[:pid_path] = v }
- opts.on("-r", "--pattern=pattern", "default: #{OPTIONS[:pattern]}", String) { |v| OPTIONS[:pattern] = v }
-
- opts.separator ""
-
- opts.on("-h", "--help", "Show this help message.") { puts opts; exit }
-
- opts.parse!
-end
-
-Inspector.inspect(OPTIONS[:pid_path], OPTIONS[:pattern])
diff --git a/railties/lib/commands/process/reaper.rb b/railties/lib/commands/process/reaper.rb
deleted file mode 100644
index 95175d41e0..0000000000
--- a/railties/lib/commands/process/reaper.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-require 'optparse'
-require 'net/http'
-require 'uri'
-
-if RUBY_PLATFORM =~ /(:?mswin|mingw)/ then abort("Reaper is only for Unix") end
-
-class Killer
- class << self
- # Searches for all processes matching the given keywords, and then invokes
- # a specific action on each of them. This is useful for (e.g.) reloading a
- # set of processes:
- #
- # Killer.process(:reload, "/tmp/pids", "dispatcher.*.pid")
- def process(action, pid_path, pattern, keyword)
- new(pid_path, pattern, keyword).process(action)
- end
-
- # Forces the (rails) application to reload by sending a +HUP+ signal to the
- # process.
- def reload(pid)
- `kill -s HUP #{pid}`
- end
-
- # Force the (rails) application to restart by sending a +USR2+ signal to the
- # process.
- def restart(pid)
- `kill -s USR2 #{pid}`
- end
-
- # Forces the (rails) application to gracefully terminate by sending a
- # +TERM+ signal to the process.
- def graceful(pid)
- `kill -s TERM #{pid}`
- end
-
- # Forces the (rails) application to terminate immediately by sending a -9
- # signal to the process.
- def kill(pid)
- `kill -9 #{pid}`
- end
-
- # Send a +USR1+ signal to the process.
- def usr1(pid)
- `kill -s USR1 #{pid}`
- end
- end
-
- def initialize(pid_path, pattern, keyword=nil)
- @pid_path, @pattern, @keyword = pid_path, pattern, keyword
- end
-
- def process(action)
- pids = find_processes
-
- if pids.empty?
- warn "Couldn't find any pid file in '#{@pid_path}' matching '#{@pattern}'"
- warn "(also looked for processes matching #{@keyword.inspect})" if @keyword
- else
- pids.each do |pid|
- puts "#{action.capitalize}ing #{pid}"
- self.class.send(action, pid)
- end
-
- delete_pid_files if terminating?(action)
- end
- end
-
- private
- def terminating?(action)
- [ "kill", "graceful" ].include?(action)
- end
-
- def find_processes
- files = pid_files
- if files.empty?
- find_processes_via_grep
- else
- files.collect { |pid_file| File.read(pid_file).to_i }
- end
- end
-
- def find_processes_via_grep
- lines = `ps axww -o 'pid command' | grep #{@keyword}`.split(/\n/).
- reject { |line| line =~ /inq|ps axww|grep|spawn-fcgi|spawner|reaper/ }
- lines.map { |line| line[/^\s*(\d+)/, 1].to_i }
- end
-
- def delete_pid_files
- pid_files.each { |pid_file| File.delete(pid_file) }
- end
-
- def pid_files
- Dir.glob(@pid_path + "/" + @pattern)
- end
-end
-
-
-OPTIONS = {
- :action => "restart",
- :pid_path => File.expand_path(RAILS_ROOT + '/tmp/pids'),
- :pattern => "dispatch.[0-9]*.pid",
- :dispatcher => File.expand_path("#{RAILS_ROOT}/public/dispatch.fcgi")
-}
-
-ARGV.options do |opts|
- opts.banner = "Usage: reaper [options]"
-
- opts.separator ""
-
- opts.on <<-EOF
- Description:
- The reaper is used to restart, reload, gracefully exit, and forcefully exit processes
- running a Rails Dispatcher (or any other process responding to the same signals). This
- is commonly done when a new version of the application is available, so the existing
- processes can be updated to use the latest code.
-
- It uses pid files to work on the processes and by default assume them to be located
- in RAILS_ROOT/tmp/pids.
-
- The reaper actions are:
-
- * restart : Restarts the application by reloading both application and framework code
- * reload : Only reloads the application, but not the framework (like the development environment)
- * graceful: Marks all of the processes for exit after the next request
- * kill : Forcefully exists all processes regardless of whether they're currently serving a request
-
- Restart is the most common and default action.
-
- Examples:
- reaper # restarts the default dispatchers
- reaper -a reload # reload the default dispatchers
- reaper -a kill -r *.pid # kill all processes that keep pids in tmp/pids
- EOF
-
- opts.on(" Options:")
-
- opts.on("-a", "--action=name", "reload|graceful|kill (default: #{OPTIONS[:action]})", String) { |v| OPTIONS[:action] = v }
- opts.on("-p", "--pidpath=path", "default: #{OPTIONS[:pid_path]}", String) { |v| OPTIONS[:pid_path] = v }
- opts.on("-r", "--pattern=pattern", "default: #{OPTIONS[:pattern]}", String) { |v| OPTIONS[:pattern] = v }
- opts.on("-d", "--dispatcher=path", "DEPRECATED. default: #{OPTIONS[:dispatcher]}", String) { |v| OPTIONS[:dispatcher] = v }
-
- opts.separator ""
-
- opts.on("-h", "--help", "Show this help message.") { puts opts; exit }
-
- opts.parse!
-end
-
-Killer.process(OPTIONS[:action], OPTIONS[:pid_path], OPTIONS[:pattern], OPTIONS[:dispatcher])
diff --git a/railties/lib/commands/process/spawner.rb b/railties/lib/commands/process/spawner.rb
deleted file mode 100644
index 8bf47abb75..0000000000
--- a/railties/lib/commands/process/spawner.rb
+++ /dev/null
@@ -1,219 +0,0 @@
-require 'active_support'
-require 'optparse'
-require 'socket'
-require 'fileutils'
-
-def daemonize #:nodoc:
- exit if fork # Parent exits, child continues.
- Process.setsid # Become session leader.
- exit if fork # Zap session leader. See [1].
- Dir.chdir "/" # Release old working directory.
- File.umask 0000 # Ensure sensible umask. Adjust as needed.
- STDIN.reopen "/dev/null" # Free file descriptors and
- STDOUT.reopen "/dev/null", "a" # point them somewhere sensible.
- STDERR.reopen STDOUT # STDOUT/ERR should better go to a logfile.
-end
-
-class Spawner
- def self.record_pid(name = "#{OPTIONS[:process]}.spawner", id = Process.pid)
- FileUtils.mkdir_p(OPTIONS[:pids])
- File.open(File.expand_path(OPTIONS[:pids] + "/#{name}.pid"), "w+") { |f| f.write(id) }
- end
-
- def self.spawn_all
- OPTIONS[:instances].times do |i|
- port = OPTIONS[:port] + i
- print "Checking if something is already running on #{OPTIONS[:address]}:#{port}..."
-
- begin
- srv = TCPServer.new(OPTIONS[:address], port)
- srv.close
- srv = nil
-
- puts "NO"
- puts "Starting dispatcher on port: #{OPTIONS[:address]}:#{port}"
-
- FileUtils.mkdir_p(OPTIONS[:pids])
- spawn(port)
- rescue
- puts "YES"
- end
- end
- end
-end
-
-class FcgiSpawner < Spawner
- def self.spawn(port)
- cmd = "#{OPTIONS[:spawner]} -f #{OPTIONS[:dispatcher]} -p #{port} -P #{OPTIONS[:pids]}/#{OPTIONS[:process]}.#{port}.pid"
- cmd << " -a #{OPTIONS[:address]}" if can_bind_to_custom_address?
- system(cmd)
- end
-
- def self.can_bind_to_custom_address?
- @@can_bind_to_custom_address ||= /^\s-a\s/.match `#{OPTIONS[:spawner]} -h`
- end
-end
-
-class MongrelSpawner < Spawner
- def self.spawn(port)
- cmd =
- "mongrel_rails start -d " +
- "-a #{OPTIONS[:address]} " +
- "-p #{port} " +
- "-P #{OPTIONS[:pids]}/#{OPTIONS[:process]}.#{port}.pid " +
- "-e #{OPTIONS[:environment]} " +
- "-c #{OPTIONS[:rails_root]} " +
- "-l #{OPTIONS[:rails_root]}/log/mongrel.log"
-
- # Add prefix functionality to spawner's call to mongrel_rails
- # Digging through mongrel's project subversion server, the earliest
- # Tag that has prefix implemented in the bin/mongrel_rails file
- # is 0.3.15 which also happens to be the earliest tag listed.
- # References: http://mongrel.rubyforge.org/svn/tags
- if Mongrel::Const::MONGREL_VERSION.to_f >=0.3 && !OPTIONS[:prefix].nil?
- cmd = cmd + " --prefix #{OPTIONS[:prefix]}"
- end
- system(cmd)
- end
-
- def self.can_bind_to_custom_address?
- true
- end
-end
-
-
-begin
- require_library_or_gem 'fcgi'
-rescue Exception
- # FCGI not available
-end
-
-begin
- require_library_or_gem 'mongrel'
-rescue Exception
- # Mongrel not available
-end
-
-server = case ARGV.first
- when "fcgi", "mongrel"
- ARGV.shift
- else
- if defined?(Mongrel)
- "mongrel"
- elsif RUBY_PLATFORM !~ /(:?mswin|mingw)/ && !silence_stderr { `spawn-fcgi -version` }.blank? && defined?(FCGI)
- "fcgi"
- end
-end
-
-case server
- when "fcgi"
- puts "=> Starting FCGI dispatchers"
- spawner_class = FcgiSpawner
- when "mongrel"
- puts "=> Starting mongrel dispatchers"
- spawner_class = MongrelSpawner
- else
- puts "Neither FCGI (spawn-fcgi) nor Mongrel was installed and available!"
- exit(0)
-end
-
-
-
-OPTIONS = {
- :environment => "production",
- :spawner => '/usr/bin/env spawn-fcgi',
- :dispatcher => File.expand_path(RELATIVE_RAILS_ROOT + '/public/dispatch.fcgi'),
- :pids => File.expand_path(RELATIVE_RAILS_ROOT + "/tmp/pids"),
- :rails_root => File.expand_path(RELATIVE_RAILS_ROOT),
- :process => "dispatch",
- :port => 8000,
- :address => '0.0.0.0',
- :instances => 3,
- :repeat => nil,
- :prefix => nil
-}
-
-ARGV.options do |opts|
- opts.banner = "Usage: spawner [platform] [options]"
-
- opts.separator ""
-
- opts.on <<-EOF
- Description:
- The spawner is a wrapper for spawn-fcgi and mongrel that makes it
- easier to start multiple processes running the Rails dispatcher. The
- spawn-fcgi command is included with the lighttpd web server, but can
- be used with both Apache and lighttpd (and any other web server
- supporting externally managed FCGI processes). Mongrel automatically
- ships with with mongrel_rails for starting dispatchers.
-
- The first choice you need to make is whether to spawn the Rails
- dispatchers as FCGI or Mongrel. By default, this spawner will prefer
- Mongrel, so if that's installed, and no platform choice is made,
- Mongrel is used.
-
- Then decide a starting port (default is 8000) and the number of FCGI
- process instances you'd like to run. So if you pick 9100 and 3
- instances, you'll start processes on 9100, 9101, and 9102.
-
- By setting the repeat option, you get a protection loop, which will
- attempt to restart any FCGI processes that might have been exited or
- outright crashed.
-
- You can select bind address for started processes. By default these
- listen on every interface. For single machine installations you would
- probably want to use 127.0.0.1, hiding them form the outside world.
-
- Examples:
- spawner # starts instances on 8000, 8001, and 8002
- # using Mongrel if available.
- spawner fcgi # starts instances on 8000, 8001, and 8002
- # using FCGI.
- spawner mongrel -i 5 # starts instances on 8000, 8001, 8002,
- # 8003, and 8004 using Mongrel.
- spawner -p 9100 -i 10 # starts 10 instances counting from 9100 to
- # 9109 using Mongrel if available.
- spawner -p 9100 -r 5 # starts 3 instances counting from 9100 to
- # 9102 and attempts start them every 5
- # seconds.
- spawner -a 127.0.0.1 # starts 3 instances binding to localhost
- EOF
-
- opts.on(" Options:")
-
- opts.on("-p", "--port=number", Integer, "Starting port number (default: #{OPTIONS[:port]})") { |v| OPTIONS[:port] = v }
-
- if spawner_class.can_bind_to_custom_address?
- opts.on("-a", "--address=ip", String, "Bind to IP address (default: #{OPTIONS[:address]})") { |v| OPTIONS[:address] = v }
- end
-
- opts.on("-p", "--port=number", Integer, "Starting port number (default: #{OPTIONS[:port]})") { |v| OPTIONS[:port] = v }
- opts.on("-i", "--instances=number", Integer, "Number of instances (default: #{OPTIONS[:instances]})") { |v| OPTIONS[:instances] = v }
- opts.on("-r", "--repeat=seconds", Integer, "Repeat spawn attempts every n seconds (default: off)") { |v| OPTIONS[:repeat] = v }
- opts.on("-e", "--environment=name", String, "test|development|production (default: #{OPTIONS[:environment]})") { |v| OPTIONS[:environment] = v }
- opts.on("-P", "--prefix=path", String, "URL prefix for Rails app. [Used only with Mongrel > v0.3.15]: (default: #{OPTIONS[:prefix]})") { |v| OPTIONS[:prefix] = v }
- opts.on("-n", "--process=name", String, "default: #{OPTIONS[:process]}") { |v| OPTIONS[:process] = v }
- opts.on("-s", "--spawner=path", String, "default: #{OPTIONS[:spawner]}") { |v| OPTIONS[:spawner] = v }
- opts.on("-d", "--dispatcher=path", String, "default: #{OPTIONS[:dispatcher]}") { |dispatcher| OPTIONS[:dispatcher] = File.expand_path(dispatcher) }
-
- opts.separator ""
-
- opts.on("-h", "--help", "Show this help message.") { puts opts; exit }
-
- opts.parse!
-end
-
-ENV["RAILS_ENV"] = OPTIONS[:environment]
-
-if OPTIONS[:repeat]
- daemonize
- trap("TERM") { exit }
- spawner_class.record_pid
-
- loop do
- spawner_class.spawn_all
- sleep(OPTIONS[:repeat])
- end
-else
- spawner_class.spawn_all
-end
diff --git a/railties/lib/commands/process/spinner.rb b/railties/lib/commands/process/spinner.rb
deleted file mode 100644
index c0b2f09a94..0000000000
--- a/railties/lib/commands/process/spinner.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-require 'optparse'
-
-def daemonize #:nodoc:
- exit if fork # Parent exits, child continues.
- Process.setsid # Become session leader.
- exit if fork # Zap session leader. See [1].
- Dir.chdir "/" # Release old working directory.
- File.umask 0000 # Ensure sensible umask. Adjust as needed.
- STDIN.reopen "/dev/null" # Free file descriptors and
- STDOUT.reopen "/dev/null", "a" # point them somewhere sensible.
- STDERR.reopen STDOUT # STDOUT/ERR should better go to a logfile.
-end
-
-OPTIONS = {
- :interval => 5.0,
- :command => File.expand_path(RAILS_ROOT + '/script/process/spawner'),
- :daemon => false
-}
-
-ARGV.options do |opts|
- opts.banner = "Usage: spinner [options]"
-
- opts.separator ""
-
- opts.on <<-EOF
- Description:
- The spinner is a protection loop for the spawner, which will attempt to restart any FCGI processes
- that might have been exited or outright crashed. It's a brute-force attempt that'll just try
- to run the spawner every X number of seconds, so it does pose a light load on the server.
-
- Examples:
- spinner # attempts to run the spawner with default settings every second with output on the terminal
- spinner -i 3 -d # only run the spawner every 3 seconds and detach from the terminal to become a daemon
- spinner -c '/path/to/app/script/process/spawner -p 9000 -i 10' -d # using custom spawner
- EOF
-
- opts.on(" Options:")
-
- opts.on("-c", "--command=path", String) { |v| OPTIONS[:command] = v }
- opts.on("-i", "--interval=seconds", Float) { |v| OPTIONS[:interval] = v }
- opts.on("-d", "--daemon") { |v| OPTIONS[:daemon] = v }
-
- opts.separator ""
-
- opts.on("-h", "--help", "Show this help message.") { puts opts; exit }
-
- opts.parse!
-end
-
-daemonize if OPTIONS[:daemon]
-
-trap(OPTIONS[:daemon] ? "TERM" : "INT") { exit }
-
-loop do
- system(OPTIONS[:command])
- sleep(OPTIONS[:interval])
-end \ No newline at end of file
diff --git a/railties/lib/commands/runner.rb b/railties/lib/commands/runner.rb
index 14159c3893..2411c3d270 100644
--- a/railties/lib/commands/runner.rb
+++ b/railties/lib/commands/runner.rb
@@ -38,11 +38,15 @@ RAILS_ENV.replace(options[:environment]) if defined?(RAILS_ENV)
require RAILS_ROOT + '/config/environment'
-if code_or_file.nil?
- $stderr.puts "Run '#{$0} -h' for help."
- exit 1
-elsif File.exist?(code_or_file)
- eval(File.read(code_or_file), nil, code_or_file)
-else
- eval(code_or_file)
+begin
+ if code_or_file.nil?
+ $stderr.puts "Run '#{$0} -h' for help."
+ exit 1
+ elsif File.exist?(code_or_file)
+ eval(File.read(code_or_file), nil, code_or_file)
+ else
+ eval(code_or_file)
+ end
+ensure
+ RAILS_DEFAULT_LOGGER.flush if RAILS_DEFAULT_LOGGER
end
diff --git a/railties/lib/commands/server.rb b/railties/lib/commands/server.rb
index 15f417b5be..7057fcc33f 100644
--- a/railties/lib/commands/server.rb
+++ b/railties/lib/commands/server.rb
@@ -1,49 +1,103 @@
require 'active_support'
+require 'action_controller'
+
require 'fileutils'
+require 'optparse'
+# TODO: Push Thin adapter upstream so we don't need worry about requiring it
begin
- require_library_or_gem 'fcgi'
+ require_library_or_gem 'thin'
rescue Exception
- # FCGI not available
+ # Thin not available
end
-begin
- require_library_or_gem 'mongrel'
-rescue Exception
- # Mongrel not available
+options = {
+ :Port => 3000,
+ :Host => "0.0.0.0",
+ :environment => (ENV['RAILS_ENV'] || "development").dup,
+ :config => RAILS_ROOT + "/config.ru",
+ :detach => false,
+ :debugger => false
+}
+
+ARGV.clone.options do |opts|
+ opts.on("-p", "--port=port", Integer,
+ "Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v }
+ opts.on("-b", "--binding=ip", String,
+ "Binds Rails to the specified ip.", "Default: 0.0.0.0") { |v| options[:Host] = v }
+ opts.on("-c", "--config=file", String,
+ "Use custom rackup configuration file") { |v| options[:config] = v }
+ opts.on("-d", "--daemon", "Make server run as a Daemon.") { options[:detach] = true }
+ opts.on("-u", "--debugger", "Enable ruby-debugging for the server.") { options[:debugger] = true }
+ opts.on("-e", "--environment=name", String,
+ "Specifies the environment to run this server under (test/development/production).",
+ "Default: development") { |v| options[:environment] = v }
+
+ opts.separator ""
+
+ opts.on("-h", "--help", "Show this help message.") { puts opts; exit }
+
+ opts.parse!
end
-begin
- require_library_or_gem 'thin'
-rescue Exception
- # Thin not available
+server = Rack::Handler.get(ARGV.first) rescue nil
+unless server
+ begin
+ server = Rack::Handler::Mongrel
+ rescue LoadError => e
+ server = Rack::Handler::WEBrick
+ end
end
-server = case ARGV.first
- when "lighttpd", "mongrel", "new_mongrel", "webrick", "thin"
- ARGV.shift
- else
- if defined?(Mongrel)
- "mongrel"
- elsif defined?(Thin)
- "thin"
- elsif RUBY_PLATFORM !~ /(:?mswin|mingw)/ && !silence_stderr { `lighttpd -version` }.blank? && defined?(FCGI)
- "lighttpd"
- else
- "webrick"
- end
+puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
+puts "=> Rails #{Rails.version} application starting on http://#{options[:Host]}:#{options[:Port]}"
+
+%w(cache pids sessions sockets).each do |dir_to_make|
+ FileUtils.mkdir_p(File.join(RAILS_ROOT, 'tmp', dir_to_make))
+end
+
+if options[:detach]
+ Process.daemon
+ pid = "#{RAILS_ROOT}/tmp/pids/server.pid"
+ File.open(pid, 'w'){ |f| f.write(Process.pid) }
+ at_exit { File.delete(pid) if File.exist?(pid) }
end
-case server
- when "webrick"
- puts "=> Booting WEBrick..."
- when "lighttpd"
- puts "=> Booting lighttpd (use 'script/server webrick' to force WEBrick)"
- when "mongrel", "new_mongrel"
- puts "=> Booting Mongrel (use 'script/server webrick' to force WEBrick)"
- when "thin"
- puts "=> Booting Thin (use 'script/server webrick' to force WEBrick)"
+ENV["RAILS_ENV"] = options[:environment]
+RAILS_ENV.replace(options[:environment]) if defined?(RAILS_ENV)
+
+if File.exist?(options[:config])
+ config = options[:config]
+ if config =~ /\.ru$/
+ cfgfile = File.read(config)
+ if cfgfile[/^#\\(.*)/]
+ opts.parse!($1.split(/\s+/))
+ end
+ inner_app = eval("Rack::Builder.new {( " + cfgfile + "\n )}.to_app", nil, config)
+ else
+ require config
+ inner_app = Object.const_get(File.basename(config, '.rb').capitalize)
+ end
+else
+ require RAILS_ROOT + "/config/environment"
+ inner_app = ActionController::Dispatcher.new
end
-%w(cache pids sessions sockets).each { |dir_to_make| FileUtils.mkdir_p(File.join(RAILS_ROOT, 'tmp', dir_to_make)) }
-require "commands/servers/#{server}"
+app = Rack::Builder.new {
+ use Rails::Rack::Logger
+ use Rails::Rack::Static
+ use Rails::Rack::Debugger if options[:debugger]
+ run inner_app
+}.to_app
+
+puts "=> Call with -d to detach"
+
+trap(:INT) { exit }
+
+puts "=> Ctrl-C to shutdown server"
+
+begin
+ server.run(app, options.merge(:AccessLog => []))
+ensure
+ puts 'Exiting'
+end
diff --git a/railties/lib/commands/servers/base.rb b/railties/lib/commands/servers/base.rb
deleted file mode 100644
index 23be169a8d..0000000000
--- a/railties/lib/commands/servers/base.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-def tail(log_file)
- cursor = File.size(log_file)
- last_checked = Time.now
- tail_thread = Thread.new do
- File.open(log_file, 'r') do |f|
- loop do
- f.seek cursor
- if f.mtime > last_checked
- last_checked = f.mtime
- contents = f.read
- cursor += contents.length
- print contents
- end
- sleep 1
- end
- end
- end
- tail_thread
-end
-
-def start_debugger
- begin
- require_library_or_gem 'ruby-debug'
- Debugger.start
- Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
- puts "=> Debugger enabled"
- rescue Exception
- puts "You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'"
- exit
- end
-end \ No newline at end of file
diff --git a/railties/lib/commands/servers/lighttpd.rb b/railties/lib/commands/servers/lighttpd.rb
deleted file mode 100644
index c9d13e86f3..0000000000
--- a/railties/lib/commands/servers/lighttpd.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-require 'rbconfig'
-require 'commands/servers/base'
-
-unless RUBY_PLATFORM !~ /mswin/ && !silence_stderr { `lighttpd -version` }.blank?
- puts "PROBLEM: Lighttpd is not available on your system (or not in your path)"
- exit 1
-end
-
-unless defined?(FCGI)
- puts "PROBLEM: Lighttpd requires that the FCGI Ruby bindings are installed on the system"
- exit 1
-end
-
-require 'initializer'
-configuration = Rails::Initializer.run(:initialize_logger).configuration
-default_config_file = config_file = Pathname.new("#{RAILS_ROOT}/config/lighttpd.conf").cleanpath
-
-require 'optparse'
-
-detach = false
-command_line_port = nil
-
-ARGV.options do |opt|
- opt.on("-p", "--port=port", "Changes the server.port number in the config/lighttpd.conf") { |port| command_line_port = port }
- opt.on('-c', "--config=#{config_file}", 'Specify a different lighttpd config file.') { |path| config_file = path }
- opt.on('-h', '--help', 'Show this message.') { puts opt; exit 0 }
- opt.on('-d', '-d', 'Call with -d to detach') { detach = true; puts "=> Configuration in config/lighttpd.conf" }
- opt.parse!
-end
-
-unless File.exist?(config_file)
- if config_file != default_config_file
- puts "=> #{config_file} not found."
- exit 1
- end
-
- require 'fileutils'
-
- source = File.expand_path(File.join(File.dirname(__FILE__),
- "..", "..", "..", "configs", "lighttpd.conf"))
- puts "=> #{config_file} not found, copying from #{source}"
-
- FileUtils.cp(source, config_file)
-end
-
-# open the config/lighttpd.conf file and add the current user defined port setting to it
-if command_line_port
- File.open(config_file, 'r+') do |config|
- lines = config.readlines
-
- lines.each do |line|
- line.gsub!(/^\s*server.port\s*=\s*(\d+)/, "server.port = #{command_line_port}")
- end
-
- config.rewind
- config.print(lines)
- config.truncate(config.pos)
- end
-end
-
-config = IO.read(config_file)
-default_port, default_ip = 3000, '0.0.0.0'
-port = config.scan(/^\s*server.port\s*=\s*(\d+)/).first rescue default_port
-ip = config.scan(/^\s*server.bind\s*=\s*"([^"]+)"/).first rescue default_ip
-puts "=> Rails #{Rails.version} application starting on http://#{ip || default_ip}:#{port || default_port}"
-
-tail_thread = nil
-
-if !detach
- puts "=> Call with -d to detach"
- puts "=> Ctrl-C to shutdown server (see config/lighttpd.conf for options)"
- detach = false
- tail_thread = tail(configuration.log_path)
-end
-
-trap(:INT) { exit }
-
-begin
- `rake tmp:sockets:clear` # Needed if lighttpd crashes or otherwise leaves FCGI sockets around
- `lighttpd #{!detach ? "-D " : ""}-f #{config_file}`
-ensure
- unless detach
- tail_thread.kill if tail_thread
- puts 'Exiting'
-
- # Ensure FCGI processes are reaped
- silence_stream(STDOUT) do
- ARGV.replace ['-a', 'kill']
- require 'commands/process/reaper'
- end
-
- `rake tmp:sockets:clear` # Remove sockets on clean shutdown
- end
-end
diff --git a/railties/lib/commands/servers/mongrel.rb b/railties/lib/commands/servers/mongrel.rb
deleted file mode 100644
index 7bb110f63a..0000000000
--- a/railties/lib/commands/servers/mongrel.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-require 'rbconfig'
-require 'commands/servers/base'
-
-unless defined?(Mongrel)
- puts "PROBLEM: Mongrel is not available on your system (or not in your path)"
- exit 1
-end
-
-require 'optparse'
-
-OPTIONS = {
- :port => 3000,
- :ip => "0.0.0.0",
- :environment => (ENV['RAILS_ENV'] || "development").dup,
- :detach => false,
- :debugger => false
-}
-
-ARGV.clone.options do |opts|
- opts.on("-p", "--port=port", Integer, "Runs Rails on the specified port.", "Default: 3000") { |v| OPTIONS[:port] = v }
- opts.on("-b", "--binding=ip", String, "Binds Rails to the specified ip.", "Default: 0.0.0.0") { |v| OPTIONS[:ip] = v }
- opts.on("-d", "--daemon", "Make server run as a Daemon.") { OPTIONS[:detach] = true }
- opts.on("-u", "--debugger", "Enable ruby-debugging for the server.") { OPTIONS[:debugger] = true }
- opts.on("-e", "--environment=name", String,
- "Specifies the environment to run this server under (test/development/production).",
- "Default: development") { |v| OPTIONS[:environment] = v }
-
- opts.separator ""
-
- opts.on("-h", "--help", "Show this help message.") { puts opts; exit }
-
- opts.parse!
-end
-
-puts "=> Rails #{Rails.version} application starting on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
-
-parameters = [
- "start",
- "-p", OPTIONS[:port].to_s,
- "-a", OPTIONS[:ip].to_s,
- "-e", OPTIONS[:environment],
- "-P", "#{RAILS_ROOT}/tmp/pids/mongrel.pid"
-]
-
-if OPTIONS[:detach]
- `mongrel_rails #{parameters.join(" ")} -d`
-else
- ENV["RAILS_ENV"] = OPTIONS[:environment]
- RAILS_ENV.replace(OPTIONS[:environment]) if defined?(RAILS_ENV)
-
- start_debugger if OPTIONS[:debugger]
-
- puts "=> Call with -d to detach"
- puts "=> Ctrl-C to shutdown server"
-
- log = Pathname.new("#{File.expand_path(RAILS_ROOT)}/log/#{RAILS_ENV}.log").cleanpath
- open(log, (File::WRONLY | File::APPEND | File::CREAT)) unless File.exist? log
- tail_thread = tail(log)
-
- trap(:INT) { exit }
-
- begin
- silence_warnings { ARGV = parameters }
- load("mongrel_rails")
- ensure
- tail_thread.kill if tail_thread
- puts 'Exiting'
- end
-end \ No newline at end of file
diff --git a/railties/lib/commands/servers/new_mongrel.rb b/railties/lib/commands/servers/new_mongrel.rb
deleted file mode 100644
index 174dbf8a37..0000000000
--- a/railties/lib/commands/servers/new_mongrel.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-unless defined?(Mongrel)
- abort "PROBLEM: Mongrel is not available on your system (or not in your path)"
-end
-
-require 'rails/mongrel_server/commands'
-
-GemPlugin::Manager.instance.load "rails::mongrel" => GemPlugin::INCLUDE, "rails" => GemPlugin::EXCLUDE
-
-case ARGV[0] ||= 'start'
-when 'start', 'stop', 'restart'
- ARGV[0] = "rails::mongrelserver::#{ARGV[0]}"
-end
-
-if not Mongrel::Command::Registry.instance.run ARGV
- exit 1
-end
diff --git a/railties/lib/commands/servers/thin.rb b/railties/lib/commands/servers/thin.rb
deleted file mode 100644
index 833469cab1..0000000000
--- a/railties/lib/commands/servers/thin.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require 'rbconfig'
-require 'commands/servers/base'
-require 'thin'
-
-
-options = ARGV.clone
-options.insert(0,'start') unless Thin::Runner.commands.include?(options[0])
-
-thin = Thin::Runner.new(options)
-
-puts "=> Rails #{Rails.version} application starting on http://#{thin.options[:address]}:#{thin.options[:port]}"
-puts "=> Ctrl-C to shutdown server"
-
-log = Pathname.new("#{File.expand_path(RAILS_ROOT)}/log/#{RAILS_ENV}.log").cleanpath
-open(log, (File::WRONLY | File::APPEND | File::CREAT)) unless File.exist? log
-tail_thread = tail(log)
-trap(:INT) { exit }
-
-begin
- thin.run!
-ensure
- tail_thread.kill if tail_thread
- puts 'Exiting'
-end
-
diff --git a/railties/lib/commands/servers/webrick.rb b/railties/lib/commands/servers/webrick.rb
deleted file mode 100644
index 18c8897cc8..0000000000
--- a/railties/lib/commands/servers/webrick.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-require 'webrick'
-require 'optparse'
-require 'commands/servers/base'
-
-OPTIONS = {
- :port => 3000,
- :ip => "0.0.0.0",
- :environment => (ENV['RAILS_ENV'] || "development").dup,
- :server_root => File.expand_path(RAILS_ROOT + "/public/"),
- :server_type => WEBrick::SimpleServer,
- :charset => "UTF-8",
- :mime_types => WEBrick::HTTPUtils::DefaultMimeTypes,
- :debugger => false
-
-}
-
-ARGV.options do |opts|
- script_name = File.basename($0)
- opts.banner = "Usage: ruby #{script_name} [options]"
-
- opts.separator ""
-
- opts.on("-p", "--port=port", Integer,
- "Runs Rails on the specified port.",
- "Default: 3000") { |v| OPTIONS[:port] = v }
- opts.on("-b", "--binding=ip", String,
- "Binds Rails to the specified ip.",
- "Default: 0.0.0.0") { |v| OPTIONS[:ip] = v }
- opts.on("-e", "--environment=name", String,
- "Specifies the environment to run this server under (test/development/production).",
- "Default: development") { |v| OPTIONS[:environment] = v }
- opts.on("-m", "--mime-types=filename", String,
- "Specifies an Apache style mime.types configuration file to be used for mime types",
- "Default: none") { |mime_types_file| OPTIONS[:mime_types] = WEBrick::HTTPUtils::load_mime_types(mime_types_file) }
-
- opts.on("-d", "--daemon",
- "Make Rails run as a Daemon (only works if fork is available -- meaning on *nix)."
- ) { OPTIONS[:server_type] = WEBrick::Daemon }
-
- opts.on("-u", "--debugger", "Enable ruby-debugging for the server.") { OPTIONS[:debugger] = true }
-
- opts.on("-c", "--charset=charset", String,
- "Set default charset for output.",
- "Default: UTF-8") { |v| OPTIONS[:charset] = v }
-
- opts.separator ""
-
- opts.on("-h", "--help",
- "Show this help message.") { puts opts; exit }
-
- opts.parse!
-end
-
-start_debugger if OPTIONS[:debugger]
-
-ENV["RAILS_ENV"] = OPTIONS[:environment]
-RAILS_ENV.replace(OPTIONS[:environment]) if defined?(RAILS_ENV)
-
-require RAILS_ROOT + "/config/environment"
-require 'webrick_server'
-
-OPTIONS['working_directory'] = File.expand_path(RAILS_ROOT)
-
-puts "=> Rails #{Rails.version} application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
-puts "=> Ctrl-C to shutdown server; call with --help for options" if OPTIONS[:server_type] == WEBrick::SimpleServer
-DispatchServlet.dispatch(OPTIONS)
diff --git a/railties/lib/console_app.rb b/railties/lib/console_app.rb
index 88e7962b43..96bf3117c8 100644
--- a/railties/lib/console_app.rb
+++ b/railties/lib/console_app.rb
@@ -1,4 +1,5 @@
-require 'action_controller/integration'
+require 'active_support/test_case'
+require 'action_controller'
# work around the at_exit hook in test/unit, which kills IRB
Test::Unit.run = true if Test::Unit.respond_to?(:run=)
diff --git a/railties/lib/console_with_helpers.rb b/railties/lib/console_with_helpers.rb
index be453a6896..039db667c4 100644
--- a/railties/lib/console_with_helpers.rb
+++ b/railties/lib/console_with_helpers.rb
@@ -1,26 +1,5 @@
-class Module
- def include_all_modules_from(parent_module)
- parent_module.constants.each do |const|
- mod = parent_module.const_get(const)
- if mod.class == Module
- send(:include, mod)
- include_all_modules_from(mod)
- end
- end
- end
-end
-
-def helper(*helper_names)
- returning @helper_proxy ||= Object.new do |helper|
- helper_names.each { |h| helper.extend "#{h}_helper".classify.constantize }
- end
-end
-
-require_dependency 'application'
-
-class << helper
- include_all_modules_from ActionView
+def helper
+ @helper ||= ApplicationController.helpers
end
@controller = ApplicationController.new
-helper :application rescue nil
diff --git a/railties/lib/fcgi_handler.rb b/railties/lib/fcgi_handler.rb
index 1bb55b9275..1256ef2286 100644
--- a/railties/lib/fcgi_handler.rb
+++ b/railties/lib/fcgi_handler.rb
@@ -98,7 +98,7 @@ class RailsFCGIHandler
with_signal_handler 'USR1' do
begin
- Dispatcher.dispatch(cgi)
+ ::Rack::Handler::FastCGI.serve(cgi, Dispatcher.new)
rescue SignalException, SystemExit
raise
rescue Exception => error
diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb
index e3a0e3bad1..4bb1e480b7 100644
--- a/railties/lib/initializer.rb
+++ b/railties/lib/initializer.rb
@@ -39,20 +39,21 @@ module Rails
nil
end
end
+
+ def backtrace_cleaner
+ @@backtrace_cleaner ||= begin
+ # Relies on ActiveSupport, so we have to lazy load to postpone definition until AS has been loaded
+ require 'rails/backtrace_cleaner'
+ Rails::BacktraceCleaner.new
+ end
+ end
def root
- if defined?(RAILS_ROOT)
- RAILS_ROOT
- else
- nil
- end
+ Pathname.new(RAILS_ROOT) if defined?(RAILS_ROOT)
end
def env
- @_env ||= begin
- require 'active_support/string_inquirer'
- ActiveSupport::StringInquirer.new(RAILS_ENV)
- end
+ @_env ||= ActiveSupport::StringInquirer.new(RAILS_ENV)
end
def cache
@@ -131,6 +132,7 @@ module Rails
add_gem_load_paths
require_frameworks
+ preload_frameworks
set_autoload_paths
add_plugin_load_paths
load_environment
@@ -147,7 +149,10 @@ module Rails
initialize_dependency_mechanism
initialize_whiny_nils
initialize_temporary_session_directory
+
initialize_time_zone
+ initialize_i18n
+
initialize_framework_settings
initialize_framework_views
@@ -252,10 +257,23 @@ module Rails
def require_frameworks
configuration.frameworks.each { |framework| require(framework.to_s) }
rescue LoadError => e
- # re-raise because Mongrel would swallow it
+ # Re-raise as RuntimeError because Mongrel would swallow LoadError.
raise e.to_s
end
+ # Preload all frameworks specified by the Configuration#frameworks.
+ # Used by Passenger to ensure everything's loaded before forking and
+ # to avoid autoload race conditions in JRuby.
+ def preload_frameworks
+ if configuration.preload_frameworks
+ configuration.frameworks.each do |framework|
+ # String#classify and #constantize aren't available yet.
+ toplevel = Object.const_get(framework.to_s.gsub(/(?:^|_)(.)/) { $1.upcase })
+ toplevel.load_all!
+ end
+ end
+ end
+
# Add the load paths used by support functions such as the info controller
def add_support_load_paths
end
@@ -350,9 +368,10 @@ Run `rake gems:install` to install the missing gems.
def load_view_paths
if configuration.frameworks.include?(:action_view)
- ActionView::PathSet::Path.eager_load_templates! if configuration.cache_classes
- ActionController::Base.view_paths.load if configuration.frameworks.include?(:action_controller)
- ActionMailer::Base.template_root.load if configuration.frameworks.include?(:action_mailer)
+ if configuration.cache_classes
+ ActionController::Base.view_paths.load if configuration.frameworks.include?(:action_controller)
+ ActionMailer::Base.template_root.load if configuration.frameworks.include?(:action_mailer)
+ end
end
end
@@ -464,8 +483,9 @@ Run `rake gems:install` to install the missing gems.
# loading module used to lazily load controllers (Configuration#controller_paths).
def initialize_routing
return unless configuration.frameworks.include?(:action_controller)
- ActionController::Routing.controller_paths = configuration.controller_paths
- ActionController::Routing::Routes.configuration_file = configuration.routes_configuration_file
+
+ ActionController::Routing.controller_paths += configuration.controller_paths
+ ActionController::Routing::Routes.add_configuration_file(configuration.routes_configuration_file)
ActionController::Routing::Routes.reload
end
@@ -493,10 +513,15 @@ Run `rake gems:install` to install the missing gems.
def initialize_time_zone
if configuration.time_zone
zone_default = Time.__send__(:get_zone, configuration.time_zone)
+
unless zone_default
- raise %{Value assigned to config.time_zone not recognized. Run "rake -D time" for a list of tasks for finding appropriate time zone names.}
+ raise \
+ 'Value assigned to config.time_zone not recognized.' +
+ 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
end
+
Time.zone_default = zone_default
+
if configuration.frameworks.include?(:active_record)
ActiveRecord::Base.time_zone_aware_attributes = true
ActiveRecord::Base.default_timezone = :utc
@@ -504,6 +529,18 @@ Run `rake gems:install` to install the missing gems.
end
end
+ # Set the i18n configuration from config.i18n but special-case for the load_path which should be
+ # appended to what's already set instead of overwritten.
+ def initialize_i18n
+ configuration.i18n.each do |setting, value|
+ if setting == :load_path
+ I18n.load_path += value
+ else
+ I18n.send("#{setting}=", value)
+ end
+ end
+ end
+
# Initializes framework-specific settings for each of the loaded frameworks
# (Configuration#frameworks). The available settings map to the accessors
# on each of the corresponding Base classes.
@@ -532,7 +569,7 @@ Run `rake gems:install` to install the missing gems.
def load_application_initializers
if gems_dependencies_loaded
Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
- load(initializer)
+ load initializer.sub(/^#{Regexp.escape(configuration.root_path)}\//, '')
end
end
end
@@ -582,12 +619,15 @@ Run `rake gems:install` to install the missing gems.
# A stub for setting options on ActiveSupport.
attr_accessor :active_support
+ # Whether to preload all frameworks at startup.
+ attr_accessor :preload_frameworks
+
# Whether or not classes should be cached (set to false if you want
# application classes to be reloaded on each request)
attr_accessor :cache_classes
# The list of paths that should be searched for controllers. (Defaults
- # to <tt>app/controllers</tt> and <tt>components</tt>.)
+ # to <tt>app/controllers</tt>.)
attr_accessor :controller_paths
# The path to the database configuration file to use. (Defaults to
@@ -732,6 +772,9 @@ Run `rake gems:install` to install the missing gems.
# timezone to <tt>:utc</tt>.
attr_accessor :time_zone
+ # Accessor for i18n settings.
+ attr_accessor :i18n
+
# Create a new Configuration instance, initialized with the default
# values.
def initialize
@@ -745,6 +788,7 @@ Run `rake gems:install` to install the missing gems.
self.log_level = default_log_level
self.view_path = default_view_path
self.controller_paths = default_controller_paths
+ self.preload_frameworks = default_preload_frameworks
self.cache_classes = default_cache_classes
self.dependency_loading = default_dependency_loading
self.whiny_nils = default_whiny_nils
@@ -755,6 +799,7 @@ Run `rake gems:install` to install the missing gems.
self.database_configuration_file = default_database_configuration_file
self.routes_configuration_file = default_routes_configuration_file
self.gems = default_gems
+ self.i18n = default_i18n
for framework in default_frameworks
self.send("#{framework}=", Rails::OrderedOptions.new)
@@ -786,6 +831,7 @@ Run `rake gems:install` to install the missing gems.
# multiple database connections. Also disables automatic dependency loading
# after boot
def threadsafe!
+ self.preload_frameworks = true
self.cache_classes = true
self.dependency_loading = false
self.action_controller.allow_concurrency = true
@@ -835,6 +881,11 @@ Run `rake gems:install` to install the missing gems.
end
end
+ def middleware
+ require 'action_controller'
+ ActionController::Dispatcher.middleware
+ end
+
def builtin_directories
# Include builtins only in the development environment.
(environment == 'development') ? Dir["#{RAILTIES_PATH}/builtin/*/"] : []
@@ -842,10 +893,10 @@ Run `rake gems:install` to install the missing gems.
def framework_paths
paths = %w(railties railties/lib activesupport/lib)
- paths << 'actionpack/lib' if frameworks.include? :action_controller or frameworks.include? :action_view
+ paths << 'actionpack/lib' if frameworks.include?(:action_controller) || frameworks.include?(:action_view)
[:active_record, :action_mailer, :active_resource, :action_web_service].each do |framework|
- paths << "#{framework.to_s.gsub('_', '')}/lib" if frameworks.include? framework
+ paths << "#{framework.to_s.gsub('_', '')}/lib" if frameworks.include?(framework)
end
paths.map { |dir| "#{framework_root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
@@ -869,9 +920,6 @@ Run `rake gems:install` to install the missing gems.
# Add the app's controller directory
paths.concat(Dir["#{root_path}/app/controllers/"])
- # Then components subdirectories.
- paths.concat(Dir["#{root_path}/components/[_a-z]*"])
-
# Followed by the standard includes.
paths.concat %w(
app
@@ -879,9 +927,9 @@ Run `rake gems:install` to install the missing gems.
app/controllers
app/helpers
app/services
- components
config
lib
+ vendor
).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
paths.concat builtin_directories
@@ -930,6 +978,10 @@ Run `rake gems:install` to install the missing gems.
true
end
+ def default_preload_frameworks
+ false
+ end
+
def default_cache_classes
true
end
@@ -967,6 +1019,18 @@ Run `rake gems:install` to install the missing gems.
def default_gems
[]
end
+
+ def default_i18n
+ i18n = Rails::OrderedOptions.new
+ i18n.load_path = []
+
+ if File.exist?(File.join(RAILS_ROOT, 'config', 'locales'))
+ i18n.load_path << Dir[File.join(RAILS_ROOT, 'config', 'locales', '*.{rb,yml}')]
+ i18n.load_path.flatten!
+ end
+
+ i18n
+ end
end
end
diff --git a/railties/lib/rails/backtrace_cleaner.rb b/railties/lib/rails/backtrace_cleaner.rb
new file mode 100644
index 0000000000..d8626aaf14
--- /dev/null
+++ b/railties/lib/rails/backtrace_cleaner.rb
@@ -0,0 +1,33 @@
+module Rails
+ class BacktraceCleaner < ActiveSupport::BacktraceCleaner
+ ERB_METHOD_SIG = /:in `_run_erb_.*/
+
+ VENDOR_DIRS = %w( vendor/plugins vendor/gems vendor/rails )
+ SERVER_DIRS = %w( lib/mongrel bin/mongrel lib/rack )
+ RAILS_NOISE = %w( script/server )
+ RUBY_NOISE = %w( rubygems/custom_require benchmark.rb )
+
+ ALL_NOISE = VENDOR_DIRS + SERVER_DIRS + RAILS_NOISE + RUBY_NOISE
+
+ def initialize
+ super
+ add_filter { |line| line.sub(RAILS_ROOT, '') }
+ add_filter { |line| line.sub(ERB_METHOD_SIG, '') }
+ add_filter { |line| line.sub('./', '/') } # for tests
+ add_silencer { |line| ALL_NOISE.any? { |dir| line.include?(dir) } }
+ end
+ end
+
+ # For installing the BacktraceCleaner in the test/unit
+ module BacktraceFilterForTestUnit #:nodoc:
+ def self.included(klass)
+ klass.send :alias_method_chain, :filter_backtrace, :cleaning
+ end
+
+ def filter_backtrace_with_cleaning(backtrace, prefix=nil)
+ backtrace = filter_backtrace_without_cleaning(backtrace, prefix)
+ backtrace = backtrace.first.split("\n") if backtrace.size == 1
+ Rails.backtrace_cleaner.clean(backtrace)
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/gem_dependency.rb b/railties/lib/rails/gem_dependency.rb
index cd280ac023..5a07841be8 100644
--- a/railties/lib/rails/gem_dependency.rb
+++ b/railties/lib/rails/gem_dependency.rb
@@ -74,6 +74,7 @@ module Rails
def dependencies
return [] if framework_gem?
+ return [] if specification.nil?
all_dependencies = specification.dependencies.map do |dependency|
GemDependency.new(dependency.name, :requirement => dependency.version_requirements)
end
diff --git a/railties/lib/rails/mongrel_server/commands.rb b/railties/lib/rails/mongrel_server/commands.rb
deleted file mode 100644
index d29b18712f..0000000000
--- a/railties/lib/rails/mongrel_server/commands.rb
+++ /dev/null
@@ -1,342 +0,0 @@
-# Copyright (c) 2005 Zed A. Shaw
-# You can redistribute it and/or modify it under the same terms as Ruby.
-#
-# Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
-# for more information.
-
-require 'optparse'
-require 'yaml'
-require 'etc'
-
-require 'mongrel'
-require 'rails/mongrel_server/handler'
-
-module Rails
- module MongrelServer
- def self.send_signal(signal, pid_file)
- pid = open(pid_file).read.to_i
- print "Sending #{signal} to Mongrel at PID #{pid}..."
- begin
- Process.kill(signal, pid)
- rescue Errno::ESRCH
- puts "Process does not exist. Not running."
- end
-
- puts "Done."
- end
-
- class RailsConfigurator < Mongrel::Configurator
- def setup_mime_types
- mime = {}
-
- if defaults[:mime_map]
- Mongrel.log("Loading additional MIME types from #{defaults[:mime_map]}")
- mime = load_mime_map(defaults[:mime_map], mime)
- end
-
- mime.each {|k,v| Mongrel::DirHandler::add_mime_type(k,v) }
- end
-
- def mount_rails(prefix)
- ENV['RAILS_ENV'] = defaults[:environment]
- ::RAILS_ENV.replace(defaults[:environment]) if defined?(::RAILS_ENV)
-
- env_location = "#{defaults[:cwd]}/config/environment"
- require env_location
-
- ActionController::Base.relative_url_root = defaults[:prefix]
- uri prefix, :handler => Rails::MongrelServer::RailsHandler.new
- end
- end
-
- class Start < GemPlugin::Plugin "/commands"
- include Mongrel::Command::Base
-
- def configure
- options [
- ["-e", "--environment ENV", "Rails environment to run as", :@environment, ENV['RAILS_ENV'] || "development"],
- ["-d", "--daemonize", "Run daemonized in the background", :@daemon, false],
- ['-p', '--port PORT', "Which port to bind to", :@port, 3000],
- ['-a', '--address ADDR', "Address to bind to", :@address, "0.0.0.0"],
- ['-l', '--log FILE', "Where to write log messages", :@log_file, "log/mongrel.log"],
- ['-P', '--pid FILE', "Where to write the PID", :@pid_file, "tmp/pids/mongrel.pid"],
- ['-n', '--num-procs INT', "Number of processors active before clients denied", :@num_procs, 1024],
- ['-o', '--timeout TIME', "Time to wait (in seconds) before killing a stalled thread", :@timeout, 60],
- ['-t', '--throttle TIME', "Time to pause (in hundredths of a second) between accepting clients", :@throttle, 0],
- ['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil],
- ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, RAILS_ROOT],
- ['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
- ['-B', '--debug', "Enable debugging mode", :@debug, false],
- ['-C', '--config PATH', "Use a config file", :@config_file, nil],
- ['-S', '--script PATH', "Load the given file as an extra config script", :@config_script, nil],
- ['-G', '--generate PATH', "Generate a config file for use with -C", :@generate, nil],
- ['', '--user USER', "User to run as", :@user, nil],
- ['', '--group GROUP', "Group to run as", :@group, nil],
- ['', '--prefix PATH', "URL prefix for Rails app", :@prefix, nil],
-
- ['-b', '--binding ADDR', "Address to bind to (deprecated, use -a)", :@address, "0.0.0.0"],
- ['-u', '--debugger', "Enable debugging mode (deprecated, use -B)", :@debug, false]
- ]
- end
-
- def validate
- if @config_file
- valid_exists?(@config_file, "Config file not there: #@config_file")
- return false unless @valid
- @config_file = File.expand_path(@config_file)
- load_config
- return false unless @valid
- end
-
- @cwd = File.expand_path(@cwd)
- valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
-
- # Change there to start, then we'll have to come back after daemonize
- Dir.chdir(@cwd)
-
- valid?(@prefix[0] == ?/ && @prefix[-1] != ?/, "Prefix must begin with / and not end in /") if @prefix
- valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file"
- valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file"
- valid_dir? @docroot, "Path to docroot not valid: #@docroot"
- valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
- valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
- valid_dir? File.dirname(@generate), "Problem accessing directory to #@generate" if @generate
- valid_user? @user if @user
- valid_group? @group if @group
-
- return @valid
- end
-
- def run
- if @generate
- @generate = File.expand_path(@generate)
- Mongrel.log(:error, "** Writing config to \"#@generate\".")
- open(@generate, "w") {|f| f.write(settings.to_yaml) }
- Mongrel.log(:error, "** Finished. Run \"mongrel_rails start -C #@generate\" to use the config file.")
- exit 0
- end
-
- config = RailsConfigurator.new(settings) do
- defaults[:log] = $stdout if defaults[:environment] == 'development'
-
- Mongrel.log("=> Rails #{Rails.version} application starting on http://#{defaults[:host]}:#{defaults[:port]}")
-
- unless defaults[:daemon]
- Mongrel.log("=> Call with -d to detach")
- Mongrel.log("=> Ctrl-C to shutdown server")
- start_debugger if defaults[:debug]
- end
-
- if defaults[:daemon]
- if File.exist? defaults[:pid_file]
- Mongrel.log(:error, "!!! PID file #{defaults[:pid_file]} already exists. Mongrel could be running already. Check your #{defaults[:log_file]} for errors.")
- Mongrel.log(:error, "!!! Exiting with error. You must stop mongrel and clear the .pid before I'll attempt a start.")
- exit 1
- end
-
- daemonize
-
- Mongrel.log("Daemonized, any open files are closed. Look at #{defaults[:pid_file]} and #{defaults[:log_file]} for info.")
- Mongrel.log("Settings loaded from #{@config_file} (they override command line).") if @config_file
- end
-
- Mongrel.log("Starting Mongrel listening at #{defaults[:host]}:#{defaults[:port]}, further information can be found in log/mongrel-#{defaults[:host]}-#{defaults[:port]}.log")
-
- listener do
- prefix = defaults[:prefix] || '/'
-
- if defaults[:debug]
- Mongrel.log("Installing debugging prefixed filters. Look in log/mongrel_debug for the files.")
- debug(prefix)
- end
-
- setup_mime_types
- dir_handler = Mongrel::DirHandler.new(defaults[:docroot], false)
- dir_handler.passthrough_missing_files = true
-
- unless defaults[:environment] == 'production'
- Mongrel.log("Mounting DirHandler at #{prefix}...")
- uri prefix, :handler => dir_handler
- end
-
-
- Mongrel.log("Starting Rails with #{defaults[:environment]} environment...")
- Mongrel.log("Mounting Rails at #{prefix}...")
- mount_rails(prefix)
- Mongrel.log("Rails loaded.")
-
-
- Mongrel.log("Loading any Rails specific GemPlugins" )
- load_plugins
-
- if defaults[:config_script]
- Mongrel.log("Loading #{defaults[:config_script]} external config script")
- run_config(defaults[:config_script])
- end
-
- setup_signals
- end
- end
-
- config.run
- Mongrel.log("Mongrel #{Mongrel::Const::MONGREL_VERSION} available at #{@address}:#{@port}")
-
- if config.defaults[:daemon]
- config.write_pid_file
- else
- Mongrel.log("Use CTRL-C to stop.")
- tail "log/#{config.defaults[:environment]}.log"
- end
-
- config.join
-
- if config.needs_restart
- unless RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw/
- cmd = "ruby #{__FILE__} start #{original_args.join(' ')}"
- Mongrel.log("Restarting with arguments: #{cmd}")
- config.stop(false, true)
- config.remove_pid_file
-
- if config.defaults[:daemon]
- system cmd
- else
- Mongrel.log(:error, "Can't restart unless in daemon mode.")
- exit 1
- end
- else
- Mongrel.log("Win32 does not support restarts. Exiting.")
- end
- end
- end
-
- def load_config
- settings = {}
- begin
- settings = YAML.load_file(@config_file)
- ensure
- Mongrel.log(:error, "** Loading settings from #{@config_file} (they override command line).") unless @daemon || settings[:daemon]
- end
-
- settings[:includes] ||= ["mongrel"]
-
- # Config file settings will override command line settings
- settings.each do |key, value|
- key = key.to_s
- if config_keys.include?(key)
- key = 'address' if key == 'host'
- self.instance_variable_set("@#{key}", value)
- else
- failure "Unknown configuration setting: #{key}"
- @valid = false
- end
- end
- end
-
- def config_keys
- @config_keys ||=
- %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)
- end
-
- def settings
- config_keys.inject({}) do |hash, key|
- value = self.instance_variable_get("@#{key}")
- key = 'host' if key == 'address'
- hash[key.to_sym] ||= value
- hash
- end
- end
-
- def start_debugger
- require_library_or_gem 'ruby-debug'
- Debugger.start
- Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
- Mongrel.log("=> Debugger enabled")
- rescue Exception
- Mongrel.log(:error, "You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'")
- exit
- end
-
- def tail(log_file)
- cursor = File.size(log_file)
- last_checked = Time.now
- tail_thread = Thread.new do
- File.open(log_file, 'r') do |f|
- loop do
- f.seek cursor
- if f.mtime > last_checked
- last_checked = f.mtime
- contents = f.read
- cursor += contents.length
- print contents
- end
- sleep 1
- end
- end
- end
- tail_thread
- end
- end
-
- class Stop < GemPlugin::Plugin "/commands"
- include Mongrel::Command::Base
-
- def configure
- options [
- ['-c', '--chdir PATH', "Change to dir before starting (will be expanded).", :@cwd, "."],
- ['-f', '--force', "Force the shutdown (kill -9).", :@force, false],
- ['-w', '--wait SECONDS', "Wait SECONDS before forcing shutdown", :@wait, "0"],
- ['-P', '--pid FILE', "Where the PID file is located.", :@pid_file, "log/mongrel.pid"]
- ]
- end
-
- def validate
- @cwd = File.expand_path(@cwd)
- valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
-
- Dir.chdir @cwd
-
- valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
- return @valid
- end
-
- def run
- if @force
- @wait.to_i.times do |waiting|
- exit(0) if not File.exist? @pid_file
- sleep 1
- end
-
- Mongrel::send_signal("KILL", @pid_file) if File.exist? @pid_file
- else
- Mongrel::send_signal("TERM", @pid_file)
- end
- end
- end
-
-
- class Restart < GemPlugin::Plugin "/commands"
- include Mongrel::Command::Base
-
- def configure
- options [
- ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, '.'],
- ['-P', '--pid FILE', "Where the PID file is located", :@pid_file, "log/mongrel.pid"]
- ]
- end
-
- def validate
- @cwd = File.expand_path(@cwd)
- valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
-
- Dir.chdir @cwd
-
- valid_exists? @pid_file, "PID file #@pid_file does not exist. Not running?"
- return @valid
- end
-
- def run
- MongrelServer::send_signal("USR2", @pid_file)
- end
- end
- end
-end
diff --git a/railties/lib/rails/mongrel_server/handler.rb b/railties/lib/rails/mongrel_server/handler.rb
deleted file mode 100644
index a19eca7259..0000000000
--- a/railties/lib/rails/mongrel_server/handler.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (c) 2005 Zed A. Shaw
-# You can redistribute it and/or modify it under the same terms as Ruby.
-#
-# Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
-# for more information.
-
-require 'mongrel'
-require 'cgi'
-require 'action_controller/dispatcher'
-
-
-module Rails
- module MongrelServer
- # Implements a handler that can run Rails and serve files out of the
- # Rails application's public directory. This lets you run your Rails
- # application with Mongrel during development and testing, then use it
- # also in production behind a server that's better at serving the
- # static files.
- #
- # The RailsHandler takes a mime_map parameter which is a simple suffix=mimetype
- # mapping that it should add to the list of valid mime types.
- #
- # It also supports page caching directly and will try to resolve a request
- # in the following order:
- #
- # * If the requested exact PATH_INFO exists as a file then serve it.
- # * If it exists at PATH_INFO+".html" exists then serve that.
- # * Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispatch to have Rails go.
- #
- # This means that if you are using page caching it will actually work with Mongrel
- # and you should see a decent speed boost (but not as fast as if you use a static
- # server like Apache or Litespeed).
- class RailsHandler < Mongrel::HttpHandler
- # Construct a Mongrel::CGIWrapper and dispatch.
- def process(request, response)
- return if response.socket.closed?
-
- cgi = Mongrel::CGIWrapper.new(request, response)
- cgi.handler = self
- # We don't want the output to be really final until we're out of the lock
- cgi.default_really_final = false
-
- ActionController::Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body)
-
- # This finalizes the output using the proper HttpResponse way
- cgi.out("text/html",true) {""}
- rescue Errno::EPIPE
- response.socket.close
- rescue Object => rails_error
- STDERR.puts "#{Time.now.httpdate}: Error dispatching #{rails_error.inspect}"
- STDERR.puts rails_error.backtrace.join("\n")
- end
- end
- end
-end
diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb
index 4d983843af..4901abe808 100644
--- a/railties/lib/rails/plugin.rb
+++ b/railties/lib/rails/plugin.rb
@@ -28,15 +28,19 @@ module Rails
end
def valid?
- File.directory?(directory) && (has_lib_directory? || has_init_file?)
+ File.directory?(directory) && (has_app_directory? || has_lib_directory? || has_init_file?)
end
# Returns a list of paths this plugin wishes to make available in <tt>$LOAD_PATH</tt>.
def load_paths
report_nonexistant_or_empty_plugin! unless valid?
- has_lib_directory? ? [lib_path] : []
+
+ returning [] do |load_paths|
+ load_paths << lib_path if has_lib_directory?
+ load_paths << app_paths if has_app_directory?
+ end.flatten
end
-
+
# Evaluates a plugin's init.rb file.
def load(initializer)
return if loaded?
@@ -56,7 +60,31 @@ module Rails
def about
@about ||= load_about_information
end
+
+ # Engines are plugins with an app/ directory.
+ def engine?
+ has_app_directory?
+ end
+
+ # Returns true if the engine ships with a routing file
+ def routed?
+ File.exist?(routing_file)
+ end
+
+
+ def view_path
+ File.join(directory, 'app', 'views')
+ end
+
+ def controller_path
+ File.join(directory, 'app', 'controllers')
+ end
+
+ def routing_file
+ File.join(directory, 'config', 'routes.rb')
+ end
+
private
def load_about_information
about_yml_path = File.join(@directory, "about.yml")
@@ -68,8 +96,13 @@ module Rails
def report_nonexistant_or_empty_plugin!
raise LoadError, "Can not find the plugin named: #{name}"
- end
-
+ end
+
+
+ def app_paths
+ [ File.join(directory, 'app', 'models'), File.join(directory, 'app', 'helpers'), controller_path ]
+ end
+
def lib_path
File.join(directory, 'lib')
end
@@ -86,6 +119,11 @@ module Rails
File.file?(gem_init_path) ? gem_init_path : classic_init_path
end
+
+ def has_app_directory?
+ File.directory?(File.join(directory, 'app'))
+ end
+
def has_lib_directory?
File.directory?(lib_path)
end
@@ -94,6 +132,7 @@ module Rails
File.file?(init_path)
end
+
def evaluate_init_rb(initializer)
if has_init_file?
silence_warnings do
diff --git a/railties/lib/rails/plugin/loader.rb b/railties/lib/rails/plugin/loader.rb
index 948d497007..be81bdf4fa 100644
--- a/railties/lib/rails/plugin/loader.rb
+++ b/railties/lib/rails/plugin/loader.rb
@@ -22,6 +22,11 @@ module Rails
@plugins ||= all_plugins.select { |plugin| should_load?(plugin) }.sort { |p1, p2| order_plugins(p1, p2) }
end
+ # Returns the plugins that are in engine-form (have an app/ directory)
+ def engines
+ @engines ||= plugins.select(&:engine?)
+ end
+
# Returns all the plugins that could be found by the current locators.
def all_plugins
@all_plugins ||= locate_plugins
@@ -33,6 +38,9 @@ module Rails
plugin.load(initializer)
register_plugin_as_loaded(plugin)
end
+
+ configure_engines
+
ensure_all_registered_plugins_are_loaded!
end
@@ -45,23 +53,49 @@ module Rails
plugins.each do |plugin|
plugin.load_paths.each do |path|
$LOAD_PATH.insert(application_lib_index + 1, path)
- ActiveSupport::Dependencies.load_paths << path
+
+ ActiveSupport::Dependencies.load_paths << path
+
unless Rails.configuration.reload_plugins?
ActiveSupport::Dependencies.load_once_paths << path
end
end
end
+
$LOAD_PATH.uniq!
- end
+ end
+
protected
+ def configure_engines
+ if engines.any?
+ add_engine_routing_configurations
+ add_engine_controller_paths
+ add_engine_view_paths
+ end
+ end
+ def add_engine_routing_configurations
+ engines.select(&:routed?).collect(&:routing_file).each do |routing_file|
+ ActionController::Routing::Routes.add_configuration_file(routing_file)
+ end
+ end
+
+ def add_engine_controller_paths
+ ActionController::Routing.controller_paths += engines.collect(&:controller_path)
+ end
+
+ def add_engine_view_paths
+ # reverse it such that the last engine can overwrite view paths from the first, like with routes
+ ActionController::Base.view_paths += ActionView::PathSet.new(engines.collect(&:view_path).reverse)
+ end
+
# The locate_plugins method uses each class in config.plugin_locators to
# find the set of all plugins available to this Rails application.
def locate_plugins
- configuration.plugin_locators.map { |locator|
+ configuration.plugin_locators.map do |locator|
locator.new(initializer).plugins
- }.flatten
+ end.flatten
# TODO: sorting based on config.plugins
end
diff --git a/railties/lib/rails/rack.rb b/railties/lib/rails/rack.rb
index b4f32c2d95..90535674e9 100644
--- a/railties/lib/rails/rack.rb
+++ b/railties/lib/rails/rack.rb
@@ -1,5 +1,6 @@
module Rails
module Rack
+ autoload :Debugger, "rails/rack/debugger"
autoload :Logger, "rails/rack/logger"
autoload :Static, "rails/rack/static"
end
diff --git a/railties/lib/rails/rack/debugger.rb b/railties/lib/rails/rack/debugger.rb
new file mode 100644
index 0000000000..aa2711c616
--- /dev/null
+++ b/railties/lib/rails/rack/debugger.rb
@@ -0,0 +1,21 @@
+module Rails
+ module Rack
+ class Debugger
+ def initialize(app)
+ @app = app
+
+ require_library_or_gem 'ruby-debug'
+ ::Debugger.start
+ ::Debugger.settings[:autoeval] = true if ::Debugger.respond_to?(:settings)
+ puts "=> Debugger enabled"
+ rescue Exception
+ puts "You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'"
+ exit
+ end
+
+ def call(env)
+ @app.call(env)
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/rack/static.rb b/railties/lib/rails/rack/static.rb
index 45eb0e5921..ef4e2642e2 100644
--- a/railties/lib/rails/rack/static.rb
+++ b/railties/lib/rails/rack/static.rb
@@ -1,3 +1,5 @@
+require 'rack/utils'
+
module Rails
module Rack
class Static
diff --git a/railties/lib/rails/vendor_gem_source_index.rb b/railties/lib/rails/vendor_gem_source_index.rb
index dc821693ac..5b7721f303 100644
--- a/railties/lib/rails/vendor_gem_source_index.rb
+++ b/railties/lib/rails/vendor_gem_source_index.rb
@@ -81,7 +81,7 @@ module Rails
spec.files = files
else
$stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems not in a versioned directory."+
- " Giving up.") unless @silence_spec_warnings
+ " Giving up.") unless @@silence_spec_warnings
next
end
end
@@ -137,4 +137,4 @@ module Rails
end
end
-end \ No newline at end of file
+end
diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb
index a0986a2e05..9bb4b2a96d 100644
--- a/railties/lib/rails/version.rb
+++ b/railties/lib/rails/version.rb
@@ -1,7 +1,7 @@
module Rails
module VERSION #:nodoc:
MAJOR = 2
- MINOR = 2
+ MINOR = 3
TINY = 0
STRING = [MAJOR, MINOR, TINY].join('.')
diff --git a/railties/lib/rails_generator/base.rb b/railties/lib/rails_generator/base.rb
index b5cfe79867..aa7081f8da 100644
--- a/railties/lib/rails_generator/base.rb
+++ b/railties/lib/rails_generator/base.rb
@@ -154,6 +154,9 @@ module Rails
File.join(destination_root, relative_destination)
end
+ def after_generate
+ end
+
protected
# Convenience method for generator subclasses to record a manifest.
def record
diff --git a/railties/lib/rails_generator/commands.rb b/railties/lib/rails_generator/commands.rb
index 6b9a636847..cacb3807d6 100644
--- a/railties/lib/rails_generator/commands.rb
+++ b/railties/lib/rails_generator/commands.rb
@@ -40,6 +40,7 @@ module Rails
# Replay action manifest. RewindBase subclass rewinds manifest.
def invoke!
manifest.replay(self)
+ after_generate
end
def dependency(generator_name, args, runtime_options = {})
diff --git a/railties/lib/rails_generator/generators/applications/app/app_generator.rb b/railties/lib/rails_generator/generators/applications/app/app_generator.rb
index 32c320385d..4a191578cf 100644
--- a/railties/lib/rails_generator/generators/applications/app/app_generator.rb
+++ b/railties/lib/rails_generator/generators/applications/app/app_generator.rb
@@ -1,109 +1,46 @@
require 'rbconfig'
+require File.dirname(__FILE__) + '/template_runner'
require 'digest/md5'
+require 'active_support/secure_random'
class AppGenerator < Rails::Generator::Base
- DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
- Config::CONFIG['ruby_install_name'])
+ DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- DATABASES = %w(mysql oracle postgresql sqlite2 sqlite3 frontbase ibm_db)
+ DATABASES = %w( mysql oracle postgresql sqlite2 sqlite3 frontbase ibm_db )
DEFAULT_DATABASE = 'sqlite3'
- default_options :db => (ENV["RAILS_DEFAULT_DATABASE"] || DEFAULT_DATABASE),
- :shebang => DEFAULT_SHEBANG, :freeze => false
mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.."
+ default_options :db => (ENV["RAILS_DEFAULT_DATABASE"] || DEFAULT_DATABASE),
+ :shebang => DEFAULT_SHEBANG, :with_dispatchers => false, :freeze => false
+
def initialize(runtime_args, runtime_options = {})
super
+
usage if args.empty?
usage("Databases supported for preconfiguration are: #{DATABASES.join(", ")}") if (options[:db] && !DATABASES.include?(options[:db]))
+
@destination_root = args.shift
@app_name = File.basename(File.expand_path(@destination_root))
end
def manifest
- # Use /usr/bin/env if no special shebang was specified
- script_options = { :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang] }
- dispatcher_options = { :chmod => 0755, :shebang => options[:shebang] }
-
- # duplicate CGI::Session#generate_unique_id
- md5 = Digest::MD5.new
- now = Time.now
- md5 << now.to_s
- md5 << String(now.usec)
- md5 << String(rand(0))
- md5 << String($$)
- md5 << @app_name
-
- # Do our best to generate a secure secret key for CookieStore
- secret = ActiveSupport::SecureRandom.hex(64)
-
record do |m|
- # Root directory and all subdirectories.
- m.directory ''
- BASEDIRS.each { |path| m.directory path }
-
- # Root
- m.file "fresh_rakefile", "Rakefile"
- m.file "README", "README"
-
- # Application
- m.template "helpers/application.rb", "app/controllers/application.rb", :assigns => { :app_name => @app_name, :app_secret => md5.hexdigest }
- m.template "helpers/application_helper.rb", "app/helpers/application_helper.rb"
- m.template "helpers/test_helper.rb", "test/test_helper.rb"
- m.template "helpers/performance_test.rb", "test/performance/browsing_test.rb"
-
- # database.yml and routes.rb
- m.template "configs/databases/#{options[:db]}.yml", "config/database.yml", :assigns => {
- :app_name => @app_name,
- :socket => options[:db] == "mysql" ? mysql_socket_location : nil
- }
- m.template "configs/routes.rb", "config/routes.rb"
-
- # Initializers
- m.template "configs/initializers/inflections.rb", "config/initializers/inflections.rb"
- m.template "configs/initializers/mime_types.rb", "config/initializers/mime_types.rb"
- m.template "configs/initializers/new_rails_defaults.rb", "config/initializers/new_rails_defaults.rb"
-
- # Environments
- m.file "environments/boot.rb", "config/boot.rb"
- m.template "environments/environment.rb", "config/environment.rb", :assigns => { :freeze => options[:freeze], :app_name => @app_name, :app_secret => secret }
- m.file "environments/production.rb", "config/environments/production.rb"
- m.file "environments/development.rb", "config/environments/development.rb"
- m.file "environments/test.rb", "config/environments/test.rb"
-
- # Scripts
- %w( about console dbconsole destroy generate performance/benchmarker performance/profiler performance/request process/reaper process/spawner process/inspector runner server plugin ).each do |file|
- m.file "bin/#{file}", "script/#{file}", script_options
- end
-
- # Dispatches
- m.file "dispatches/dispatch.rb", "public/dispatch.rb", dispatcher_options
- m.file "dispatches/dispatch.rb", "public/dispatch.cgi", dispatcher_options
- m.file "dispatches/dispatch.fcgi", "public/dispatch.fcgi", dispatcher_options
-
- # HTML files
- %w(404 422 500 index).each do |file|
- m.template "html/#{file}.html", "public/#{file}.html"
- end
-
- m.template "html/favicon.ico", "public/favicon.ico"
- m.template "html/robots.txt", "public/robots.txt"
- m.file "html/images/rails.png", "public/images/rails.png"
-
- # Javascripts
- m.file "html/javascripts/prototype.js", "public/javascripts/prototype.js"
- m.file "html/javascripts/effects.js", "public/javascripts/effects.js"
- m.file "html/javascripts/dragdrop.js", "public/javascripts/dragdrop.js"
- m.file "html/javascripts/controls.js", "public/javascripts/controls.js"
- m.file "html/javascripts/application.js", "public/javascripts/application.js"
-
- # Docs
- m.file "doc/README_FOR_APP", "doc/README_FOR_APP"
+ create_directories(m)
+ create_root_files(m)
+ create_app_files(m)
+ create_config_files(m)
+ create_script_files(m)
+ create_test_files(m)
+ create_public_files(m)
+ create_documentation_file(m)
+ create_log_files(m)
+ end
+ end
- # Logs
- %w(server production development test).each { |file|
- m.file "configs/empty.log", "log/#{file}.log", :chmod => 0666
- }
+ def after_generate
+ if options[:template]
+ Rails::TemplateRunner.new(@destination_root, options[:template])
end
end
@@ -123,57 +60,199 @@ class AppGenerator < Rails::Generator::Base
"Preconfigure for selected database (options: #{DATABASES.join('/')}).",
"Default: #{DEFAULT_DATABASE}") { |v| options[:db] = v }
+ opt.on("-D", "--with-dispatchers",
+ "Add CGI/FastCGI/mod_ruby dispatches code to generated application skeleton",
+ "Default: false") { |v| options[:with_dispatchers] = v }
+
opt.on("-f", "--freeze",
"Freeze Rails in vendor/rails from the gems generating the skeleton",
"Default: false") { |v| options[:freeze] = v }
+
+ opt.on("-m", "--template=path", String,
+ "Use an application template that lives at path (can be a filesystem path or URL).",
+ "Default: (none)") { |v| options[:template] = v }
+
+ end
+
+
+ private
+ def create_directories(m)
+ m.directory ''
+
+ # Intermediate directories are automatically created so don't sweat their absence here.
+ %w(
+ app/controllers
+ app/helpers
+ app/models
+ app/views/layouts
+ config/environments
+ config/initializers
+ config/locales
+ db
+ doc
+ lib
+ lib/tasks
+ log
+ public/images
+ public/javascripts
+ public/stylesheets
+ script/performance
+ test/fixtures
+ test/functional
+ test/integration
+ test/performance
+ test/unit
+ vendor
+ vendor/plugins
+ tmp/sessions
+ tmp/sockets
+ tmp/cache
+ tmp/pids
+ ).each { |path| m.directory(path) }
+ end
+
+ def create_root_files(m)
+ m.file "fresh_rakefile", "Rakefile"
+ m.file "README", "README"
+ end
+
+ def create_app_files(m)
+ m.file "helpers/application_controller.rb", "app/controllers/application_controller.rb"
+ m.file "helpers/application_helper.rb", "app/helpers/application_helper.rb"
+ end
+
+ def create_config_files(m)
+ create_database_configuration_file(m)
+ create_routes_file(m)
+ create_locale_file(m)
+ create_initializer_files(m)
+ create_environment_files(m)
+ end
+
+ def create_documentation_file(m)
+ m.file "doc/README_FOR_APP", "doc/README_FOR_APP"
end
+ def create_log_files(m)
+ %w( server production development test ).each do |file|
+ m.file "configs/empty.log", "log/#{file}.log", :chmod => 0666
+ end
+ end
+
+ def create_public_files(m)
+ create_dispatch_files(m)
+ create_error_files(m)
+ create_welcome_file(m)
+ create_browser_convention_files(m)
+ create_rails_image(m)
+ create_javascript_files(m)
+ end
+
+ def create_script_files(m)
+ %w(
+ about console dbconsole destroy generate runner server plugin
+ performance/benchmarker performance/profiler performance/request
+ ).each do |file|
+ m.file "bin/#{file}", "script/#{file}", {
+ :chmod => 0755,
+ :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang]
+ }
+ end
+ end
+
+ def create_test_files(m)
+ m.file "helpers/test_helper.rb", "test/test_helper.rb"
+ m.file "helpers/performance_test.rb", "test/performance/browsing_test.rb"
+ end
+
+
+ def create_database_configuration_file(m)
+ m.template "configs/databases/#{options[:db]}.yml", "config/database.yml", :assigns => {
+ :app_name => @app_name,
+ :socket => options[:db] == "mysql" ? mysql_socket_location : nil }
+ end
+
+ def create_routes_file(m)
+ m.file "configs/routes.rb", "config/routes.rb"
+ end
+
+ def create_initializer_files(m)
+ %w(
+ backtrace_silencers
+ inflections
+ mime_types
+ new_rails_defaults
+ ).each do |initializer|
+ m.file "configs/initializers/#{initializer}.rb", "config/initializers/#{initializer}.rb"
+ end
+
+ m.template "configs/initializers/session_store.rb", "config/initializers/session_store.rb",
+ :assigns => { :app_name => @app_name, :app_secret => ActiveSupport::SecureRandom.hex(64) }
+ end
+
+ def create_locale_file(m)
+ m.file "configs/locales/en.yml", "config/locales/en.yml"
+ end
+
+ def create_environment_files(m)
+ m.template "environments/environment.rb", "config/environment.rb",
+ :assigns => { :freeze => options[:freeze] }
+
+ m.file "environments/boot.rb", "config/boot.rb"
+ m.file "environments/production.rb", "config/environments/production.rb"
+ m.file "environments/development.rb", "config/environments/development.rb"
+ m.file "environments/test.rb", "config/environments/test.rb"
+ end
+
+
+ def create_dispatch_files(m)
+ if options[:with_dispatchers]
+ dispatcher_options = { :chmod => 0755, :shebang => options[:shebang] }
+
+ m.file "dispatches/config.ru", "config.ru"
+ m.file "dispatches/dispatch.rb", "public/dispatch.rb", dispatcher_options
+ m.file "dispatches/dispatch.rb", "public/dispatch.cgi", dispatcher_options
+ m.file "dispatches/dispatch.fcgi", "public/dispatch.fcgi", dispatcher_options
+ end
+ end
+
+ def create_error_files(m)
+ %w( 404 422 500 ).each do |file|
+ m.file "html/#{file}.html", "public/#{file}.html"
+ end
+ end
+
+ def create_welcome_file(m)
+ m.file 'html/index.html', 'public/index.html'
+ end
+
+ def create_browser_convention_files(m)
+ m.file "html/favicon.ico", "public/favicon.ico"
+ m.file "html/robots.txt", "public/robots.txt"
+ end
+
+ def create_rails_image(m)
+ m.file "html/images/rails.png", "public/images/rails.png"
+ end
+
+ def create_javascript_files(m)
+ %w( prototype effects dragdrop controls application ).each do |javascript|
+ m.file "html/javascripts/#{javascript}.js", "public/javascripts/#{javascript}.js"
+ end
+ end
+
+
def mysql_socket_location
- MYSQL_SOCKET_LOCATIONS.find { |f| File.exist?(f) } unless RUBY_PLATFORM =~ /(:?mswin|mingw)/
- end
-
-
- # Installation skeleton. Intermediate directories are automatically
- # created so don't sweat their absence here.
- BASEDIRS = %w(
- app/controllers
- app/helpers
- app/models
- app/views/layouts
- config/environments
- config/initializers
- db
- doc
- lib
- lib/tasks
- log
- public/images
- public/javascripts
- public/stylesheets
- script/performance
- script/process
- test/fixtures
- test/functional
- test/integration
- test/performance
- test/unit
- vendor
- vendor/plugins
- tmp/sessions
- tmp/sockets
- tmp/cache
- tmp/pids
- )
-
- MYSQL_SOCKET_LOCATIONS = [
- "/tmp/mysql.sock", # default
- "/var/run/mysqld/mysqld.sock", # debian/gentoo
- "/var/tmp/mysql.sock", # freebsd
- "/var/lib/mysql/mysql.sock", # fedora
- "/opt/local/lib/mysql/mysql.sock", # fedora
- "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
- "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
- "/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
- "/opt/lampp/var/mysql/mysql.sock" # xampp for linux
- ]
-end
+ [
+ "/tmp/mysql.sock", # default
+ "/var/run/mysqld/mysqld.sock", # debian/gentoo
+ "/var/tmp/mysql.sock", # freebsd
+ "/var/lib/mysql/mysql.sock", # fedora
+ "/opt/local/lib/mysql/mysql.sock", # fedora
+ "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
+ "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
+ "/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
+ "/opt/lampp/var/mysql/mysql.sock" # xampp for linux
+ ].find { |f| File.exist?(f) } unless RUBY_PLATFORM =~ /(:?mswin|mingw)/
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/applications/app/scm/git.rb b/railties/lib/rails_generator/generators/applications/app/scm/git.rb
new file mode 100644
index 0000000000..445de6ab42
--- /dev/null
+++ b/railties/lib/rails_generator/generators/applications/app/scm/git.rb
@@ -0,0 +1,16 @@
+module Rails
+ class Git < Scm
+ def self.clone(repos, branch=nil)
+ `git clone #{repos}`
+
+ if branch
+ `cd #{repos.split('/').last}/`
+ `git checkout #{branch}`
+ end
+ end
+
+ def self.run(command)
+ `git #{command}`
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/applications/app/scm/scm.rb b/railties/lib/rails_generator/generators/applications/app/scm/scm.rb
new file mode 100644
index 0000000000..f6c08cad39
--- /dev/null
+++ b/railties/lib/rails_generator/generators/applications/app/scm/scm.rb
@@ -0,0 +1,8 @@
+module Rails
+ class Scm
+ private
+ def self.hash_to_parameters(hash)
+ hash.collect { |key, value| "--#{key} #{(value.kind_of?(String) ? value : "")}"}.join(" ")
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/applications/app/scm/svn.rb b/railties/lib/rails_generator/generators/applications/app/scm/svn.rb
new file mode 100644
index 0000000000..22b5966d25
--- /dev/null
+++ b/railties/lib/rails_generator/generators/applications/app/scm/svn.rb
@@ -0,0 +1,7 @@
+module Rails
+ class Svn < Scm
+ def self.checkout(repos, branch = nil)
+ `svn checkout #{repos}/#{branch || "trunk"}`
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/applications/app/template_runner.rb b/railties/lib/rails_generator/generators/applications/app/template_runner.rb
new file mode 100644
index 0000000000..0083e0d5a5
--- /dev/null
+++ b/railties/lib/rails_generator/generators/applications/app/template_runner.rb
@@ -0,0 +1,363 @@
+require File.dirname(__FILE__) + '/scm/scm'
+require File.dirname(__FILE__) + '/scm/git'
+require File.dirname(__FILE__) + '/scm/svn'
+
+require 'open-uri'
+require 'fileutils'
+
+module Rails
+ class TemplateRunner
+ attr_reader :behavior, :description, :root
+
+ def initialize(root, template) # :nodoc:
+ @root = Dir.pwd + "/" + root
+
+ puts "applying template: #{template}"
+
+ load_template(template)
+
+ puts "#{template} applied."
+ end
+
+ def load_template(template)
+ begin
+ code = open(template).read
+ in_root { self.instance_eval(code) }
+ rescue LoadError
+ raise "The template [#{template}] could not be loaded."
+ end
+ end
+
+ # Create a new file in the Rails project folder. Specify the
+ # relative path from RAILS_ROOT. Data is the return value of a block
+ # or a data string.
+ #
+ # ==== Examples
+ #
+ # file("lib/fun_party.rb") do
+ # hostname = ask("What is the virtual hostname I should use?")
+ # "vhost.name = #{hostname}"
+ # end
+ #
+ # file("config/apach.conf", "your apache config")
+ #
+ def file(filename, data = nil, &block)
+ puts "creating file #{filename}"
+ dir, file = [File.dirname(filename), File.basename(filename)]
+
+ inside(dir) do
+ File.open(file, "w") do |f|
+ if block_given?
+ f.write(block.call)
+ else
+ f.write(data)
+ end
+ end
+ end
+ end
+
+ # Install a plugin. You must provide either a Subversion url or Git url.
+ #
+ # ==== Examples
+ #
+ # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git'
+ # plugin 'restful-authentication', :svn => 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
+ #
+ def plugin(name, options)
+ puts "installing plugin #{name}"
+
+ if options[:git] || options[:svn]
+ in_root do
+ `script/plugin install #{options[:svn] || options[:git]}`
+ end
+ else
+ puts "! no git or svn provided for #{name}. skipping..."
+ end
+ end
+
+ # Adds an entry into config/environment.rb for the supplied gem :
+ def gem(name, options = {})
+ puts "adding gem #{name}"
+
+ sentinel = 'Rails::Initializer.run do |config|'
+ gems_code = "config.gem '#{name}'"
+
+ if options.any?
+ opts = options.inject([]) {|result, h| result << [":#{h[0]} => '#{h[1]}'"] }.join(", ")
+ gems_code << ", #{opts}"
+ end
+
+ in_root do
+ gsub_file 'config/environment.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
+ "#{match}\n #{gems_code}"
+ end
+ end
+ end
+
+ # Run a command in git.
+ #
+ # ==== Examples
+ #
+ # git :init
+ # git :add => "this.file that.rb"
+ # git :add => "onefile.rb", :rm => "badfile.cxx"
+ #
+ def git(command = {})
+ puts "running git #{command}"
+
+ in_root do
+ if command.is_a?(Symbol)
+ Git.run(command.to_s)
+ else
+ command.each do |command, options|
+ Git.run("#{command} #{options}")
+ end
+ end
+ end
+ end
+
+ # Create a new file in the vendor/ directory. Code can be specified
+ # in a block or a data string can be given.
+ #
+ # ==== Examples
+ #
+ # vendor("sekrit.rb") do
+ # sekrit_salt = "#{Time.now}--#{3.years.ago}--#{rand}--"
+ # "salt = '#{sekrit_salt}'"
+ # end
+ #
+ # vendor("foreign.rb", "# Foreign code is fun")
+ #
+ def vendor(filename, data = nil, &block)
+ puts "vendoring file #{filename}"
+ inside("vendor") do |folder|
+ File.open("#{folder}/#{filename}", "w") do |f|
+ if block_given?
+ f.write(block.call)
+ else
+ f.write(data)
+ end
+ end
+ end
+ end
+
+ # Create a new file in the lib/ directory. Code can be specified
+ # in a block or a data string can be given.
+ #
+ # ==== Examples
+ #
+ # lib("crypto.rb") do
+ # "crypted_special_value = '#{rand}--#{Time.now}--#{rand(1337)}--'"
+ # end
+ #
+ # lib("foreign.rb", "# Foreign code is fun")
+ #
+ def lib(filename, data = nil)
+ puts "add lib file #{filename}"
+ inside("lib") do |folder|
+ File.open("#{folder}/#{filename}", "w") do |f|
+ if block_given?
+ f.write(block.call)
+ else
+ f.write(data)
+ end
+ end
+ end
+ end
+
+ # Create a new Rakefile with the provided code (either in a block or a string).
+ #
+ # ==== Examples
+ #
+ # rakefile("bootstrap.rake") do
+ # project = ask("What is the UNIX name of your project?")
+ #
+ # <<-TASK
+ # namespace :#{project} do
+ # task :bootstrap do
+ # puts "i like boots!"
+ # end
+ # end
+ # TASK
+ # end
+ #
+ # rakefile("seed.rake", "puts 'im plantin ur seedz'")
+ #
+ def rakefile(filename, data = nil, &block)
+ puts "adding rakefile #{filename}"
+ inside("lib/tasks") do |folder|
+ File.open("#{folder}/#{filename}", "w") do |f|
+ if block_given?
+ f.write(block.call)
+ else
+ f.write(data)
+ end
+ end
+ end
+ end
+
+ # Create a new initializer with the provided code (either in a block or a string).
+ #
+ # ==== Examples
+ #
+ # initializer("globals.rb") do
+ # data = ""
+ #
+ # ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do
+ # data << "#{const} = :entp"
+ # end
+ #
+ # data
+ # end
+ #
+ # initializer("api.rb", "API_KEY = '123456'")
+ #
+ def initializer(filename, data = nil, &block)
+ puts "adding initializer #{filename}"
+ inside("config/initializers") do |folder|
+ File.open("#{folder}/#{filename}", "w") do |f|
+ if block_given?
+ f.write(block.call)
+ else
+ f.write(data)
+ end
+ end
+ end
+ end
+
+ # Generate something using a generator from Rails or a plugin.
+ # The second parameter is the argument string that is passed to
+ # the generator or an Array that is joined.
+ #
+ # ==== Example
+ #
+ # generate(:authenticated, "user session")
+ #
+ def generate(what, args = nil)
+ puts "generating #{what}"
+ args = args.join(" ") if args.class == Array
+
+ in_root { `#{root}/script/generate #{what} #{args}` }
+ end
+
+ # Executes a command
+ #
+ # ==== Example
+ #
+ # inside('vendor') do
+ # run('ln -s ~/edge rails)
+ # end
+ #
+ def run(command)
+ puts "executing #{command} from #{Dir.pwd}"
+ `#{command}`
+ end
+
+ # Runs the supplied rake task
+ #
+ # ==== Example
+ #
+ # rake("db:migrate")
+ # rake("db:migrate", "production")
+ #
+ def rake(command, env = 'development')
+ puts "running rake task #{command}"
+ in_root { `rake #{command} RAILS_ENV=#{env}` }
+ end
+
+ # Just run the capify command in root
+ #
+ # ==== Example
+ #
+ # capify!
+ #
+ def capify!
+ in_root { `capify .` }
+ end
+
+ # Add Rails to /vendor/rails
+ #
+ # ==== Example
+ #
+ # freeze!
+ #
+ def freeze!(args = {})
+ puts "vendoring rails edge"
+ in_root { `rake rails:freeze:edge` }
+ end
+
+ # Make an entry in Rails routing file conifg/routes.rb
+ #
+ # === Example
+ #
+ # route "map.root :controller => :welcome"
+ #
+ def route(routing_code)
+ sentinel = 'ActionController::Routing::Routes.draw do |map|'
+
+ in_root do
+ gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
+ "#{match}\n #{routing_code}\n"
+ end
+ end
+ end
+
+ protected
+
+ # Get a user's input
+ #
+ # ==== Example
+ #
+ # answer = ask("Should I freeze the latest Rails?")
+ # freeze! if ask("Should I freeze the latest Rails?") == "yes"
+ #
+ def ask(string)
+ puts string
+ gets.strip
+ end
+
+ # Do something in the root of the Rails application or
+ # a provided subfolder; the full path is yielded to the block you provide.
+ # The path is set back to the previous path when the method exits.
+ def inside(dir = '', &block)
+ folder = File.join(root, dir)
+ FileUtils.mkdir_p(folder) unless File.exist?(folder)
+ FileUtils.cd(folder) { block.arity == 1 ? yield(folder) : yield }
+ end
+
+ def in_root
+ FileUtils.cd(root) { yield }
+ end
+
+ # Helper to test if the user says yes(y)?
+ #
+ # ==== Example
+ #
+ # freeze! if yes?("Should I freeze the latest Rails?")
+ #
+ def yes?(question)
+ answer = ask(question).downcase
+ answer == "y" || answer == "yes"
+ end
+
+ # Helper to test if the user does NOT say yes(y)?
+ #
+ # ==== Example
+ #
+ # capify! if no?("Will you be using vlad to deploy your application?")
+ #
+ def no?(question)
+ !yes?(question)
+ end
+
+ def gsub_file(relative_destination, regexp, *args, &block)
+ path = destination_path(relative_destination)
+ content = File.read(path).gsub(regexp, *args, &block)
+ File.open(path, 'wb') { |file| file.write(content) }
+ end
+
+ def destination_path(relative_destination)
+ File.join(root, relative_destination)
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/components/controller/USAGE b/railties/lib/rails_generator/generators/components/controller/USAGE
index d4fae60c81..362872e84a 100644
--- a/railties/lib/rails_generator/generators/components/controller/USAGE
+++ b/railties/lib/rails_generator/generators/components/controller/USAGE
@@ -6,24 +6,25 @@ Description:
path like 'parent_module/controller_name'.
This generates a controller class in app/controllers, view templates in
- app/views/controller_name, a helper class in app/helpers, and a functional
- test suite in test/functional.
+ app/views/controller_name, a helper class in app/helpers, a functional
+ test suite in test/functional and a helper test suite in test/unit/helpers.
Example:
`./script/generate controller CreditCard open debit credit close`
Credit card controller with URLs like /credit_card/debit.
- Controller: app/controllers/credit_card_controller.rb
- Views: app/views/credit_card/debit.html.erb [...]
- Helper: app/helpers/credit_card_helper.rb
- Test: test/functional/credit_card_controller_test.rb
+ Controller: app/controllers/credit_card_controller.rb
+ Functional Test: test/functional/credit_card_controller_test.rb
+ Views: app/views/credit_card/debit.html.erb [...]
+ Helper: app/helpers/credit_card_helper.rb
+ Helper Test: test/unit/helpers/credit_card_helper_test.rb
Modules Example:
`./script/generate controller 'admin/credit_card' suspend late_fee`
Credit card admin controller with URLs /admin/credit_card/suspend.
- Controller: app/controllers/admin/credit_card_controller.rb
- Views: app/views/admin/credit_card/debit.html.erb [...]
- Helper: app/helpers/admin/credit_card_helper.rb
- Test: test/functional/admin/credit_card_controller_test.rb
-
+ Controller: app/controllers/admin/credit_card_controller.rb
+ Functional Test: test/functional/admin/credit_card_controller_test.rb
+ Views: app/views/admin/credit_card/debit.html.erb [...]
+ Helper: app/helpers/admin/credit_card_helper.rb
+ Helper Test: test/unit/helpers/admin/credit_card_helper_test.rb
diff --git a/railties/lib/rails_generator/generators/components/controller/controller_generator.rb b/railties/lib/rails_generator/generators/components/controller/controller_generator.rb
index 77b2220d57..dc126e8a98 100644
--- a/railties/lib/rails_generator/generators/components/controller/controller_generator.rb
+++ b/railties/lib/rails_generator/generators/components/controller/controller_generator.rb
@@ -2,13 +2,14 @@ class ControllerGenerator < Rails::Generator::NamedBase
def manifest
record do |m|
# Check for class naming collisions.
- m.class_collisions "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper"
+ m.class_collisions "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper", "#{class_name}HelperTest"
# Controller, helper, views, and test directories.
m.directory File.join('app/controllers', class_path)
m.directory File.join('app/helpers', class_path)
m.directory File.join('app/views', class_path, file_name)
m.directory File.join('test/functional', class_path)
+ m.directory File.join('test/unit/helpers', class_path)
# Controller class, functional test, and helper class.
m.template 'controller.rb',
@@ -26,6 +27,11 @@ class ControllerGenerator < Rails::Generator::NamedBase
class_path,
"#{file_name}_helper.rb")
+ m.template 'helper_test.rb',
+ File.join('test/unit/helpers',
+ class_path,
+ "#{file_name}_helper_test.rb")
+
# View template for each action.
actions.each do |action|
path = File.join('app/views', class_path, file_name, "#{action}.html.erb")
diff --git a/railties/lib/rails_generator/generators/components/controller/templates/helper_test.rb b/railties/lib/rails_generator/generators/components/controller/templates/helper_test.rb
new file mode 100644
index 0000000000..591e40900e
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/controller/templates/helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class <%= class_name %>HelperTest < ActionView::TestCase
+end
diff --git a/railties/lib/rails_generator/generators/components/helper/USAGE b/railties/lib/rails_generator/generators/components/helper/USAGE
new file mode 100644
index 0000000000..ef27ca617e
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/helper/USAGE
@@ -0,0 +1,24 @@
+Description:
+ Stubs out a new helper. Pass the helper name, either
+ CamelCased or under_scored.
+
+ To create a helper within a module, specify the helper name as a
+ path like 'parent_module/helper_name'.
+
+ This generates a helper class in app/helpers and a helper test
+ suite in test/unit/helpers.
+
+Example:
+ `./script/generate helper CreditCard`
+
+ Credit card helper.
+ Helper: app/helpers/credit_card_helper.rb
+ Test: test/unit/helpers/credit_card_helper_test.rb
+
+Modules Example:
+ `./script/generate helper 'admin/credit_card'`
+
+ Credit card admin helper.
+ Helper: app/helpers/admin/credit_card_helper.rb
+ Test: test/unit/helpers/admin/credit_card_helper_test.rb
+
diff --git a/railties/lib/rails_generator/generators/components/helper/helper_generator.rb b/railties/lib/rails_generator/generators/components/helper/helper_generator.rb
new file mode 100644
index 0000000000..f7831f7c7a
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/helper/helper_generator.rb
@@ -0,0 +1,25 @@
+class HelperGenerator < Rails::Generator::NamedBase
+ def manifest
+ record do |m|
+ # Check for class naming collisions.
+ m.class_collisions class_path, "#{class_name}Helper", "#{class_name}HelperTest"
+
+ # Helper and helper test directories.
+ m.directory File.join('app/helpers', class_path)
+ m.directory File.join('test/unit/helpers', class_path)
+
+ # Helper and helper test class.
+
+ m.template 'helper.rb',
+ File.join('app/helpers',
+ class_path,
+ "#{file_name}_helper.rb")
+
+ m.template 'helper_test.rb',
+ File.join('test/unit/helpers',
+ class_path,
+ "#{file_name}_helper_test.rb")
+
+ end
+ end
+end
diff --git a/railties/lib/rails_generator/generators/components/helper/templates/helper.rb b/railties/lib/rails_generator/generators/components/helper/templates/helper.rb
new file mode 100644
index 0000000000..3fe2ecdc74
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/helper/templates/helper.rb
@@ -0,0 +1,2 @@
+module <%= class_name %>Helper
+end
diff --git a/railties/lib/rails_generator/generators/components/helper/templates/helper_test.rb b/railties/lib/rails_generator/generators/components/helper/templates/helper_test.rb
new file mode 100644
index 0000000000..591e40900e
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/helper/templates/helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class <%= class_name %>HelperTest < ActionView::TestCase
+end
diff --git a/railties/lib/rails_generator/generators/components/resource/USAGE b/railties/lib/rails_generator/generators/components/resource/USAGE
index 83cc9d7654..e6043f1de1 100644
--- a/railties/lib/rails_generator/generators/components/resource/USAGE
+++ b/railties/lib/rails_generator/generators/components/resource/USAGE
@@ -11,8 +11,8 @@ Description:
You don't have to think up every attribute up front, but it helps to
sketch out a few so you can start working with the resource immediately.
- This creates a model, controller, tests and fixtures for both, and the
- corresponding map.resources declaration in config/routes.rb
+ This creates a model, controller, helper, tests and fixtures for all of them,
+ and the corresponding map.resources declaration in config/routes.rb
Unlike the scaffold generator, the resource generator does not create
views or add any methods to the generated controller.
diff --git a/railties/lib/rails_generator/generators/components/resource/resource_generator.rb b/railties/lib/rails_generator/generators/components/resource/resource_generator.rb
index ea6dd65bde..4ee2fbff63 100644
--- a/railties/lib/rails_generator/generators/components/resource/resource_generator.rb
+++ b/railties/lib/rails_generator/generators/components/resource/resource_generator.rb
@@ -40,6 +40,7 @@ class ResourceGenerator < Rails::Generator::NamedBase
m.directory(File.join('app/views', controller_class_path, controller_file_name))
m.directory(File.join('test/functional', controller_class_path))
m.directory(File.join('test/unit', class_path))
+ m.directory(File.join('test/unit/helpers', class_path))
m.dependency 'model', [name] + @args, :collision => :skip
@@ -49,6 +50,7 @@ class ResourceGenerator < Rails::Generator::NamedBase
m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb"))
+ m.template('helper_test.rb', File.join('test/unit/helpers', controller_class_path, "#{controller_file_name}_helper_test.rb"))
m.route_resources controller_file_name
end
diff --git a/railties/lib/rails_generator/generators/components/resource/templates/helper_test.rb b/railties/lib/rails_generator/generators/components/resource/templates/helper_test.rb
new file mode 100644
index 0000000000..061f64a5e3
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/resource/templates/helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class <%= controller_class_name %>HelperTest < ActionView::TestCase
+end
diff --git a/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb b/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb
index ff0381da2a..2a5edeedb6 100644
--- a/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb
@@ -47,6 +47,7 @@ class ScaffoldGenerator < Rails::Generator::NamedBase
m.directory(File.join('app/views/layouts', controller_class_path))
m.directory(File.join('test/functional', controller_class_path))
m.directory(File.join('test/unit', class_path))
+ m.directory(File.join('test/unit/helpers', class_path))
m.directory(File.join('public/stylesheets', class_path))
for action in scaffold_views
@@ -66,6 +67,7 @@ class ScaffoldGenerator < Rails::Generator::NamedBase
m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb"))
+ m.template('helper_test.rb', File.join('test/unit/helpers', controller_class_path, "#{controller_file_name}_helper_test.rb"))
m.route_resources controller_file_name
diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb b/railties/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb
new file mode 100644
index 0000000000..061f64a5e3
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class <%= controller_class_name %>HelperTest < ActionView::TestCase
+end
diff --git a/railties/lib/rails_generator/secret_key_generator.rb b/railties/lib/rails_generator/secret_key_generator.rb
index 553811d35d..7dd495a2f5 100644
--- a/railties/lib/rails_generator/secret_key_generator.rb
+++ b/railties/lib/rails_generator/secret_key_generator.rb
@@ -1,3 +1,5 @@
+require 'active_support/deprecation'
+
module Rails
# A class for creating random secret keys. This class will do its best to create a
# random secret key that's as secure as possible, using whatever methods are
diff --git a/railties/lib/tasks/databases.rake b/railties/lib/tasks/databases.rake
index 5cb27f1f10..a90c1d4a77 100644
--- a/railties/lib/tasks/databases.rake
+++ b/railties/lib/tasks/databases.rake
@@ -1,7 +1,12 @@
namespace :db do
+ task :load_config => :rails_env do
+ require 'active_record'
+ ActiveRecord::Base.configurations = Rails::Configuration.new.database_configuration
+ end
+
namespace :create do
desc 'Create all the local databases defined in config/database.yml'
- task :all => :environment do
+ task :all => :load_config do
ActiveRecord::Base.configurations.each_value do |config|
# Skip entries that don't have a database key, such as the first entry here:
#
@@ -22,7 +27,7 @@ namespace :db do
end
desc 'Create the database defined in config/database.yml for the current RAILS_ENV'
- task :create => :environment do
+ task :create => :load_config do
create_database(ActiveRecord::Base.configurations[RAILS_ENV])
end
@@ -76,7 +81,7 @@ namespace :db do
namespace :drop do
desc 'Drops all the local databases defined in config/database.yml'
- task :all => :environment do
+ task :all => :load_config do
ActiveRecord::Base.configurations.each_value do |config|
# Skip entries that don't have a database key
next unless config['database']
@@ -87,7 +92,7 @@ namespace :db do
end
desc 'Drops the database for the current RAILS_ENV'
- task :drop => :environment do
+ task :drop => :load_config do
config = ActiveRecord::Base.configurations[RAILS_ENV || 'development']
begin
drop_database(config)
@@ -393,6 +398,7 @@ end
def drop_database(config)
case config['adapter']
when 'mysql'
+ ActiveRecord::Base.establish_connection(config)
ActiveRecord::Base.connection.drop_database config['database']
when /^sqlite/
FileUtils.rm(File.join(RAILS_ROOT, config['database']))
diff --git a/railties/lib/tasks/framework.rake b/railties/lib/tasks/framework.rake
index 66ab78c3b2..d639214ffe 100644
--- a/railties/lib/tasks/framework.rake
+++ b/railties/lib/tasks/framework.rake
@@ -5,7 +5,6 @@ namespace :rails do
deps = %w(actionpack activerecord actionmailer activesupport activeresource)
require 'rubygems'
require 'rubygems/gem_runner'
- Gem.manage_gems
rails = (version = ENV['VERSION']) ?
Gem.cache.find_name('rails', "= #{version}").first :
@@ -79,7 +78,7 @@ namespace :rails do
end
desc "Update both configs, scripts and public/javascripts from Rails"
- task :update => [ "update:scripts", "update:javascripts", "update:configs" ]
+ task :update => [ "update:scripts", "update:javascripts", "update:configs", "update:application_controller" ]
namespace :update do
desc "Add new scripts to the application script/ directory"
@@ -115,5 +114,24 @@ namespace :rails do
require 'railties_path'
FileUtils.cp(RAILTIES_PATH + '/environments/boot.rb', RAILS_ROOT + '/config/boot.rb')
end
+
+ desc "Rename application.rb to application_controller.rb"
+ task :application_controller do
+ old_style = RAILS_ROOT + '/app/controllers/application.rb'
+ new_style = RAILS_ROOT + '/app/controllers/application_controller.rb'
+ if File.exists?(old_style) && !File.exists?(new_style)
+ FileUtils.mv(old_style, new_style)
+ puts "#{old_style} has been renamed to #{new_style}, update your SCM as necessary"
+ end
+ end
+
+ desc "Generate dispatcher files in RAILS_ROOT/public"
+ task :generate_dispatchers do
+ require 'railties_path'
+ FileUtils.cp(RAILTIES_PATH + '/dispatches/config.ru', RAILS_ROOT + '/config.ru')
+ FileUtils.cp(RAILTIES_PATH + '/dispatches/dispatch.fcgi', RAILS_ROOT + '/public/dispatch.fcgi')
+ FileUtils.cp(RAILTIES_PATH + '/dispatches/dispatch.rb', RAILS_ROOT + '/public/dispatch.rb')
+ FileUtils.cp(RAILTIES_PATH + '/dispatches/dispatch.rb', RAILS_ROOT + '/public/dispatch.cgi')
+ end
end
end
diff --git a/railties/lib/tasks/middleware.rake b/railties/lib/tasks/middleware.rake
new file mode 100644
index 0000000000..e0dcf50307
--- /dev/null
+++ b/railties/lib/tasks/middleware.rake
@@ -0,0 +1,7 @@
+desc 'Prints out your Rack middleware stack'
+task :middleware => :environment do
+ ActionController::Dispatcher.middleware.each do |middleware|
+ puts "use #{middleware.inspect}"
+ end
+ puts "run ActionController::Dispatcher.new"
+end
diff --git a/railties/lib/tasks/misc.rake b/railties/lib/tasks/misc.rake
index 5c99725203..411750bf40 100644
--- a/railties/lib/tasks/misc.rake
+++ b/railties/lib/tasks/misc.rake
@@ -3,6 +3,12 @@ task :environment do
require(File.join(RAILS_ROOT, 'config', 'environment'))
end
+task :rails_env do
+ unless defined? RAILS_ENV
+ RAILS_ENV = ENV['RAILS_ENV'] ||= 'development'
+ end
+end
+
desc 'Generate a crytographically secure secret key. This is typically used to generate a secret for cookie sessions.'
task :secret do
puts ActiveSupport::SecureRandom.hex(64)
diff --git a/railties/lib/tasks/statistics.rake b/railties/lib/tasks/statistics.rake
index dbd0773194..5ab27a0f62 100644
--- a/railties/lib/tasks/statistics.rake
+++ b/railties/lib/tasks/statistics.rake
@@ -4,7 +4,6 @@ STATS_DIRECTORIES = [
%w(Models app/models),
%w(Libraries lib/),
%w(APIs app/apis),
- %w(Components components),
%w(Integration\ tests test/integration),
%w(Functional\ tests test/functional),
%w(Unit\ tests test/unit)
diff --git a/railties/lib/tasks/testing.rake b/railties/lib/tasks/testing.rake
index 328bde7442..4242458672 100644
--- a/railties/lib/tasks/testing.rake
+++ b/railties/lib/tasks/testing.rake
@@ -7,7 +7,7 @@ def recent_tests(source_pattern, test_path, touched_since = 10.minutes.ago)
tests = []
source_dir = File.dirname(path).split("/")
source_file = File.basename(path, '.rb')
-
+
# Support subdirs in app/models and app/controllers
modified_test_path = source_dir.length > 2 ? "#{test_path}/" << source_dir[1..source_dir.length].join('/') : test_path
@@ -18,7 +18,7 @@ def recent_tests(source_pattern, test_path, touched_since = 10.minutes.ago)
# For modified files in app, run tests in subdirs too. ex. /test/functional/account/*_test.rb
test = "#{modified_test_path}/#{File.basename(path, '.rb').sub("_controller","")}"
FileList["#{test}/*_test.rb"].each { |f| tests.push f } if File.exist?(test)
-
+
return tests
end
@@ -63,7 +63,7 @@ namespace :test do
t.test_files = touched.uniq
end
Rake::Task['test:recent'].comment = "Test recent changes"
-
+
Rake::TestTask.new(:uncommitted => "db:test:prepare") do |t|
def t.file_list
if File.directory?(".svn")
@@ -82,7 +82,7 @@ namespace :test do
unit_tests.uniq + functional_tests.uniq
end
-
+
t.libs << 'test'
t.verbose = true
end
diff --git a/railties/lib/test_help.rb b/railties/lib/test_help.rb
index 3cc61d7932..b5c92c1790 100644
--- a/railties/lib/test_help.rb
+++ b/railties/lib/test_help.rb
@@ -1,21 +1,30 @@
-require_dependency 'application'
-
# Make double-sure the RAILS_ENV is set to test,
# so fixtures are loaded to the right database
silence_warnings { RAILS_ENV = "test" }
require 'test/unit'
require 'active_support/test_case'
-require 'active_record/fixtures'
require 'action_controller/test_case'
+require 'action_view/test_case'
require 'action_controller/integration'
require 'action_mailer/test_case' if defined?(ActionMailer)
-Test::Unit::TestCase.fixture_path = RAILS_ROOT + "/test/fixtures/"
-ActionController::IntegrationTest.fixture_path = Test::Unit::TestCase.fixture_path
+if defined?(ActiveRecord)
+ require 'active_record/test_case'
+ require 'active_record/fixtures'
+
+ class ActiveSupport::TestCase
+ include ActiveRecord::TestFixtures
+ self.fixture_path = "#{RAILS_ROOT}/test/fixtures/"
+ self.use_instantiated_fixtures = false
+ self.use_transactional_fixtures = true
+ end
+
+ ActionController::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path
-def create_fixtures(*table_names)
- Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names)
+ def create_fixtures(*table_names, &block)
+ Fixtures.create_fixtures(ActiveSupport::TestCase.fixture_path, table_names, {}, &block)
+ end
end
begin