aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2008-12-03 10:32:30 -0600
committerJeremy Kemper <jeremy@bitsweat.net>2008-12-03 10:32:30 -0600
commit99f2cb4918786382413bdd29b3cacfd5b9377677 (patch)
tree9279a5f1b63a03f51b1a04734a4c70bb6b6c3546 /railties
parent0b4858cf38f522208381f9bfbbb5c066aceb30d2 (diff)
parent1e1056f6435254c81f02fd0fba53d9356050cb00 (diff)
downloadrails-99f2cb4918786382413bdd29b3cacfd5b9377677.tar.gz
rails-99f2cb4918786382413bdd29b3cacfd5b9377677.tar.bz2
rails-99f2cb4918786382413bdd29b3cacfd5b9377677.zip
Merge branch 'master' of git@github.com:rails/rails
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG47
-rw-r--r--railties/Rakefile6
-rwxr-xr-xrailties/bin/process/inspector3
-rwxr-xr-xrailties/bin/process/reaper3
-rwxr-xr-xrailties/bin/process/spawner3
-rwxr-xr-xrailties/bin/rails1
-rw-r--r--railties/config.ru17
-rw-r--r--railties/configs/initializers/new_rails_defaults.rb2
-rw-r--r--railties/configs/initializers/session_store.rb15
-rw-r--r--railties/dispatches/config.ru7
-rw-r--r--railties/environments/environment.rb62
-rw-r--r--railties/environments/production.rb17
-rw-r--r--railties/environments/test.rb5
-rw-r--r--railties/helpers/application_controller.rb8
-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/server.rb20
-rw-r--r--railties/lib/fcgi_handler.rb2
-rw-r--r--railties/lib/initializer.rb16
-rw-r--r--railties/lib/rails/gem_dependency.rb1
-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.rb348
-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/tasks/databases.rake14
-rw-r--r--railties/lib/tasks/framework.rake1
-rw-r--r--railties/lib/tasks/middleware.rake7
-rw-r--r--railties/lib/tasks/misc.rake6
-rw-r--r--railties/test/gem_dependency_test.rb14
-rw-r--r--railties/test/initializer_test.rb6
-rw-r--r--railties/test/vendor/gems/dummy-gem-f-1.0.0/.specification39
-rw-r--r--railties/test/vendor/gems/dummy-gem-f-1.0.0/lib/dummy-gem-f.rb1
-rw-r--r--railties/test/vendor/gems/dummy-gem-g-1.0.0/.specification39
-rw-r--r--railties/test/vendor/gems/dummy-gem-g-1.0.0/lib/dummy-gem-g.rb1
39 files changed, 855 insertions, 747 deletions
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index ad8ba43c17..ca49c5d1c7 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -1,6 +1,51 @@
*2.3.0 [Edge]*
-* Enhanced Rails.root to take parameters that'll be join with the root, like Rails.root('app', 'controllers') => File.join(Rails.root, 'app', 'controllers') #1482 [Damian Janowski]
+* Add "-m/--template" option to Rails generator to apply a template to the generated application. [Jeremy McAnally]
+
+ This has been extracted from rg - http://github.com/jeremymcanally/rg
+
+ Example:
+
+ # template.rb
+
+ # Install plugins from git or svn
+ plugin "will-paginate", :git => "git://github.com/mislav/will_paginate.git"
+ plugin "old-restful-auth", :svn => "http://svn.techno-weenie.net/projects/plugins/restful_authentication/"
+
+ # Add gems to environment.rb
+ gem "jeremymcanally-context"
+ gem "bluecloth"
+
+ # Vendor file. Data in a string or...
+ vendor("borrowed.rb", <<CODE
+ def helpful_method
+ do_something_helpful_here
+ end
+ CODE
+
+ # ...file data from block return value.
+ # #initializer creates a new initializer file
+ initializer("crypto.rb") do
+ salt = "--#{Time.now}--#{rand}--#{srand(Time.now.to_i)}"
+
+ "SPECIAL_SALT = '#{salt}'"
+ end
+
+ Usage:
+
+ To use a template, provide a file path or URL:
+
+ 1. Using a local file :
+
+ rails <application name> -m /path/to/my/template.rb
+
+ 2. Or directly from a URL :
+
+ rails <application name> --template=http://gist.github.com/31208.txt
+
+* Extracted the process scripts (inspector, reaper, spawner) into the plugin irs_process_scripts [DHH]
+
+* Changed Rails.root to return a Pathname object (allows for Rails.root.join('app', 'controllers') => "#{RAILS_ROOT}/app/controllers") #1482 [Damian Janowski/?]
* Added view path support for engines [DHH]
diff --git a/railties/Rakefile b/railties/Rakefile
index bf70219aa8..f812b42f1d 100644
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -53,7 +53,6 @@ BASE_DIRS = %w(
public
script
script/performance
- script/process
test
vendor
vendor/plugins
@@ -71,7 +70,7 @@ LOG_FILES = %w( server.log development.log test.log production.log )
HTML_FILES = %w( 422.html 404.html 500.html index.html robots.txt favicon.ico images/rails.png
javascripts/prototype.js javascripts/application.js
javascripts/effects.js javascripts/dragdrop.js javascripts/controls.js )
-BIN_FILES = %w( about console destroy generate performance/benchmarker performance/profiler process/reaper process/spawner process/inspector runner server plugin )
+BIN_FILES = %w( about console destroy generate performance/benchmarker performance/profiler runner server plugin )
VENDOR_LIBS = %w( actionpack activerecord actionmailer activesupport activeresource railties )
@@ -174,9 +173,6 @@ task :copy_dispatches do
copy_with_rewritten_ruby_path("dispatches/dispatch.fcgi", "#{PKG_DESTINATION}/public/dispatch.fcgi")
chmod 0755, "#{PKG_DESTINATION}/public/dispatch.fcgi"
-
- # copy_with_rewritten_ruby_path("dispatches/gateway.cgi", "#{PKG_DESTINATION}/public/gateway.cgi")
- # chmod 0755, "#{PKG_DESTINATION}/public/gateway.cgi"
end
task :copy_html_files do
diff --git a/railties/bin/process/inspector b/railties/bin/process/inspector
deleted file mode 100755
index bf25ad86d1..0000000000
--- a/railties/bin/process/inspector
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../config/boot'
-require 'commands/process/inspector'
diff --git a/railties/bin/process/reaper b/railties/bin/process/reaper
deleted file mode 100755
index c77f04535f..0000000000
--- a/railties/bin/process/reaper
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../config/boot'
-require 'commands/process/reaper'
diff --git a/railties/bin/process/spawner b/railties/bin/process/spawner
deleted file mode 100755
index 7118f3983c..0000000000
--- a/railties/bin/process/spawner
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../config/boot'
-require 'commands/process/spawner'
diff --git a/railties/bin/rails b/railties/bin/rails
index ae0cc8adca..6a0c675206 100755
--- a/railties/bin/rails
+++ b/railties/bin/rails
@@ -8,6 +8,7 @@ if %w(--version -v).include? ARGV.first
end
freeze = ARGV.any? { |option| %w(--freeze -f).include?(option) }
+
app_path = ARGV.first
require File.dirname(__FILE__) + '/../lib/rails_generator'
diff --git a/railties/config.ru b/railties/config.ru
deleted file mode 100644
index 43492a2dcc..0000000000
--- a/railties/config.ru
+++ /dev/null
@@ -1,17 +0,0 @@
-# Rackup Configuration
-#
-# Start Rails mongrel server with rackup
-# $ rackup -p 3000 config.ru
-#
-# Start server with webrick (or any compatible Rack server) instead
-# $ rackup -p 3000 -s webrick config.ru
-
-# Require your environment file to bootstrap Rails
-require File.dirname(__FILE__) + '/config/environment'
-
-# Static server middleware
-# You can remove this extra check if you use an asset server
-use Rails::Rack::Static
-
-# Dispatch the request
-run ActionController::Dispatcher.new
diff --git a/railties/configs/initializers/new_rails_defaults.rb b/railties/configs/initializers/new_rails_defaults.rb
index 78e0117cc4..8ec3186c84 100644
--- a/railties/configs/initializers/new_rails_defaults.rb
+++ b/railties/configs/initializers/new_rails_defaults.rb
@@ -1,3 +1,5 @@
+# Be sure to restart your server when you modify this file.
+
# These settings change the behavior of Rails 2 apps and will be defaults
# for Rails 3. You can remove this initializer when Rails 3 is released.
diff --git a/railties/configs/initializers/session_store.rb b/railties/configs/initializers/session_store.rb
new file mode 100644
index 0000000000..40179e0aa3
--- /dev/null
+++ b/railties/configs/initializers/session_store.rb
@@ -0,0 +1,15 @@
+# Be sure to restart your server when you modify this file.
+
+# Your secret key for verifying cookie session data integrity.
+# If you change this key, all old sessions will become invalid!
+# Make sure the secret is at least 30 characters and all random,
+# no regular words or you'll be exposed to dictionary attacks.
+ActionController::Base.session = {
+ :session_key => '_<%= app_name %>_session',
+ :secret => '<%= app_secret %>'
+}
+
+# Use the database for sessions instead of the cookie-based default,
+# which shouldn't be used to store highly confidential information
+# (create the session table with "rake db:sessions:create")
+# ActionController::Base.session_store = :active_record_store
diff --git a/railties/dispatches/config.ru b/railties/dispatches/config.ru
new file mode 100644
index 0000000000..acbfe4e9ae
--- /dev/null
+++ b/railties/dispatches/config.ru
@@ -0,0 +1,7 @@
+# Rack Dispatcher
+
+# Require your environment file to bootstrap Rails
+require File.dirname(__FILE__) + '/config/environment'
+
+# Dispatch the request
+run ActionController::Dispatcher.new
diff --git a/railties/environments/environment.rb b/railties/environments/environment.rb
index 5cb201401b..4a2df36307 100644
--- a/railties/environments/environment.rb
+++ b/railties/environments/environment.rb
@@ -1,9 +1,5 @@
# Be sure to restart your server when you modify this file
-# Uncomment below to force Rails into production mode when
-# you don't control web/app server and can't set it the proper way
-# ENV['RAILS_ENV'] ||= 'production'
-
# Specifies gem version of Rails to use when vendor/rails is not present
<%= '# ' if freeze %>RAILS_GEM_VERSION = '<%= Rails::VERSION::STRING %>' unless defined? RAILS_GEM_VERSION
@@ -14,62 +10,32 @@ Rails::Initializer.run do |config|
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
- # See Rails::Configuration for more options.
- # Skip frameworks you're not going to use. To use Rails without a database
- # you must remove the Active Record framework.
- # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
+ # Add additional load paths for your own custom dirs
+ # config.load_paths += %W( #{RAILS_ROOT}/extras )
- # Specify gems that this application depends on.
- # They can then be installed with "rake gems:install" on new installations.
- # You have to specify the :lib option for libraries, where the Gem name (sqlite3-ruby) differs from the file itself (sqlite3)
+ # Specify gems that this application depends on and have them installed with rake gems:install
# config.gem "bj"
# config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
# config.gem "sqlite3-ruby", :lib => "sqlite3"
# config.gem "aws-s3", :lib => "aws/s3"
- # Only load the plugins named here, in the order given. By default, all plugins
- # in vendor/plugins are loaded in alphabetical order.
+ # Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
- # Add additional load paths for your own custom dirs
- # config.load_paths += %W( #{RAILS_ROOT}/extras )
+ # Skip frameworks you're not going to use. To use Rails without a database,
+ # you must remove the Active Record framework.
+ # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
- # Force all environments to use the same logger level
- # (by default production uses :info, the others :debug)
- # config.log_level = :debug
+ # Activate observers that should always be running
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
- # Make Time.zone default to the specified zone, and make Active Record store time values
- # in the database in UTC, and return them converted to the specified local zone.
- # Run "rake -D time" for a list of tasks for finding time zone names. Comment line to use default local time.
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
+ # Run "rake -D time" for a list of tasks for finding time zone names.
config.time_zone = 'UTC'
- # The internationalization framework can be changed to have another default locale (standard is :en) or more load paths.
- # All files from config/locales/*.rb,yml are added automatically.
- # config.i18n.load_path << Dir[File.join(RAILS_ROOT, 'my', 'locales', '*.{rb,yml}')]
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
# config.i18n.default_locale = :de
-
- # Your secret key for verifying cookie session data integrity.
- # If you change this key, all old sessions will become invalid!
- # Make sure the secret is at least 30 characters and all random,
- # no regular words or you'll be exposed to dictionary attacks.
- config.action_controller.session = {
- :session_key => '_<%= app_name %>_session',
- :secret => '<%= app_secret %>'
- }
-
- # Use the database for sessions instead of the cookie-based default,
- # which shouldn't be used to store highly confidential information
- # (create the session table with "rake db:sessions:create")
- # config.action_controller.session_store = :active_record_store
-
- # Use SQL instead of Active Record's schema dumper when creating the test database.
- # This is necessary if your schema can't be completely dumped by the schema dumper,
- # like if you have constraints or database-specific column types
- # config.active_record.schema_format = :sql
-
- # Activate observers that should always be running
- # Please note that observers generated using script/generate observer need to have an _observer suffix
- # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
-end
+end \ No newline at end of file
diff --git a/railties/environments/production.rb b/railties/environments/production.rb
index ec5b7bc865..1fc9f6b923 100644
--- a/railties/environments/production.rb
+++ b/railties/environments/production.rb
@@ -4,21 +4,24 @@
# Code is not reloaded between requests
config.cache_classes = true
-# Enable threaded mode
-# config.threadsafe!
-
-# Use a different logger for distributed setups
-# config.logger = SyslogLogger.new
-
# Full error reports are disabled and caching is turned on
config.action_controller.consider_all_requests_local = false
config.action_controller.perform_caching = true
+# See everything in the log (default is :info)
+# config.log_level = :debug
+
+# Use a different logger for distributed setups
+# config.logger = SyslogLogger.new
+
# Use a different cache store in production
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and javascripts from an asset server
-# config.action_controller.asset_host = "http://assets.example.com"
+# config.action_controller.asset_host = "http://assets.example.com"
# Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false
+
+# Enable threaded mode
+# config.threadsafe! \ No newline at end of file
diff --git a/railties/environments/test.rb b/railties/environments/test.rb
index 1e709e1d19..496eb9572b 100644
--- a/railties/environments/test.rb
+++ b/railties/environments/test.rb
@@ -20,3 +20,8 @@ config.action_controller.allow_forgery_protection = false
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
+
+# Use SQL instead of Active Record's schema dumper when creating the test database.
+# This is necessary if your schema can't be completely dumped by the schema dumper,
+# like if you have constraints or database-specific column types
+# config.active_record.schema_format = :sql \ No newline at end of file
diff --git a/railties/helpers/application_controller.rb b/railties/helpers/application_controller.rb
index ef33aa8353..6635a3f487 100644
--- a/railties/helpers/application_controller.rb
+++ b/railties/helpers/application_controller.rb
@@ -3,12 +3,8 @@
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
- # See ActionController::RequestForgeryProtection for details
- protect_from_forgery
-
- # See ActionController::Base for details
- # Uncomment this to filter the contents of submitted sensitive data parameters
- # from your application log (in this case, all fields with names like "password").
+ # Scrub sensitive parameters from your log
# filter_parameter_logging :password
end
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/server.rb b/railties/lib/commands/server.rb
index a4bb52592f..7057fcc33f 100644
--- a/railties/lib/commands/server.rb
+++ b/railties/lib/commands/server.rb
@@ -65,7 +65,6 @@ end
ENV["RAILS_ENV"] = options[:environment]
RAILS_ENV.replace(options[:environment]) if defined?(RAILS_ENV)
-require RAILS_ROOT + "/config/environment"
if File.exist?(options[:config])
config = options[:config]
@@ -74,20 +73,23 @@ if File.exist?(options[:config])
if cfgfile[/^#\\(.*)/]
opts.parse!($1.split(/\s+/))
end
- app = eval("Rack::Builder.new {( " + cfgfile + "\n )}.to_app", nil, config)
+ inner_app = eval("Rack::Builder.new {( " + cfgfile + "\n )}.to_app", nil, config)
else
require config
- app = Object.const_get(File.basename(config, '.rb').capitalize)
+ inner_app = Object.const_get(File.basename(config, '.rb').capitalize)
end
else
- app = Rack::Builder.new {
- use Rails::Rack::Logger
- use Rails::Rack::Static
- use Rails::Rack::Debugger if options[:debugger]
- run ActionController::Dispatcher.new
- }.to_app
+ require RAILS_ROOT + "/config/environment"
+ inner_app = ActionController::Dispatcher.new
end
+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 }
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 b645ac3da2..4bb1e480b7 100644
--- a/railties/lib/initializer.rb
+++ b/railties/lib/initializer.rb
@@ -48,8 +48,8 @@ module Rails
end
end
- def root(*args)
- File.join(RAILS_ROOT, *args.compact) if defined?(RAILS_ROOT)
+ def root
+ Pathname.new(RAILS_ROOT) if defined?(RAILS_ROOT)
end
def env
@@ -513,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
@@ -876,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/*/"] : []
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_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 32383d2bbd..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,117 +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'
+ mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.."
default_options :db => (ENV["RAILS_DEFAULT_DATABASE"] || DEFAULT_DATABASE),
:shebang => DEFAULT_SHEBANG, :with_dispatchers => false, :freeze => false
- mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.."
+
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_controller.rb", "app/controllers/application_controller.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/backtrace_silencers.rb", "config/initializers/backtrace_silencers.rb"
- 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"
-
- # Locale
- m.template "configs/locales/en.yml", "config/locales/en.yml"
-
- # 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
- if options[:with_dispatchers]
- 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
-
- # 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
@@ -138,55 +67,192 @@ class AppGenerator < Rails::Generator::Base
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
- config/locales
- 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/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 df080e94ac..d639214ffe 100644
--- a/railties/lib/tasks/framework.rake
+++ b/railties/lib/tasks/framework.rake
@@ -128,6 +128,7 @@ namespace :rails do
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')
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/test/gem_dependency_test.rb b/railties/test/gem_dependency_test.rb
index 4f9e824c9f..1d4f2b18b3 100644
--- a/railties/test/gem_dependency_test.rb
+++ b/railties/test/gem_dependency_test.rb
@@ -129,5 +129,19 @@ uses_mocha "Plugin Tests" do
assert_equal '1.0.0', DUMMY_GEM_E_VERSION
end
+ def test_gem_handle_missing_dependencies
+ dummy_gem = Rails::GemDependency.new "dummy-gem-g"
+ dummy_gem.add_load_paths
+ dummy_gem.load
+ assert dummy_gem.loaded?
+ debugger
+ assert_equal 2, dummy_gem.dependencies.size
+ assert_nothing_raised do
+ dummy_gem.dependencies.each do |g|
+ g.dependencies
+ end
+ end
+ end
+
end
end
diff --git a/railties/test/initializer_test.rb b/railties/test/initializer_test.rb
index 33c81bc5ad..dad9e55e61 100644
--- a/railties/test/initializer_test.rb
+++ b/railties/test/initializer_test.rb
@@ -314,10 +314,10 @@ end
class RailsRootTest < Test::Unit::TestCase
def test_rails_dot_root_equals_rails_root
- assert_equal RAILS_ROOT, Rails.root
+ assert_equal RAILS_ROOT, Rails.root.to_s
end
- def test_rails_dot_root_accepts_arguments_for_file_dot_join
- assert_equal File.join(RAILS_ROOT, 'app', 'controllers'), Rails.root('app', 'controllers')
+ def test_rails_dot_root_should_be_a_pathname
+ assert_equal File.join(RAILS_ROOT, 'app', 'controllers'), Rails.root.join('app', 'controllers').to_s
end
end \ No newline at end of file
diff --git a/railties/test/vendor/gems/dummy-gem-f-1.0.0/.specification b/railties/test/vendor/gems/dummy-gem-f-1.0.0/.specification
new file mode 100644
index 0000000000..70a36b9a8c
--- /dev/null
+++ b/railties/test/vendor/gems/dummy-gem-f-1.0.0/.specification
@@ -0,0 +1,39 @@
+--- !ruby/object:Gem::Specification
+name: dummy-gem-f
+version: !ruby/object:Gem::Version
+ version: 1.3.0
+platform: ruby
+authors:
+- "Nobody"
+date: 2008-10-03 00:00:00 -04:00
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: absolutely-no-such-gem
+ type: :runtime
+ version_requirement:
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: 1.0.0
+ version:
+files:
+- lib
+- lib/dummy-gem-f.rb
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+required_rubygems_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+requirements: []
+specification_version: 2
+summary: Dummy Gem F
diff --git a/railties/test/vendor/gems/dummy-gem-f-1.0.0/lib/dummy-gem-f.rb b/railties/test/vendor/gems/dummy-gem-f-1.0.0/lib/dummy-gem-f.rb
new file mode 100644
index 0000000000..0271c8c48a
--- /dev/null
+++ b/railties/test/vendor/gems/dummy-gem-f-1.0.0/lib/dummy-gem-f.rb
@@ -0,0 +1 @@
+DUMMY_GEM_F_VERSION="1.0.0"
diff --git a/railties/test/vendor/gems/dummy-gem-g-1.0.0/.specification b/railties/test/vendor/gems/dummy-gem-g-1.0.0/.specification
new file mode 100644
index 0000000000..5483048c1c
--- /dev/null
+++ b/railties/test/vendor/gems/dummy-gem-g-1.0.0/.specification
@@ -0,0 +1,39 @@
+--- !ruby/object:Gem::Specification
+name: dummy-gem-g
+version: !ruby/object:Gem::Version
+ version: 1.3.0
+platform: ruby
+authors:
+- "Nobody"
+date: 2008-10-03 00:00:00 -04:00
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: dummy-gem-f
+ type: :development
+ version_requirement:
+ version_requirements: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: 1.0.0
+ version:
+files:
+- lib
+- lib/dummy-gem-g.rb
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+required_rubygems_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: "0"
+ version:
+requirements: []
+specification_version: 2
+summary: Dummy Gem G
diff --git a/railties/test/vendor/gems/dummy-gem-g-1.0.0/lib/dummy-gem-g.rb b/railties/test/vendor/gems/dummy-gem-g-1.0.0/lib/dummy-gem-g.rb
new file mode 100644
index 0000000000..8fc056586c
--- /dev/null
+++ b/railties/test/vendor/gems/dummy-gem-g-1.0.0/lib/dummy-gem-g.rb
@@ -0,0 +1 @@
+DUMMY_GEM_G_VERSION="1.0.0"