aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rwxr-xr-xrailties/bin/gen31
-rwxr-xr-xrailties/bin/rails13
-rw-r--r--railties/lib/generators.rb26
-rw-r--r--railties/lib/generators/actions.rb284
-rw-r--r--railties/lib/generators/base.rb93
-rw-r--r--railties/lib/generators/generated_attribute.rb44
-rw-r--r--railties/lib/generators/named_base.rb74
-rw-r--r--railties/lib/generators/rails/app/USAGE (renamed from railties/lib/rails_generator/generators/applications/app/USAGE)0
-rw-r--r--railties/lib/generators/rails/app/app_generator.rb200
-rw-r--r--railties/lib/generators/rails/app/templates/README (renamed from railties/README)0
-rwxr-xr-xrailties/lib/generators/rails/app/templates/Rakefile (renamed from railties/fresh_rakefile)0
-rw-r--r--railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb (renamed from railties/helpers/application_controller.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb (renamed from railties/helpers/application_helper.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/app/models/.empty_directory (renamed from railties/configs/empty.log)0
-rw-r--r--railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory (renamed from railties/html/favicon.ico)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/boot.rb (renamed from railties/environments/boot.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/frontbase.yml (renamed from railties/configs/databases/frontbase.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml (renamed from railties/configs/databases/ibm_db.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/mysql.yml (renamed from railties/configs/databases/mysql.yml)12
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/oracle.yml (renamed from railties/configs/databases/oracle.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/postgresql.yml (renamed from railties/configs/databases/postgresql.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/sqlite2.yml (renamed from railties/configs/databases/sqlite2.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml (renamed from railties/configs/databases/sqlite3.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/environment.rb (renamed from railties/environments/environment.rb)8
-rw-r--r--railties/lib/generators/rails/app/templates/config/environments/development.rb (renamed from railties/environments/development.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/environments/production.rb (renamed from railties/environments/production.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/environments/test.rb (renamed from railties/environments/test.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb (renamed from railties/configs/initializers/backtrace_silencers.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/initializers/inflections.rb (renamed from railties/configs/initializers/inflections.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb (renamed from railties/configs/initializers/mime_types.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/initializers/new_rails_defaults.rb (renamed from railties/configs/initializers/new_rails_defaults.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt (renamed from railties/configs/initializers/session_store.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/locales/en.yml (renamed from railties/configs/locales/en.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/routes.rb (renamed from railties/configs/routes.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/db/seeds.rb (renamed from railties/configs/seeds.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/dispatchers/config.ru (renamed from railties/dispatches/config.ru)0
-rwxr-xr-xrailties/lib/generators/rails/app/templates/dispatchers/dispatch.fcgi (renamed from railties/dispatches/dispatch.fcgi)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/dispatchers/dispatch.rb (renamed from railties/dispatches/dispatch.rb)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/dispatchers/gateway.cgi (renamed from railties/dispatches/gateway.cgi)2
-rw-r--r--railties/lib/generators/rails/app/templates/doc/README_FOR_APP (renamed from railties/doc/README_FOR_APP)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/404.html (renamed from railties/html/404.html)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/422.html (renamed from railties/html/422.html)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/500.html (renamed from railties/html/500.html)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/favicon.ico0
-rw-r--r--railties/lib/generators/rails/app/templates/public/images/rails.png (renamed from railties/html/images/rails.png)bin6646 -> 6646 bytes
-rw-r--r--railties/lib/generators/rails/app/templates/public/index.html (renamed from railties/html/index.html)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/javascripts/application.js (renamed from railties/html/javascripts/application.js)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/javascripts/controls.js (renamed from railties/html/javascripts/controls.js)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js (renamed from railties/html/javascripts/dragdrop.js)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/javascripts/effects.js (renamed from railties/html/javascripts/effects.js)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/javascripts/prototype.js (renamed from railties/html/javascripts/prototype.js)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/robots.txt (renamed from railties/html/robots.txt)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory0
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/about.tt (renamed from railties/bin/about)4
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/console.tt (renamed from railties/bin/console)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/dbconsole.tt (renamed from railties/bin/dbconsole)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/destroy.tt (renamed from railties/bin/destroy)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/generate.tt (renamed from railties/bin/generate)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/performance/benchmarker.tt (renamed from railties/bin/performance/benchmarker)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/performance/profiler.tt (renamed from railties/bin/performance/profiler)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/plugin.tt (renamed from railties/bin/plugin)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/runner.tt (renamed from railties/bin/runner)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/server.tt (renamed from railties/bin/server)2
-rw-r--r--railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory0
-rw-r--r--railties/lib/generators/rails/app/templates/test/functional/.empty_directory0
-rw-r--r--railties/lib/generators/rails/app/templates/test/integration/.empty_directory0
-rw-r--r--railties/lib/generators/rails/app/templates/test/performance/performance_test.rb (renamed from railties/helpers/performance_test.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/test/test_helper.rb (renamed from railties/helpers/test_helper.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/test/unit/.empty_directory0
-rw-r--r--railties/lib/generators/rails/metal/USAGE8
-rw-r--r--railties/lib/generators/rails/metal/metal_generator.rb7
-rw-r--r--railties/lib/generators/rails/metal/templates/metal.rb12
-rw-r--r--railties/lib/generators/rails/plugin/USAGE13
-rw-r--r--railties/lib/generators/rails/plugin/plugin_generator.rb41
-rw-r--r--railties/lib/generators/rails/plugin/templates/MIT-LICENSE20
-rw-r--r--railties/lib/generators/rails/plugin/templates/README13
-rw-r--r--railties/lib/generators/rails/plugin/templates/Rakefile23
-rw-r--r--railties/lib/generators/rails/plugin/templates/generators/%file_name%/%file_name%_generator.rb.tt2
-rw-r--r--railties/lib/generators/rails/plugin/templates/generators/%file_name%/USAGE.tt8
-rw-r--r--railties/lib/generators/rails/plugin/templates/generators/%file_name%/templates/.empty_directory0
-rw-r--r--railties/lib/generators/rails/plugin/templates/init.rb1
-rw-r--r--railties/lib/generators/rails/plugin/templates/install.rb1
-rw-r--r--railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt1
-rw-r--r--railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt4
-rw-r--r--railties/lib/generators/rails/plugin/templates/uninstall.rb1
-rw-r--r--railties/lib/generators/test_unit.rb12
-rw-r--r--railties/lib/generators/test_unit/plugin/plugin_generator.rb14
-rw-r--r--railties/lib/generators/test_unit/plugin/templates/test/%file_name%_test.rb8
-rw-r--r--railties/lib/generators/test_unit/plugin/templates/test/test_helper.rb3
-rw-r--r--railties/lib/rails_generator/generators/applications/app/app_generator.rb263
-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.rb401
-rw-r--r--railties/lib/rails_generator/secret_key_generator.rb24
-rw-r--r--railties/test/boot_test.rb2
-rw-r--r--railties/test/generators/actions_test.rb184
-rw-r--r--railties/test/generators/app_test.rb132
-rw-r--r--railties/test/generators/generator_test_helper.rb305
-rw-r--r--railties/test/generators/rails_template_runner_test.rb216
-rw-r--r--railties/test/rails_generator/generator_test_helper.rb303
-rw-r--r--railties/test/rails_generator/rails_controller_generator_test.rb (renamed from railties/test/generators/rails_controller_generator_test.rb)0
-rw-r--r--railties/test/rails_generator/rails_helper_generator_test.rb (renamed from railties/test/generators/rails_helper_generator_test.rb)0
-rw-r--r--railties/test/rails_generator/rails_mailer_generator_test.rb (renamed from railties/test/generators/rails_mailer_generator_test.rb)0
-rw-r--r--railties/test/rails_generator/rails_model_generator_test.rb (renamed from railties/test/generators/rails_model_generator_test.rb)0
-rw-r--r--railties/test/rails_generator/rails_model_subclass_generator_test.rb (renamed from railties/test/generators/rails_model_subclass_generator_test.rb)0
-rw-r--r--railties/test/rails_generator/rails_resource_generator_test.rb (renamed from railties/test/generators/rails_resource_generator_test.rb)0
-rw-r--r--railties/test/rails_generator/rails_scaffold_generator_test.rb (renamed from railties/test/generators/rails_scaffold_generator_test.rb)0
-rw-r--r--railties/test/secret_key_generation_test.rb38
109 files changed, 1623 insertions, 1281 deletions
diff --git a/railties/bin/gen b/railties/bin/gen
new file mode 100755
index 0000000000..ad3a793610
--- /dev/null
+++ b/railties/bin/gen
@@ -0,0 +1,31 @@
+require File.dirname(__FILE__) + '/../lib/ruby_version_check'
+Signal.trap("INT") { puts; exit }
+
+require File.dirname(__FILE__) + '/../lib/rails/version'
+if %w(--version -v).include? ARGV.first
+ puts "Rails #{Rails::VERSION::STRING}"
+ exit(0)
+end
+
+if ARGV.size == 0
+ puts "Please select a generator. Options: foo, bar"
+ return
+else ARGV.size == 1
+ ARGV << "--help"
+end
+
+require File.dirname(__FILE__) + '/../lib/generators'
+
+Rails::Generators.builtin.each do |group, name|
+ require "generators/#{group}/#{name}/#{name}_generator"
+end
+
+name = ARGV.shift
+
+if klass = Thor::Util.find_by_namespace("rails:#{name}")
+ klass.start
+elsif klass = Thor::Util.find_by_namespace(name)
+ klass.start
+else
+ puts "Could not find generator #{name}."
+end
diff --git a/railties/bin/rails b/railties/bin/rails
index 6a0c675206..538d0cbc84 100755
--- a/railties/bin/rails
+++ b/railties/bin/rails
@@ -7,14 +7,9 @@ if %w(--version -v).include? ARGV.first
exit(0)
end
-freeze = ARGV.any? { |option| %w(--freeze -f).include?(option) }
+ARGV << "--help" if ARGV.empty?
-app_path = ARGV.first
+require File.dirname(__FILE__) + '/../lib/generators'
+require 'generators/rails/app/app_generator'
-require File.dirname(__FILE__) + '/../lib/rails_generator'
-
-require 'rails_generator/scripts/generate'
-Rails::Generator::Base.use_application_sources!
-Rails::Generator::Scripts::Generate.new.run(ARGV, :generator => 'app')
-
-Dir.chdir(app_path) { `rake rails:freeze:gems`; puts "froze" } if freeze \ No newline at end of file
+Rails::Generators::AppGenerator.start
diff --git a/railties/lib/generators.rb b/railties/lib/generators.rb
new file mode 100644
index 0000000000..4743409f0c
--- /dev/null
+++ b/railties/lib/generators.rb
@@ -0,0 +1,26 @@
+activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
+$:.unshift(activesupport_path) if File.directory?(activesupport_path)
+require 'active_support/all'
+
+# TODO Use vendored Thor
+require 'rubygems'
+gem 'josevalim-thor'
+require 'thor'
+
+$:.unshift(File.dirname(__FILE__))
+require 'rails/version' unless defined?(Rails::VERSION)
+
+require 'generators/base'
+require 'generators/named_base'
+require 'generators/test_unit'
+
+module Rails
+ module Generators
+ def self.builtin
+ Dir[File.dirname(__FILE__) + '/generators/*/*'].collect do |file|
+ file.split('/')[-2, 2]
+ end
+ end
+ end
+end
+
diff --git a/railties/lib/generators/actions.rb b/railties/lib/generators/actions.rb
new file mode 100644
index 0000000000..c905f17f61
--- /dev/null
+++ b/railties/lib/generators/actions.rb
@@ -0,0 +1,284 @@
+require 'open-uri'
+
+module Rails
+ module Generators
+ module Actions
+
+ # Loads an external file and execute it in the instance binding.
+ #
+ # ==== Parameters
+ # path<String>:: The path to the file to execute. Can be a web address or
+ # a relative path from the source root.
+ #
+ # ==== Examples
+ #
+ # apply "http://gist.github.com/103208"
+ #
+ # apply "recipes/jquery.rb"
+ #
+ def apply(path, log_status=true)
+ path = File.expand_path(path, source_root) unless path =~ /^http\:\/\//
+
+ log :apply, path, log_status
+ instance_eval(open(path).read)
+ log :applied, path, log_status
+ end
+
+ # Install a plugin. You must provide either a Subversion url or Git url.
+ # For a Git-hosted plugin, you can specify if it should be added as a submodule instead of cloned.
+ #
+ # ==== Examples
+ #
+ # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git'
+ # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git', :submodule => true
+ # plugin 'restful-authentication', :svn => 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
+ #
+ def plugin(name, options)
+ log :plugin, name
+
+ if options[:git] && options[:submodule]
+ in_root do
+ run "git submodule add #{options[:git]} vendor/plugins/#{name}", false
+ end
+ elsif options[:git] || options[:svn]
+ in_root do
+ run_ruby_script "script/plugin install #{options[:svn] || options[:git]}", false
+ end
+ else
+ log "! no git or svn provided for #{name}. Skipping..."
+ end
+ end
+
+ # Adds an entry into config/environment.rb for the supplied gem. If env
+ # is specified, add the gem to the given environment.
+ #
+ # ==== Example
+ #
+ # gem "rspec", :env => :test
+ # gem "technoweenie-restful-authentication", :lib => "restful-authentication", :source => "http://gems.github.com/"
+ #
+ def gem(name, options = {})
+ log :gem, name
+ env = options.delete(:env)
+
+ gems_code = "config.gem '#{name}'"
+
+ if options.any?
+ opts = options.inject([]) {|result, h| result << [":#{h[0]} => #{h[1].inspect.gsub('"',"'")}"] }.sort.join(", ")
+ gems_code << ", #{opts}"
+ end
+
+ environment gems_code, :env => env
+ end
+
+ # Adds a line inside the Initializer block for config/environment.rb.
+ #
+ # If options :env is specified, the line is appended to the corresponding
+ # file in config/environments.
+ #
+ def environment(data=nil, options={}, &block)
+ sentinel = 'Rails::Initializer.run do |config|'
+
+ data = block.call if !data && block_given?
+
+ in_root do
+ if options[:env].nil?
+ gsub_file 'config/environment.rb', /(#{Regexp.escape(sentinel)})/mi, false do |match|
+ "#{match}\n " << data
+ end
+ else
+ Array.wrap(options[:env]).each do|env|
+ append_file "config/environments/#{env}.rb", "\n#{data}", false
+ end
+ 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 = {})
+ in_root do
+ if command.is_a?(Symbol)
+ run "git #{command}"
+ else
+ command.each do |command, options|
+ run "git #{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)
+ log :vendor, filename
+ create_file("vendor/#{filename}", data, false, &block)
+ 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, &block)
+ log :lib, filename
+ create_file("lib/#{filename}", data, false, &block)
+ 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)
+ log :rakefile, filename
+ create_file("lib/tasks/#{filename}", data, false, &block)
+ 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)
+ log :initializer, filename
+ create_file("config/initializers/#{filename}", data, false, &block)
+ 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)
+ log :generate, what
+ argument = args.map {|arg| arg.to_s }.flatten.join(" ")
+
+ in_root { run_ruby_script("script/generate #{what} #{argument}", false) }
+ end
+
+ # Runs the supplied rake task
+ #
+ # ==== Example
+ #
+ # rake("db:migrate")
+ # rake("db:migrate", :env => "production")
+ # rake("gems:install", :sudo => true)
+ #
+ def rake(command, options={})
+ log :rake, command
+ env = options[:env] || 'development'
+ sudo = options[:sudo] ? 'sudo ' : ''
+ in_root { run("#{sudo}rake #{command} RAILS_ENV=#{env}", false) }
+ end
+
+ # Just run the capify command in root
+ #
+ # ==== Example
+ #
+ # capify!
+ #
+ def capify!
+ log :capify, ""
+ in_root { run('capify .', false) }
+ end
+
+ # Add Rails to /vendor/rails
+ #
+ # ==== Example
+ #
+ # freeze!
+ #
+ def freeze!(args = {})
+ log :vendor, "rails"
+ in_root { run('rake rails:freeze:edge', false) }
+ end
+
+ # Make an entry in Rails routing file conifg/routes.rb
+ #
+ # === Example
+ #
+ # route "map.root :controller => :welcome"
+ #
+ def route(routing_code)
+ log :route, routing_code
+ sentinel = 'ActionController::Routing::Routes.draw do |map|'
+
+ in_root do
+ gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi, false do |match|
+ "#{match}\n #{routing_code}\n"
+ end
+ end
+ end
+
+ protected
+
+ # Define file as an alias to create_file for backwards compatibility.
+ #
+ def file(*args, &block)
+ create_file(*args, &block)
+ end
+
+ # Define log for backwards compatibility. If just one argument is sent,
+ # invoke say, otherwise invoke say_status.
+ #
+ def log(*args)
+ if args.size == 1
+ say args.first.to_s
+ else
+ say_status *args
+ end
+ end
+
+ end
+ end
+end
diff --git a/railties/lib/generators/base.rb b/railties/lib/generators/base.rb
new file mode 100644
index 0000000000..b530713805
--- /dev/null
+++ b/railties/lib/generators/base.rb
@@ -0,0 +1,93 @@
+require 'generators/actions'
+
+module Rails
+ module Generators
+ class Error < Thor::Error
+ end
+
+ class Base < Thor::Group
+ include Rails::Generators::Actions
+ include Thor::Actions
+
+ # Automatically sets the source root based on the class name.
+ #
+ def self.source_root
+ @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), base_name, generator_name, 'templates'))
+ end
+
+ # Convenience method to get the namespace from the class name.
+ #
+ def self.namespace(name=nil)
+ if name
+ super
+ else
+ @namespace ||= "#{base_name}:#{generator_name}"
+ end
+ end
+
+ protected
+
+ # Use Rails default banner.
+ #
+ def self.banner
+ "#{$0} #{generator_name} #{self.arguments.map(&:usage).join(' ')} [options]"
+ end
+
+ # Sets the base_name. Overwriten by test unit generators.
+ #
+ def self.base_name
+ 'rails'
+ end
+
+ # Removes the namespaces and get the generator name. For example,
+ # Rails::Generators::MetalGenerator will return "metal" as generator name.
+ #
+ # The name is used to set the namespace (in this case "rails:metal")
+ # and to set the source root ("rails/metal/templates").
+ #
+ def self.generator_name
+ @generator_name ||= begin
+ klass_name = self.name.split('::').last
+ klass_name.gsub!(/Generator$/, '')
+ klass_name.underscore
+ end
+ end
+
+ # Small macro to add ruby as an option to the generator with proper
+ # default value plus an instance helper method called shebang.
+ #
+ def self.add_shebang_option!
+ require 'rbconfig'
+ default = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
+
+ class_option :ruby, :type => :string, :aliases => "-r", :default => default,
+ :desc => "Path to the Ruby binary of your choice"
+
+ no_tasks do
+ define_method :shebang do
+ "#!#{options[:ruby] || "/usr/bin/env ruby"}"
+ end
+ end
+ end
+
+ # Small macro to add test_framework option and invoke it.
+ #
+ def self.add_test_framework_option!
+ # TODO Reduce the example name
+ class_option :test_framework, :type => :string, :aliases => "-t", :default => "test_unit",
+ :desc => "Test framework to be invoked by this generator"
+
+ define_method :invoke_test_framework do
+ return unless options[:test_framework]
+ name = "#{options[:test_framework]}:#{self.class.generator_name}"
+
+ begin
+ invoke name
+ rescue Thor::UndefinedTaskError # TODO Ensure this message is called.
+ say "Could not find and/or invoke #{name}."
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/generated_attribute.rb b/railties/lib/generators/generated_attribute.rb
new file mode 100644
index 0000000000..0ead945281
--- /dev/null
+++ b/railties/lib/generators/generated_attribute.rb
@@ -0,0 +1,44 @@
+module Rails
+ module Generators
+ class GeneratedAttribute
+ attr_accessor :name, :type, :column
+
+ def initialize(name, type)
+ @name, @type = name, type.to_sym
+ @column = ActiveRecord::ConnectionAdapters::Column.new(@name, nil, @type)
+ end
+
+ def field_type
+ @field_type ||= case type
+ when :integer, :float, :decimal then :text_field
+ when :datetime, :timestamp, :time then :datetime_select
+ when :date then :date_select
+ when :string then :text_field
+ when :text then :text_area
+ when :boolean then :check_box
+ else
+ :text_field
+ end
+ end
+
+ def default
+ @default ||= case type
+ when :integer then 1
+ when :float then 1.5
+ when :decimal then "9.99"
+ when :datetime, :timestamp, :time then Time.now.to_s(:db)
+ when :date then Date.today.to_s(:db)
+ when :string then "MyString"
+ when :text then "MyText"
+ when :boolean then false
+ else
+ ""
+ end
+ end
+
+ def reference?
+ [ :references, :belongs_to ].include?(self.type)
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/named_base.rb b/railties/lib/generators/named_base.rb
new file mode 100644
index 0000000000..223b34ce57
--- /dev/null
+++ b/railties/lib/generators/named_base.rb
@@ -0,0 +1,74 @@
+require 'generators/base'
+require 'generators/generated_attribute'
+
+module Rails
+ module Generators
+ class NamedBase < Base
+ argument :name, :type => :string
+
+ attr_reader :class_name, :singular_name, :plural_name, :table_name,
+ :class_path, :file_path, :class_nesting, :class_nesting_depth
+
+ alias :file_name :singular_name
+
+ def initialize(*args)
+ super
+ assign_names!
+ parse_attributes! if respond_to?(:attributes)
+ end
+
+ protected
+
+ def assign_names!
+ base_name, @class_path, @file_path, @class_nesting, @class_nesting_depth = extract_modules(name)
+ @class_name_without_nesting, @singular_name, @plural_name = inflect_names(base_name)
+
+ @table_name = if !defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names
+ plural_name
+ else
+ singular_name
+ end
+ @table_name.gsub! '/', '_'
+
+ if @class_nesting.empty?
+ @class_name = @class_name_without_nesting
+ else
+ @table_name = @class_nesting.underscore << "_" << @table_name
+ @class_name = "#{@class_nesting}::#{@class_name_without_nesting}"
+ end
+ end
+
+ # Convert attributes hash into an array with GeneratedAttribute objects.
+ #
+ def parse_attributes!
+ attributes.map! do |name, type|
+ Rails::Generator::GeneratedAttribute.new(name, type)
+ end
+ end
+
+ # Extract modules from filesystem-style or ruby-style path. Both
+ # good/fun/stuff and Good::Fun::Stuff produce the same results.
+ #
+ def extract_modules(name)
+ modules = name.include?('/') ? name.split('/') : name.split('::')
+ name = modules.pop
+ path = modules.map { |m| m.underscore }
+
+ file_path = (path + [name.underscore]).join('/')
+ nesting = modules.map { |m| m.camelize }.join('::')
+
+ [name, path, file_path, nesting, modules.size]
+ end
+
+ # Receives name and return camelized, underscored and pluralized names.
+ #
+ def inflect_names(name)
+ camel = name.camelize
+ under = camel.underscore
+ plural = under.pluralize
+ [camel, under, plural]
+ end
+
+ end
+ end
+end
diff --git a/railties/lib/rails_generator/generators/applications/app/USAGE b/railties/lib/generators/rails/app/USAGE
index 36d6061a59..36d6061a59 100644
--- a/railties/lib/rails_generator/generators/applications/app/USAGE
+++ b/railties/lib/generators/rails/app/USAGE
diff --git a/railties/lib/generators/rails/app/app_generator.rb b/railties/lib/generators/rails/app/app_generator.rb
new file mode 100644
index 0000000000..45e46aed02
--- /dev/null
+++ b/railties/lib/generators/rails/app/app_generator.rb
@@ -0,0 +1,200 @@
+require 'digest/md5'
+require 'active_support/secure_random'
+
+module Rails::Generators
+ class AppGenerator < Base
+ DATABASES = %w( mysql oracle postgresql sqlite2 sqlite3 frontbase ibm_db )
+ add_shebang_option!
+
+ argument :app_path, :type => :string
+
+ class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
+ :desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
+
+ class_option :freeze, :type => :boolean, :aliases => "-F", :default => false,
+ :desc => "Freeze Rails in vendor/rails from the gems"
+
+ class_option :template, :type => :string, :aliases => "-m",
+ :desc => "Path to an application template (can be a filesystem path or URL)."
+
+ class_option :with_dispatchers, :type => :boolean, :aliases => "-D", :default => false,
+ :desc => "Add CGI/FastCGI/mod_ruby dispatchers code"
+
+ class_option :skip_activerecord, :type => :boolean, :aliases => "-A", :default => false,
+ :desc => "Skip ActiveRecord files"
+
+ class_option :skip_testunit, :type => :boolean, :aliases => "-U", :default => false,
+ :desc => "Skip TestUnit files"
+
+ class_option :skip_prototype, :type => :boolean, :aliases => "-P", :default => false,
+ :desc => "Skip Prototype files"
+
+ # Add Rails options
+ #
+ class_option :version, :type => :boolean, :aliases => "-v", :group => :rails,
+ :desc => "Show Rails version number and quit"
+
+ class_option :help, :type => :boolean, :aliases => "-h", :group => :rails,
+ :desc => "Show this help message and quit"
+
+ def initialize(*args)
+ super
+ if !options[:no_activerecord] && !DATABASES.include?(options[:database])
+ raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
+ end
+ end
+
+ def create_root
+ self.root = File.expand_path(app_path, root)
+ empty_directory '.'
+
+ app_name # Sets the app name
+ FileUtils.cd(root)
+ end
+
+ def create_root_files
+ copy_file "Rakefile"
+ copy_file "README"
+ end
+
+ def create_app_files
+ directory "app"
+ end
+
+ def create_config_files
+ empty_directory "config"
+
+ inside "config" do
+ copy_file "boot.rb"
+ copy_file "routes.rb"
+ template "environment.rb"
+
+ directory "environments"
+ directory "initializers"
+ directory "locales"
+ end
+ end
+
+ def create_activerecord_files
+ return if options[:skip_activerecord]
+ template "config/databases/#{options[:database]}.yml", "config/database.yml"
+ end
+
+ def create_db_files
+ directory "db"
+ end
+
+ def create_doc_files
+ directory "doc"
+ end
+
+ def create_lib_files
+ empty_directory "lib"
+ empty_directory "lib/tasks"
+ end
+
+ def create_log_files
+ empty_directory "log"
+
+ inside "log" do
+ %w( server production development test ).each do |file|
+ create_file "#{file}.log"
+ chmod "#{file}.log", 0666, false
+ end
+ end
+ end
+
+ def create_public_files
+ directory "public", "public", false # Non-recursive. Do small steps, so anyone can overwrite it.
+ end
+
+ def create_dispatch_files
+ return unless options[:with_dispatchers]
+ copy_file "dispatchers/config.ru", "config.ru"
+
+ template "dispatchers/dispatch.rb", "public/dispatch.rb"
+ chmod "public/dispatch.rb", 0755, false
+
+ template "dispatchers/dispatch.rb", "public/dispatch.cgi"
+ chmod "public/dispatch.cgi", 0755, false
+
+ template "dispatchers/dispatch.fcgi", "public/dispatch.fcgi"
+ chmod "public/dispatch.fcgi", 0755, false
+ end
+
+ def create_public_image_files
+ directory "public/images"
+ end
+
+ def create_public_stylesheets_files
+ directory "public/stylesheets"
+ end
+
+ def create_prototype_files
+ return if options[:skip_prototype]
+ directory "public/javascripts"
+ end
+
+ def create_script_files
+ directory "script"
+ chmod "script", 0755, false
+ end
+
+ def create_test_files
+ return if options[:skip_testunit]
+ directory "test"
+ end
+
+ def create_tmp_files
+ empty_directory "tmp"
+
+ inside "tmp" do
+ %w(sessions sockets cache pids).each do |dir|
+ empty_directory dir
+ end
+ end
+ end
+
+ def create_vendor_files
+ empty_directory "vendor/plugins"
+ end
+
+ def apply_rails_template
+ apply options[:template] if options[:template]
+ rescue LoadError, Errno::ENOENT => e
+ raise Error, "The template [#{options[:template]}] could not be loaded. Error: #{e}"
+ end
+
+ def freeze?
+ freeze! if options[:freeze]
+ end
+
+ protected
+
+ def app_name
+ @app_name ||= File.basename(root)
+ end
+
+ def app_secret
+ ActiveSupport::SecureRandom.hex(64)
+ end
+
+ def self.banner
+ "#{$0} #{self.arguments.map(&:usage).join(' ')} [options]"
+ end
+
+ def mysql_socket
+ @mysql_socket ||= [
+ "/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
+end
diff --git a/railties/README b/railties/lib/generators/rails/app/templates/README
index 37ec8ea211..37ec8ea211 100644
--- a/railties/README
+++ b/railties/lib/generators/rails/app/templates/README
diff --git a/railties/fresh_rakefile b/railties/lib/generators/rails/app/templates/Rakefile
index 3bb0e8592a..3bb0e8592a 100755
--- a/railties/fresh_rakefile
+++ b/railties/lib/generators/rails/app/templates/Rakefile
diff --git a/railties/helpers/application_controller.rb b/railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb
index 6635a3f487..6635a3f487 100644
--- a/railties/helpers/application_controller.rb
+++ b/railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb
diff --git a/railties/helpers/application_helper.rb b/railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb
index 22a7940eb2..22a7940eb2 100644
--- a/railties/helpers/application_helper.rb
+++ b/railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb
diff --git a/railties/configs/empty.log b/railties/lib/generators/rails/app/templates/app/models/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/configs/empty.log
+++ b/railties/lib/generators/rails/app/templates/app/models/.empty_directory
diff --git a/railties/html/favicon.ico b/railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/html/favicon.ico
+++ b/railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory
diff --git a/railties/environments/boot.rb b/railties/lib/generators/rails/app/templates/config/boot.rb
index 0ad0f787f8..0ad0f787f8 100644
--- a/railties/environments/boot.rb
+++ b/railties/lib/generators/rails/app/templates/config/boot.rb
diff --git a/railties/configs/databases/frontbase.yml b/railties/lib/generators/rails/app/templates/config/databases/frontbase.yml
index c0c3588be1..c0c3588be1 100644
--- a/railties/configs/databases/frontbase.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/frontbase.yml
diff --git a/railties/configs/databases/ibm_db.yml b/railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml
index a9716ddb44..a9716ddb44 100644
--- a/railties/configs/databases/ibm_db.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml
diff --git a/railties/configs/databases/mysql.yml b/railties/lib/generators/rails/app/templates/config/databases/mysql.yml
index 1a14bfb332..6bf2f7b1fd 100644
--- a/railties/configs/databases/mysql.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/mysql.yml
@@ -22,8 +22,8 @@ development:
pool: 5
username: root
password:
-<% if socket -%>
- socket: <%= socket %>
+<% if mysql_socket -%>
+ socket: <%= mysql_socket %>
<% else -%>
host: localhost
<% end -%>
@@ -39,8 +39,8 @@ test:
pool: 5
username: root
password:
-<% if socket -%>
- socket: <%= socket %>
+<% if mysql_socket -%>
+ socket: <%= mysql_socket %>
<% else -%>
host: localhost
<% end -%>
@@ -53,8 +53,8 @@ production:
pool: 5
username: root
password:
-<% if socket -%>
- socket: <%= socket %>
+<% if mysql_socket -%>
+ socket: <%= mysql_socket %>
<% else -%>
host: localhost
<% end -%>
diff --git a/railties/configs/databases/oracle.yml b/railties/lib/generators/rails/app/templates/config/databases/oracle.yml
index a1883f6256..a1883f6256 100644
--- a/railties/configs/databases/oracle.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/oracle.yml
diff --git a/railties/configs/databases/postgresql.yml b/railties/lib/generators/rails/app/templates/config/databases/postgresql.yml
index f600e054cf..f600e054cf 100644
--- a/railties/configs/databases/postgresql.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/postgresql.yml
diff --git a/railties/configs/databases/sqlite2.yml b/railties/lib/generators/rails/app/templates/config/databases/sqlite2.yml
index 46f01cb42c..46f01cb42c 100644
--- a/railties/configs/databases/sqlite2.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/sqlite2.yml
diff --git a/railties/configs/databases/sqlite3.yml b/railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml
index 025d62a8d8..025d62a8d8 100644
--- a/railties/configs/databases/sqlite3.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml
diff --git a/railties/environments/environment.rb b/railties/lib/generators/rails/app/templates/config/environment.rb
index 4a2df36307..d1080cb529 100644
--- a/railties/environments/environment.rb
+++ b/railties/lib/generators/rails/app/templates/config/environment.rb
@@ -1,7 +1,7 @@
# Be sure to restart your server when you modify this file
# 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
+<%= '# ' if options[:freeze] %>RAILS_GEM_VERSION = '<%= Rails::VERSION::STRING %>' unless defined? RAILS_GEM_VERSION
# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')
@@ -26,10 +26,14 @@ Rails::Initializer.run do |config|
# Skip frameworks you're not going to use. To use Rails without a database,
# you must remove the Active Record framework.
+<%- if options[:skip_activerecord] -%>
+ config.frameworks -= [ :active_record ]
+<%- else -%>
# config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
# Activate observers that should always be running
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
+<%- end -%>
# 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.
@@ -38,4 +42,4 @@ Rails::Initializer.run do |config|
# 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
-end \ No newline at end of file
+end
diff --git a/railties/environments/development.rb b/railties/lib/generators/rails/app/templates/config/environments/development.rb
index 85c9a6080e..85c9a6080e 100644
--- a/railties/environments/development.rb
+++ b/railties/lib/generators/rails/app/templates/config/environments/development.rb
diff --git a/railties/environments/production.rb b/railties/lib/generators/rails/app/templates/config/environments/production.rb
index 1fc9f6b923..1fc9f6b923 100644
--- a/railties/environments/production.rb
+++ b/railties/lib/generators/rails/app/templates/config/environments/production.rb
diff --git a/railties/environments/test.rb b/railties/lib/generators/rails/app/templates/config/environments/test.rb
index 496eb9572b..496eb9572b 100644
--- a/railties/environments/test.rb
+++ b/railties/lib/generators/rails/app/templates/config/environments/test.rb
diff --git a/railties/configs/initializers/backtrace_silencers.rb b/railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb
index 839d4cde19..839d4cde19 100644
--- a/railties/configs/initializers/backtrace_silencers.rb
+++ b/railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb
diff --git a/railties/configs/initializers/inflections.rb b/railties/lib/generators/rails/app/templates/config/initializers/inflections.rb
index d531b8bb82..d531b8bb82 100644
--- a/railties/configs/initializers/inflections.rb
+++ b/railties/lib/generators/rails/app/templates/config/initializers/inflections.rb
diff --git a/railties/configs/initializers/mime_types.rb b/railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb
index 72aca7e441..72aca7e441 100644
--- a/railties/configs/initializers/mime_types.rb
+++ b/railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb
diff --git a/railties/configs/initializers/new_rails_defaults.rb b/railties/lib/generators/rails/app/templates/config/initializers/new_rails_defaults.rb
index 8ec3186c84..8ec3186c84 100644
--- a/railties/configs/initializers/new_rails_defaults.rb
+++ b/railties/lib/generators/rails/app/templates/config/initializers/new_rails_defaults.rb
diff --git a/railties/configs/initializers/session_store.rb b/railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt
index 4499ab84b6..4499ab84b6 100644
--- a/railties/configs/initializers/session_store.rb
+++ b/railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt
diff --git a/railties/configs/locales/en.yml b/railties/lib/generators/rails/app/templates/config/locales/en.yml
index f265c068d8..f265c068d8 100644
--- a/railties/configs/locales/en.yml
+++ b/railties/lib/generators/rails/app/templates/config/locales/en.yml
diff --git a/railties/configs/routes.rb b/railties/lib/generators/rails/app/templates/config/routes.rb
index ea14ce1bfc..ea14ce1bfc 100644
--- a/railties/configs/routes.rb
+++ b/railties/lib/generators/rails/app/templates/config/routes.rb
diff --git a/railties/configs/seeds.rb b/railties/lib/generators/rails/app/templates/db/seeds.rb
index 3174d0cb8a..3174d0cb8a 100644
--- a/railties/configs/seeds.rb
+++ b/railties/lib/generators/rails/app/templates/db/seeds.rb
diff --git a/railties/dispatches/config.ru b/railties/lib/generators/rails/app/templates/dispatchers/config.ru
index acbfe4e9ae..acbfe4e9ae 100644
--- a/railties/dispatches/config.ru
+++ b/railties/lib/generators/rails/app/templates/dispatchers/config.ru
diff --git a/railties/dispatches/dispatch.fcgi b/railties/lib/generators/rails/app/templates/dispatchers/dispatch.fcgi
index 664dbbbee8..f5b3b71875 100755
--- a/railties/dispatches/dispatch.fcgi
+++ b/railties/lib/generators/rails/app/templates/dispatchers/dispatch.fcgi
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+<%= shebang %>
#
# You may specify the path to the FastCGI crash log (a log of unhandled
# exceptions which forced the FastCGI instance to exit, great for debugging)
diff --git a/railties/dispatches/dispatch.rb b/railties/lib/generators/rails/app/templates/dispatchers/dispatch.rb
index 32fa3b2665..48e888113a 100755
--- a/railties/dispatches/dispatch.rb
+++ b/railties/lib/generators/rails/app/templates/dispatchers/dispatch.rb
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
diff --git a/railties/dispatches/gateway.cgi b/railties/lib/generators/rails/app/templates/dispatchers/gateway.cgi
index 0305b7f810..bdc1055a22 100755
--- a/railties/dispatches/gateway.cgi
+++ b/railties/lib/generators/rails/app/templates/dispatchers/gateway.cgi
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require 'drb'
diff --git a/railties/doc/README_FOR_APP b/railties/lib/generators/rails/app/templates/doc/README_FOR_APP
index fe41f5cc24..fe41f5cc24 100644
--- a/railties/doc/README_FOR_APP
+++ b/railties/lib/generators/rails/app/templates/doc/README_FOR_APP
diff --git a/railties/html/404.html b/railties/lib/generators/rails/app/templates/public/404.html
index eff660b90c..eff660b90c 100644
--- a/railties/html/404.html
+++ b/railties/lib/generators/rails/app/templates/public/404.html
diff --git a/railties/html/422.html b/railties/lib/generators/rails/app/templates/public/422.html
index b54e4a3cad..b54e4a3cad 100644
--- a/railties/html/422.html
+++ b/railties/lib/generators/rails/app/templates/public/422.html
diff --git a/railties/html/500.html b/railties/lib/generators/rails/app/templates/public/500.html
index ec3bbf02c4..ec3bbf02c4 100644
--- a/railties/html/500.html
+++ b/railties/lib/generators/rails/app/templates/public/500.html
diff --git a/railties/lib/generators/rails/app/templates/public/favicon.ico b/railties/lib/generators/rails/app/templates/public/favicon.ico
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/public/favicon.ico
diff --git a/railties/html/images/rails.png b/railties/lib/generators/rails/app/templates/public/images/rails.png
index d5edc04e65..d5edc04e65 100644
--- a/railties/html/images/rails.png
+++ b/railties/lib/generators/rails/app/templates/public/images/rails.png
Binary files differ
diff --git a/railties/html/index.html b/railties/lib/generators/rails/app/templates/public/index.html
index cd337dc74c..cd337dc74c 100644
--- a/railties/html/index.html
+++ b/railties/lib/generators/rails/app/templates/public/index.html
diff --git a/railties/html/javascripts/application.js b/railties/lib/generators/rails/app/templates/public/javascripts/application.js
index fe4577696b..fe4577696b 100644
--- a/railties/html/javascripts/application.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/application.js
diff --git a/railties/html/javascripts/controls.js b/railties/lib/generators/rails/app/templates/public/javascripts/controls.js
index ca29aefdd1..ca29aefdd1 100644
--- a/railties/html/javascripts/controls.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/controls.js
diff --git a/railties/html/javascripts/dragdrop.js b/railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js
index 07229f986f..07229f986f 100644
--- a/railties/html/javascripts/dragdrop.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js
diff --git a/railties/html/javascripts/effects.js b/railties/lib/generators/rails/app/templates/public/javascripts/effects.js
index 5a639d2dea..5a639d2dea 100644
--- a/railties/html/javascripts/effects.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/effects.js
diff --git a/railties/html/javascripts/prototype.js b/railties/lib/generators/rails/app/templates/public/javascripts/prototype.js
index dfe8ab4e13..dfe8ab4e13 100644
--- a/railties/html/javascripts/prototype.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/prototype.js
diff --git a/railties/html/robots.txt b/railties/lib/generators/rails/app/templates/public/robots.txt
index 085187fa58..085187fa58 100644
--- a/railties/html/robots.txt
+++ b/railties/lib/generators/rails/app/templates/public/robots.txt
diff --git a/railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory b/railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory
diff --git a/railties/bin/about b/railties/lib/generators/rails/app/templates/script/about.tt
index ed8deb0dfc..9604485fd2 100755
--- a/railties/bin/about
+++ b/railties/lib/generators/rails/app/templates/script/about.tt
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
$LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info"
-require 'commands/about' \ No newline at end of file
+require 'commands/about'
diff --git a/railties/bin/console b/railties/lib/generators/rails/app/templates/script/console.tt
index 498077ab33..307b7c09c4 100755
--- a/railties/bin/console
+++ b/railties/lib/generators/rails/app/templates/script/console.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/console'
diff --git a/railties/bin/dbconsole b/railties/lib/generators/rails/app/templates/script/dbconsole.tt
index caa60ce829..7ce41645a6 100755
--- a/railties/bin/dbconsole
+++ b/railties/lib/generators/rails/app/templates/script/dbconsole.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/dbconsole'
diff --git a/railties/bin/destroy b/railties/lib/generators/rails/app/templates/script/destroy.tt
index a4df765a39..9f22a9dbca 100755
--- a/railties/bin/destroy
+++ b/railties/lib/generators/rails/app/templates/script/destroy.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/destroy'
diff --git a/railties/bin/generate b/railties/lib/generators/rails/app/templates/script/generate.tt
index 173a9f147d..9a9e17ab29 100755
--- a/railties/bin/generate
+++ b/railties/lib/generators/rails/app/templates/script/generate.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/generate'
diff --git a/railties/bin/performance/benchmarker b/railties/lib/generators/rails/app/templates/script/performance/benchmarker.tt
index c842d35d33..3abf448c15 100755
--- a/railties/bin/performance/benchmarker
+++ b/railties/lib/generators/rails/app/templates/script/performance/benchmarker.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../../config/boot'
require 'commands/performance/benchmarker'
diff --git a/railties/bin/performance/profiler b/railties/lib/generators/rails/app/templates/script/performance/profiler.tt
index d855ac8b13..66f851a079 100755
--- a/railties/bin/performance/profiler
+++ b/railties/lib/generators/rails/app/templates/script/performance/profiler.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../../config/boot'
require 'commands/performance/profiler'
diff --git a/railties/bin/plugin b/railties/lib/generators/rails/app/templates/script/plugin.tt
index 87cd2070fe..f0603c33c4 100755
--- a/railties/bin/plugin
+++ b/railties/lib/generators/rails/app/templates/script/plugin.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/plugin'
diff --git a/railties/bin/runner b/railties/lib/generators/rails/app/templates/script/runner.tt
index a4a7cb25ba..7302825f6c 100755
--- a/railties/bin/runner
+++ b/railties/lib/generators/rails/app/templates/script/runner.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/runner'
diff --git a/railties/bin/server b/railties/lib/generators/rails/app/templates/script/server.tt
index 3c67f39b69..893db31a20 100755
--- a/railties/bin/server
+++ b/railties/lib/generators/rails/app/templates/script/server.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/server'
diff --git a/railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory b/railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory
diff --git a/railties/lib/generators/rails/app/templates/test/functional/.empty_directory b/railties/lib/generators/rails/app/templates/test/functional/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/test/functional/.empty_directory
diff --git a/railties/lib/generators/rails/app/templates/test/integration/.empty_directory b/railties/lib/generators/rails/app/templates/test/integration/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/test/integration/.empty_directory
diff --git a/railties/helpers/performance_test.rb b/railties/lib/generators/rails/app/templates/test/performance/performance_test.rb
index 4b60558b43..4b60558b43 100644
--- a/railties/helpers/performance_test.rb
+++ b/railties/lib/generators/rails/app/templates/test/performance/performance_test.rb
diff --git a/railties/helpers/test_helper.rb b/railties/lib/generators/rails/app/templates/test/test_helper.rb
index b9fe2517c8..b9fe2517c8 100644
--- a/railties/helpers/test_helper.rb
+++ b/railties/lib/generators/rails/app/templates/test/test_helper.rb
diff --git a/railties/lib/generators/rails/app/templates/test/unit/.empty_directory b/railties/lib/generators/rails/app/templates/test/unit/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/test/unit/.empty_directory
diff --git a/railties/lib/generators/rails/metal/USAGE b/railties/lib/generators/rails/metal/USAGE
new file mode 100644
index 0000000000..123ec6c03f
--- /dev/null
+++ b/railties/lib/generators/rails/metal/USAGE
@@ -0,0 +1,8 @@
+Description:
+ Cast some metal!
+
+Examples:
+ `./script/generate metal poller`
+
+ This will create:
+ Metal: app/metal/poller.rb
diff --git a/railties/lib/generators/rails/metal/metal_generator.rb b/railties/lib/generators/rails/metal/metal_generator.rb
new file mode 100644
index 0000000000..ba062b30be
--- /dev/null
+++ b/railties/lib/generators/rails/metal/metal_generator.rb
@@ -0,0 +1,7 @@
+module Rails::Generators
+ class MetalGenerator < NamedBase
+ def create_file
+ template "metal.rb", "app/metal/#{file_name}.rb"
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/metal/templates/metal.rb b/railties/lib/generators/rails/metal/templates/metal.rb
new file mode 100644
index 0000000000..e94982b69a
--- /dev/null
+++ b/railties/lib/generators/rails/metal/templates/metal.rb
@@ -0,0 +1,12 @@
+# Allow the metal piece to run in isolation
+require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
+
+class <%= class_name %>
+ def self.call(env)
+ if env["PATH_INFO"] =~ /^\/<%= file_name %>/
+ [200, {"Content-Type" => "text/html"}, ["Hello, World!"]]
+ else
+ [404, {"Content-Type" => "text/html"}, ["Not Found"]]
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/plugin/USAGE b/railties/lib/generators/rails/plugin/USAGE
new file mode 100644
index 0000000000..8a17fa4dec
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/USAGE
@@ -0,0 +1,13 @@
+Description:
+ Stubs out a new plugin at vendor/plugins. Pass the plugin name, either
+ CamelCased or under_scored, as an argument.
+
+Example:
+ `./script/generate plugin BrowserFilters`
+
+ creates a standard browser_filters plugin:
+ vendor/plugins/browser_filters/README
+ vendor/plugins/browser_filters/init.rb
+ vendor/plugins/browser_filters/install.rb
+ vendor/plugins/browser_filters/lib/browser_filters.rb
+ vendor/plugins/browser_filters/test/browser_filters_test.rb
diff --git a/railties/lib/generators/rails/plugin/plugin_generator.rb b/railties/lib/generators/rails/plugin/plugin_generator.rb
new file mode 100644
index 0000000000..38afb3984e
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/plugin_generator.rb
@@ -0,0 +1,41 @@
+module Rails
+ module Generators
+ class PluginGenerator < NamedBase
+ def create_root
+ self.root = File.expand_path("vendor/plugins/#{file_name}", root)
+ empty_directory '.'
+ FileUtils.cd(root)
+ end
+
+ # TODO Check class collision
+
+ def create_root_files
+ %w(README MIT-LICENSE Rakefile init.rb install.rb uninstall.rb).each do |file|
+ template file
+ end
+ end
+
+ def create_lib_files
+ directory 'lib'
+ end
+
+ add_test_framework_option!
+
+ class_option :with_tasks, :type => :boolean, :aliases => "-r", :default => false,
+ :desc => "When supplied creates tasks base files."
+
+ class_option :with_generator, :type => :boolean, :aliases => "-g", :default => false,
+ :desc => "When supplied creates generator base files."
+
+ def create_tasks_files
+ return unless options[:with_tasks]
+ directory 'tasks'
+ end
+
+ def create_generator_files
+ return unless options[:with_generator]
+ directory 'generators'
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/plugin/templates/MIT-LICENSE b/railties/lib/generators/rails/plugin/templates/MIT-LICENSE
new file mode 100644
index 0000000000..8717df053d
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) <%= Date.today.year %> [name of plugin creator]
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/railties/lib/generators/rails/plugin/templates/README b/railties/lib/generators/rails/plugin/templates/README
new file mode 100644
index 0000000000..702db07cb1
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/README
@@ -0,0 +1,13 @@
+<%= class_name %>
+<%= "=" * class_name.size %>
+
+Introduction goes here.
+
+
+Example
+=======
+
+Example goes here.
+
+
+Copyright (c) <%= Date.today.year %> [name of plugin creator], released under the MIT license
diff --git a/railties/lib/generators/rails/plugin/templates/Rakefile b/railties/lib/generators/rails/plugin/templates/Rakefile
new file mode 100644
index 0000000000..85e8ff1834
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/Rakefile
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the <%= file_name %> plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the <%= file_name %> plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = '<%= class_name %>'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
diff --git a/railties/lib/generators/rails/plugin/templates/generators/%file_name%/%file_name%_generator.rb.tt b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/%file_name%_generator.rb.tt
new file mode 100644
index 0000000000..90aa557eeb
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/%file_name%_generator.rb.tt
@@ -0,0 +1,2 @@
+class <%= class_name %>Generator < Rails::Generators::NamedBase
+end
diff --git a/railties/lib/generators/rails/plugin/templates/generators/%file_name%/USAGE.tt b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/USAGE.tt
new file mode 100644
index 0000000000..ea9f4f12cc
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/USAGE.tt
@@ -0,0 +1,8 @@
+Description:
+ Explain the generator
+
+Example:
+ ./script/generate <%= file_name %> Thing
+
+ This will create:
+ what/will/it/create
diff --git a/railties/lib/generators/rails/plugin/templates/generators/%file_name%/templates/.empty_directory b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/templates/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/templates/.empty_directory
diff --git a/railties/lib/generators/rails/plugin/templates/init.rb b/railties/lib/generators/rails/plugin/templates/init.rb
new file mode 100644
index 0000000000..3c19a743c9
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/init.rb
@@ -0,0 +1 @@
+# Include hook code here
diff --git a/railties/lib/generators/rails/plugin/templates/install.rb b/railties/lib/generators/rails/plugin/templates/install.rb
new file mode 100644
index 0000000000..f7732d3796
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/install.rb
@@ -0,0 +1 @@
+# Install hook code here
diff --git a/railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt b/railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt
new file mode 100644
index 0000000000..d8d908a959
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt
@@ -0,0 +1 @@
+# <%= class_name %>
diff --git a/railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt b/railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt
new file mode 100644
index 0000000000..72920a9d3a
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :<%= file_name %> do
+# # Task goes here
+# end
diff --git a/railties/lib/generators/rails/plugin/templates/uninstall.rb b/railties/lib/generators/rails/plugin/templates/uninstall.rb
new file mode 100644
index 0000000000..9738333463
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/uninstall.rb
@@ -0,0 +1 @@
+# Uninstall hook code here
diff --git a/railties/lib/generators/test_unit.rb b/railties/lib/generators/test_unit.rb
new file mode 100644
index 0000000000..ecf4c546ed
--- /dev/null
+++ b/railties/lib/generators/test_unit.rb
@@ -0,0 +1,12 @@
+require 'generators/named_base'
+
+module TestUnit
+ module Generators
+ class Base < Rails::Generators::NamedBase
+ protected
+ def self.base_name
+ 'test_unit'
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/test_unit/plugin/plugin_generator.rb b/railties/lib/generators/test_unit/plugin/plugin_generator.rb
new file mode 100644
index 0000000000..1c987ab1c9
--- /dev/null
+++ b/railties/lib/generators/test_unit/plugin/plugin_generator.rb
@@ -0,0 +1,14 @@
+module TestUnit
+ module Generators
+ class PluginGenerator < Base
+ desc <<DESC
+Description:
+ Create TestUnit files for plugin generator.
+DESC
+
+ def create_test_files
+ directory 'test'
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/test_unit/plugin/templates/test/%file_name%_test.rb b/railties/lib/generators/test_unit/plugin/templates/test/%file_name%_test.rb
new file mode 100644
index 0000000000..3e0bc29d3a
--- /dev/null
+++ b/railties/lib/generators/test_unit/plugin/templates/test/%file_name%_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class <%= class_name %>Test < ActiveSupport::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
diff --git a/railties/lib/generators/test_unit/plugin/templates/test/test_helper.rb b/railties/lib/generators/test_unit/plugin/templates/test/test_helper.rb
new file mode 100644
index 0000000000..cf148b8b47
--- /dev/null
+++ b/railties/lib/generators/test_unit/plugin/templates/test/test_helper.rb
@@ -0,0 +1,3 @@
+require 'rubygems'
+require 'active_support'
+require 'active_support/test_case' \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/applications/app/app_generator.rb b/railties/lib/rails_generator/generators/applications/app/app_generator.rb
deleted file mode 100644
index c8c2239f34..0000000000
--- a/railties/lib/rails_generator/generators/applications/app/app_generator.rb
+++ /dev/null
@@ -1,263 +0,0 @@
-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'])
-
- 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
-
-
- 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
- record do |m|
- 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
-
- def after_generate
- if options[:template]
- Rails::TemplateRunner.new(options[:template], @destination_root)
- end
- end
-
- protected
- def banner
- "Usage: #{$0} /path/to/your/app [options]"
- end
-
- def add_options!(opt)
- opt.separator ''
- opt.separator 'Options:'
- opt.on("-r", "--ruby=path", String,
- "Path to the Ruby binary of your choice (otherwise scripts use env, dispatchers current path).",
- "Default: #{DEFAULT_SHEBANG}") { |v| options[:shebang] = v }
-
- opt.on("-d", "--database=name", String,
- "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_seeds_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
- ).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_seeds_file(m)
- m.file "configs/seeds.rb", "db/seeds.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
- [
- "/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
deleted file mode 100644
index 445de6ab42..0000000000
--- a/railties/lib/rails_generator/generators/applications/app/scm/git.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-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
deleted file mode 100644
index f6c08cad39..0000000000
--- a/railties/lib/rails_generator/generators/applications/app/scm/scm.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 22b5966d25..0000000000
--- a/railties/lib/rails_generator/generators/applications/app/scm/svn.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 0e24d11950..0000000000
--- a/railties/lib/rails_generator/generators/applications/app/template_runner.rb
+++ /dev/null
@@ -1,401 +0,0 @@
-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 :root
- attr_writer :logger
-
- def initialize(template, root = '') # :nodoc:
- @root = File.expand_path(File.directory?(root) ? root : File.join(Dir.pwd, root))
-
- log 'applying', "template: #{template}"
-
- load_template(template)
-
- log 'applied', "#{template}"
- end
-
- def load_template(template)
- begin
- code = open(template).read
- in_root { self.instance_eval(code) }
- rescue LoadError, Errno::ENOENT => e
- raise "The template [#{template}] could not be loaded. Error: #{e}"
- 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, log_action = true, &block)
- log 'file', filename if log_action
- 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.
- # For a Git-hosted plugin, you can specify if it should be added as a submodule instead of cloned.
- #
- # ==== Examples
- #
- # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git'
- # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git', :submodule => true
- # plugin 'restful-authentication', :svn => 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
- #
- def plugin(name, options)
- log 'plugin', name
-
- if options[:git] && options[:submodule]
- in_root do
- Git.run("submodule add #{options[:git]} vendor/plugins/#{name}")
- end
- elsif options[:git] || options[:svn]
- in_root do
- run_ruby_script("script/plugin install #{options[:svn] || options[:git]}", false)
- end
- else
- log "! 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 = {})
- log 'gem', name
- env = options.delete(:env)
-
- gems_code = "config.gem '#{name}'"
-
- if options.any?
- opts = options.inject([]) {|result, h| result << [":#{h[0]} => #{h[1].inspect.gsub('"',"'")}"] }.sort.join(", ")
- gems_code << ", #{opts}"
- end
-
- environment gems_code, :env => env
- end
-
- # Adds a line inside the Initializer block for config/environment.rb. Used by #gem
- # If options :env is specified, the line is appended to the corresponding
- # file in config/environments/#{env}.rb
- def environment(data = nil, options = {}, &block)
- sentinel = 'Rails::Initializer.run do |config|'
-
- data = block.call if !data && block_given?
-
- in_root do
- if options[:env].nil?
- gsub_file 'config/environment.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
- "#{match}\n " << data
- end
- else
- Array.wrap(options[:env]).each do|env|
- append_file "config/environments/#{env}.rb", "\n#{data}"
- end
- 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 = {})
- in_root do
- if command.is_a?(Symbol)
- log 'running', "git #{command}"
- Git.run(command.to_s)
- else
- command.each do |command, options|
- log 'running', "git #{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)
- log 'vendoring', filename
- file("vendor/#{filename}", data, false, &block)
- 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, &block)
- log 'lib', filename
- file("lib/#{filename}", data, false, &block)
- 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)
- log 'rakefile', filename
- file("lib/tasks/#{filename}", data, false, &block)
- 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)
- log 'initializer', filename
- file("config/initializers/#{filename}", data, false, &block)
- 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)
- log 'generating', what
- argument = args.map {|arg| arg.to_s }.flatten.join(" ")
-
- in_root { run_ruby_script("script/generate #{what} #{argument}", false) }
- end
-
- # Executes a command
- #
- # ==== Example
- #
- # inside('vendor') do
- # run('ln -s ~/edge rails)
- # end
- #
- def run(command, log_action = true)
- log 'executing', "#{command} from #{Dir.pwd}" if log_action
- `#{command}`
- end
-
- # Executes a ruby script (taking into account WIN32 platform quirks)
- def run_ruby_script(command, log_action = true)
- ruby_command = RUBY_PLATFORM=~ /win32/ ? 'ruby ' : ''
- run("#{ruby_command}#{command}", log_action)
- end
-
- # Runs the supplied rake task
- #
- # ==== Example
- #
- # rake("db:migrate")
- # rake("db:migrate", :env => "production")
- # rake("gems:install", :sudo => true)
- #
- def rake(command, options = {})
- log 'rake', command
- env = options[:env] || 'development'
- sudo = options[:sudo] ? 'sudo ' : ''
- in_root { run("#{sudo}rake #{command} RAILS_ENV=#{env}", false) }
- end
-
- # Just run the capify command in root
- #
- # ==== Example
- #
- # capify!
- #
- def capify!
- log 'capifying'
- in_root { run('capify .', false) }
- end
-
- # Add Rails to /vendor/rails
- #
- # ==== Example
- #
- # freeze!
- #
- def freeze!(args = {})
- log 'vendor', 'rails edge'
- in_root { run('rake rails:freeze:edge', false) }
- end
-
- # Make an entry in Rails routing file conifg/routes.rb
- #
- # === Example
- #
- # route "map.root :controller => :welcome"
- #
- def route(routing_code)
- log '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)
- log '', string
- STDIN.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
-
- # Run a regular expression replacement on a file
- #
- # ==== Example
- #
- # gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'
- #
- 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
-
- # Append text to a file
- #
- # ==== Example
- #
- # append_file 'config/environments/test.rb', 'config.gem "rspec"'
- #
- def append_file(relative_destination, data)
- path = destination_path(relative_destination)
- File.open(path, 'ab') { |file| file.write(data) }
- end
-
- def destination_path(relative_destination)
- File.join(root, relative_destination)
- end
-
- def log(action, message = '')
- logger.log(action, message)
- end
-
- def logger
- @logger ||= Rails::Generator::Base.logger
- end
-
- def logger
- @logger ||= if defined?(Rails::Generator::Base)
- Rails::Generator::Base.logger
- else
- require 'rails_generator/simple_logger'
- Rails::Generator::SimpleLogger.new(STDOUT)
- end
- end
-
- end
-end
diff --git a/railties/lib/rails_generator/secret_key_generator.rb b/railties/lib/rails_generator/secret_key_generator.rb
deleted file mode 100644
index 7dd495a2f5..0000000000
--- a/railties/lib/rails_generator/secret_key_generator.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-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
- # available on the current platform. For example:
- #
- # generator = Rails::SecretKeyGenerator("some unique identifier, such as the application name")
- # generator.generate_secret # => "f3f1be90053fa851... (some long string)"
- #
- # This class is *deprecated* in Rails 2.2 in favor of ActiveSupport::SecureRandom.
- # It is currently a wrapper around ActiveSupport::SecureRandom.
- class SecretKeyGenerator
- def initialize(identifier)
- end
-
- # Generate a random secret key with the best possible method available on
- # the current platform.
- def generate_secret
- ActiveSupport::SecureRandom.hex(64)
- end
- deprecate :generate_secret=>"You should use ActiveSupport::SecureRandom.hex(64)"
- end
-end
diff --git a/railties/test/boot_test.rb b/railties/test/boot_test.rb
index 2dd68857c3..02c7b461f7 100644
--- a/railties/test/boot_test.rb
+++ b/railties/test/boot_test.rb
@@ -1,6 +1,6 @@
require 'abstract_unit'
require 'initializer'
-require "#{File.dirname(__FILE__)}/../environments/boot"
+require "#{File.dirname(__FILE__)}/../lib/generator/templates/app/config/boot"
require 'rails/gem_dependency'
class BootTest < Test::Unit::TestCase
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
new file mode 100644
index 0000000000..6030504fa3
--- /dev/null
+++ b/railties/test/generators/actions_test.rb
@@ -0,0 +1,184 @@
+require 'abstract_unit'
+require 'generators/generator_test_helper'
+
+class ActionsTest < GeneratorTestCase
+ def setup
+ super
+ @git_plugin_uri = 'git://github.com/technoweenie/restful-authentication.git'
+ @svn_plugin_uri = 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
+ end
+
+ def test_apply_loads_and_evaluates_a_template
+ template = <<-TEMPLATE
+ @foo = "FOO"
+ TEMPLATE
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ generator.expects(:open).with("http://gist.github.com/103208.txt").returns(template)
+ action :apply, "http://gist.github.com/103208.txt"
+ assert_equal generator.instance_variable_get("@foo"), "FOO"
+ end
+
+ def test_file_should_write_data_to_file_path
+ action :file, 'lib/test_file.rb', 'heres test data'
+ assert_file 'lib/test_file.rb', 'heres test data'
+ end
+
+ def test_file_should_write_block_contents_to_file_path
+ action(:file, 'lib/test_file.rb'){ 'heres block data' }
+ assert_file 'lib/test_file.rb', 'heres block data'
+ end
+
+ def test_plugin_with_git_option_should_run_plugin_install
+ generator.expects(:run).once.with("ruby script/plugin install #{@git_plugin_uri}", false)
+ action :plugin, 'restful-authentication', :git => @git_plugin_uri
+ end
+
+ def test_plugin_with_svn_option_should_run_plugin_install
+ generator.expects(:run).once.with("ruby script/plugin install #{@svn_plugin_uri}", false)
+ action :plugin, 'restful-authentication', :svn => @svn_plugin_uri
+ end
+
+ def test_plugin_with_git_option_and_submodule_should_use_git_scm
+ generator.expects(:run).with("git submodule add #{@git_plugin_uri} vendor/plugins/rest_auth", false)
+ action :plugin, 'rest_auth', :git => @git_plugin_uri, :submodule => true
+ end
+
+ def test_plugin_with_no_options_should_skip_method
+ generator.expects(:run).never
+ action :plugin, 'rest_auth', {}
+ end
+
+ def test_gem_should_put_gem_dependency_in_enviroment
+ run_generator
+ action :gem, 'will-paginate'
+ assert_file 'config/environment.rb', /config\.gem 'will\-paginate'/
+ end
+
+ def test_gem_with_options_should_include_options_in_gem_dependency_in_environment
+ run_generator
+ action :gem, 'mislav-will-paginate', :lib => 'will-paginate', :source => 'http://gems.github.com'
+
+ regexp = /#{Regexp.escape("config.gem 'mislav-will-paginate', :lib => 'will-paginate', :source => 'http://gems.github.com'")}/
+ assert_file 'config/environment.rb', regexp
+ end
+
+ def test_gem_with_env_string_should_put_gem_dependency_in_specified_environment
+ run_generator
+ action :gem, 'rspec', :env => 'test'
+ assert_file 'config/environments/test.rb', /config\.gem 'rspec'/
+ end
+
+ def test_gem_with_env_array_should_put_gem_dependency_in_specified_environments
+ run_generator
+ action :gem, 'quietbacktrace', :env => %w[ development test ]
+ assert_file 'config/environments/development.rb', /config\.gem 'quietbacktrace'/
+ assert_file 'config/environments/test.rb', /config\.gem 'quietbacktrace'/
+ end
+
+ def test_gem_with_lib_option_set_to_false_should_put_gem_dependency_in_enviroment_correctly
+ run_generator
+ action :gem, 'mislav-will-paginate', :lib => false
+ assert_file 'config/environment.rb', /config\.gem 'mislav\-will\-paginate'\, :lib => false/
+ end
+
+ def test_environment_should_include_data_in_environment_initializer_block
+ run_generator
+ load_paths = 'config.load_paths += %w["#{RAILS_ROOT}/app/extras"]'
+ action :environment, load_paths
+ assert_file 'config/environment.rb', /#{Regexp.escape(load_paths)}/
+ end
+
+ def test_environment_with_block_should_include_block_contents_in_environment_initializer_block
+ run_generator
+
+ action :environment do
+ '# This wont be added'
+ '# This will be added'
+ end
+
+ assert_file 'config/environment.rb', /# This will be added/
+ end
+
+ def test_git_with_symbol_should_run_command_using_git_scm
+ generator.expects(:run).once.with('git init')
+ action :git, :init
+ end
+
+ def test_git_with_hash_should_run_each_command_using_git_scm
+ generator.expects(:run).times(2)
+ action :git, :rm => 'README', :add => '.'
+ end
+
+ def test_vendor_should_write_data_to_file_in_vendor
+ action :vendor, 'vendor_file.rb', '# vendor data'
+ assert_file 'vendor/vendor_file.rb', '# vendor data'
+ end
+
+ def test_lib_should_write_data_to_file_in_lib
+ action :lib, 'my_library.rb', 'class MyLibrary'
+ assert_file 'lib/my_library.rb', 'class MyLibrary'
+ end
+
+ def test_rakefile_should_write_date_to_file_in_lib_tasks
+ action :rakefile, 'myapp.rake', 'task :run => [:environment]'
+ assert_file 'lib/tasks/myapp.rake', 'task :run => [:environment]'
+ end
+
+ def test_initializer_should_write_date_to_file_in_config_initializers
+ action :initializer, 'constants.rb', 'MY_CONSTANT = 42'
+ assert_file 'config/initializers/constants.rb', 'MY_CONSTANT = 42'
+ end
+
+ def test_generate_should_run_script_generate_with_argument_and_options
+ generator.expects(:run).once.with('ruby script/generate model MyModel', false)
+ action :generate, 'model', 'MyModel'
+ end
+
+ def test_rake_should_run_rake_command_with_development_env
+ generator.expects(:run).once.with('rake log:clear RAILS_ENV=development', false)
+ action :rake, 'log:clear'
+ end
+
+ def test_rake_with_env_option_should_run_rake_command_in_env
+ generator.expects(:run).once.with('rake log:clear RAILS_ENV=production', false)
+ action :rake, 'log:clear', :env => 'production'
+ end
+
+ def test_rake_with_sudo_option_should_run_rake_command_with_sudo
+ generator.expects(:run).once.with('sudo rake log:clear RAILS_ENV=development', false)
+ action :rake, 'log:clear', :sudo => true
+ end
+
+ def test_capify_should_run_the_capify_command
+ generator.expects(:run).once.with('capify .', false)
+ action :capify!
+ end
+
+ def test_freeze_should_freeze_rails_edge
+ generator.expects(:run).once.with('rake rails:freeze:edge', false)
+ action :freeze!
+ end
+
+ def test_route_should_add_data_to_the_routes_block_in_config_routes
+ run_generator
+ route_command = "map.route '/login', :controller => 'sessions', :action => 'new'"
+ action :route, route_command
+ assert_file 'config/routes.rb', /#{Regexp.escape(route_command)}/
+ end
+
+ protected
+
+ def run_generator
+ silence(:stdout) { Rails::Generators::AppGenerator.start [destination_root] }
+ end
+
+ def generator(config={})
+ @generator ||= Rails::Generators::Base.new([], {}, { :root => destination_root }.merge!(config))
+ end
+
+ def action(*args, &block)
+ silence(:stdout){ generator.send(*args, &block) }
+ end
+
+end
diff --git a/railties/test/generators/app_test.rb b/railties/test/generators/app_test.rb
new file mode 100644
index 0000000000..a67f7e4926
--- /dev/null
+++ b/railties/test/generators/app_test.rb
@@ -0,0 +1,132 @@
+require 'abstract_unit'
+require 'generators/generator_test_helper'
+
+class AppTest < GeneratorTestCase
+
+ def test_application_skeleton_is_created
+ run_generator
+
+ %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| assert_file path }
+ end
+
+ def test_invalid_database_option_raises_an_error
+ content = capture(:stderr){ run_generator(["-d", "unknown"]) }
+ assert_match /Invalid value for \-\-database option/, content
+ end
+
+ def test_dispatchers_are_not_added_by_default
+ run_generator
+ assert_no_file "config.ru"
+ assert_no_file "public/dispatch.cgi"
+ assert_no_file "public/dispatch.fcgi"
+ end
+
+ def test_dispatchers_are_added_if_required
+ run_generator ["--with-dispatchers"]
+ assert_file "config.ru"
+ assert_file "public/dispatch.cgi"
+ assert_file "public/dispatch.fcgi"
+ end
+
+ def test_config_database_is_added_by_default
+ run_generator
+ assert_file "config/database.yml", /sqlite3/
+ end
+
+ def test_config_database_is_not_added_if_skip_activerecord_is_given
+ run_generator ["--skip-activerecord"]
+ assert_no_file "config/database.yml"
+ end
+
+ def test_activerecord_is_removed_from_frameworks_if_skip_activerecord_is_given
+ run_generator ["--skip-activerecord"]
+ assert_file "config/environment.rb", /config\.frameworks \-= \[ :active_record \]/
+ end
+
+ def test_prototype_and_test_unit_are_added_by_default
+ run_generator
+ assert_file "public/javascripts/prototype.js"
+ assert_file "test"
+ end
+
+ def test_prototype_and_test_unit_are_skipped_if_required
+ run_generator ["--skip-prototype", "--skip-testunit"]
+ assert_no_file "public/javascripts/prototype.js"
+ assert_no_file "test"
+ end
+
+ def test_shebang_is_added_to_files
+ run_generator ["--ruby", "foo/bar/baz"]
+
+ %w(
+ about
+ console
+ dbconsole
+ destroy
+ generate
+ plugin
+ runner
+ server
+ ).each { |path| assert_file "script/#{path}", /#!foo\/bar\/baz/ }
+ end
+
+ def test_rails_is_frozen
+ generator(:freeze => true, :database => "sqlite3").expects(:run).with("rake rails:freeze:edge", false)
+ silence(:stdout){ generator.invoke(:all) }
+ assert_file 'config/environment.rb', /# RAILS_GEM_VERSION/
+ end
+
+ def test_template_raises_an_error_with_invalid_path
+ content = capture(:stderr){ run_generator(["-m", "non/existant/path"]) }
+ assert_match /The template \[.*\] could not be loaded/, content
+ assert_match /non\/existant\/path/, content
+ end
+
+ def test_template_is_executed_when_supplied
+ path = "http://gist.github.com/103208.txt"
+ template = %{ say "It works!" }
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ generator(:template => path, :database => "sqlite3").expects(:open).with(path).returns(template)
+ assert_match /It works!/, silence(:stdout){ generator.invoke(:all) }
+ end
+
+ protected
+
+ def run_generator(args=[])
+ silence(:stdout) { Rails::Generators::AppGenerator.start [destination_root].concat(args) }
+ end
+
+ def generator(options={})
+ @generator ||= Rails::Generators::AppGenerator.new([destination_root], options, :root => destination_root)
+ end
+
+end
diff --git a/railties/test/generators/generator_test_helper.rb b/railties/test/generators/generator_test_helper.rb
index 01bf1c90bd..2b988bde7a 100644
--- a/railties/test/generators/generator_test_helper.rb
+++ b/railties/test/generators/generator_test_helper.rb
@@ -1,303 +1,56 @@
require 'test/unit'
require 'fileutils'
-# Mock out what we need from AR::Base
-module ActiveRecord
- class Base
- class << self
- attr_accessor :pluralize_table_names, :timestamped_migrations
- end
- self.pluralize_table_names = true
- self.timestamped_migrations = true
- end
-
- module ConnectionAdapters
- class Column
- attr_reader :name, :default, :type, :limit, :null, :sql_type, :precision, :scale
-
- def initialize(name, default, sql_type = nil)
- @name = name
- @default = default
- @type = @sql_type = sql_type
- end
-
- def human_name
- @name.humanize
- end
- end
- end
-end
-
-# Mock up necessities from ActionView
-module ActionView
- module Helpers
- module ActionRecordHelper; end
- class InstanceTag; end
- end
-end
-
-# Set RAILS_ROOT appropriately fixture generation
-tmp_dir = "#{File.dirname(__FILE__)}/../fixtures/tmp"
-
-if defined? RAILS_ROOT
- RAILS_ROOT.replace tmp_dir
-else
- RAILS_ROOT = tmp_dir
-end
-FileUtils.mkdir_p RAILS_ROOT
-
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../lib"
-require 'initializer'
-# Mocks out the configuration
-module Rails
- def self.configuration
- Rails::Configuration.new
- end
-end
-
-require 'rails_generator'
+# For this while, let's load all generators by hand
+require 'generators'
+require 'generators/rails/app/app_generator'
class GeneratorTestCase < Test::Unit::TestCase
include FileUtils
- def setup
- ActiveRecord::Base.pluralize_table_names = true
-
- mkdir_p "#{RAILS_ROOT}/app/views/layouts"
- mkdir_p "#{RAILS_ROOT}/config"
- mkdir_p "#{RAILS_ROOT}/db"
- mkdir_p "#{RAILS_ROOT}/test/fixtures"
- mkdir_p "#{RAILS_ROOT}/public/stylesheets"
-
- File.open("#{RAILS_ROOT}/config/routes.rb", 'w') do |f|
- f << "ActionController::Routing::Routes.draw do |map|\n\nend"
- end
+ def destination_root
+ @destination_root ||= File.expand_path("#{File.dirname(__FILE__)}/../fixtures/tmp")
end
- def teardown
- rm_rf "#{RAILS_ROOT}/app"
- rm_rf "#{RAILS_ROOT}/test"
- rm_rf "#{RAILS_ROOT}/config"
- rm_rf "#{RAILS_ROOT}/db"
- rm_rf "#{RAILS_ROOT}/public"
+ def setup
+ mkdir_p(destination_root)
+ rm_rf(destination_root)
end
def test_truth
# don't complain, test/unit
end
- # Instantiates the Generator.
- def build_generator(name, params)
- Rails::Generator::Base.instance(name, params)
- end
-
- # Runs the +create+ command (like the command line does).
- def run_generator(name, params)
- silence_generator do
- build_generator(name, params).command(:create).invoke!
- end
- end
-
- # Silences the logger temporarily and returns the output as a String.
- def silence_generator
- logger_original = Rails::Generator::Base.logger
- myout = StringIO.new
- Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(myout)
- yield if block_given?
- Rails::Generator::Base.logger = logger_original
- myout.string
- end
-
- # Asserts that the given controller was generated.
- # It takes a name or symbol without the <tt>_controller</tt> part and an optional super class.
- # The contents of the class source file is passed to a block.
- def assert_generated_controller_for(name, parent = "ApplicationController")
- assert_generated_class "app/controllers/#{name.to_s.underscore}_controller", parent do |body|
- yield body if block_given?
- end
- end
-
- # Asserts that the given model was generated.
- # It takes a name or symbol and an optional super class.
- # The contents of the class source file is passed to a block.
- def assert_generated_model_for(name, parent = "ActiveRecord::Base")
- assert_generated_class "app/models/#{name.to_s.underscore}", parent do |body|
- yield body if block_given?
- end
- end
-
- # Asserts that the given helper was generated.
- # It takes a name or symbol without the <tt>_helper</tt> part.
- # The contents of the module source file is passed to a block.
- def assert_generated_helper_for(name)
- assert_generated_module "app/helpers/#{name.to_s.underscore}_helper" do |body|
- yield body if block_given?
- end
- end
-
- # Asserts that the given functional test was generated.
- # It takes a name or symbol without the <tt>_controller_test</tt> part and an optional super class.
- # The contents of the class source file is passed to a block.
- def assert_generated_functional_test_for(name, parent = "ActionController::TestCase")
- assert_generated_class "test/functional/#{name.to_s.underscore}_controller_test",parent do |body|
- yield body if block_given?
- end
- end
-
- # Asserts that the given helper test test was generated.
- # It takes a name or symbol without the <tt>_helper_test</tt> part and an optional super class.
- # The contents of the class source file is passed to a block.
- def assert_generated_helper_test_for(name, parent = "ActionView::TestCase")
- path = "test/unit/helpers/#{name.to_s.underscore}_helper_test"
- # Have to pass the path without the "test/" part so that class_name_from_path will return a correct result
- class_name = class_name_from_path(path.gsub(/^test\//, ''))
-
- assert_generated_class path,parent,class_name do |body|
- yield body if block_given?
- end
- end
-
- # Asserts that the given unit test was generated.
- # It takes a name or symbol without the <tt>_test</tt> part and an optional super class.
- # The contents of the class source file is passed to a block.
- def assert_generated_unit_test_for(name, parent = "ActiveSupport::TestCase")
- assert_generated_class "test/unit/#{name.to_s.underscore}_test", parent do |body|
- yield body if block_given?
- end
- end
-
- # Asserts that the given file was generated.
- # The contents of the file is passed to a block.
- def assert_generated_file(path)
- assert_file_exists(path)
- File.open("#{RAILS_ROOT}/#{path}") do |f|
- yield f.read if block_given?
- end
- end
-
- # asserts that the given file exists
- def assert_file_exists(path)
- assert File.exist?("#{RAILS_ROOT}/#{path}"),
- "The file '#{RAILS_ROOT}/#{path}' should exist"
- end
-
- # Asserts that the given class source file was generated.
- # It takes a path without the <tt>.rb</tt> part and an optional super class.
- # The contents of the class source file is passed to a block.
- def assert_generated_class(path, parent = nil, class_name = class_name_from_path(path))
- assert_generated_file("#{path}.rb") do |body|
- assert_match /class #{class_name}#{parent.nil? ? '':" < #{parent}"}/, body, "the file '#{path}.rb' should be a class"
- yield body if block_given?
- end
- end
-
- def class_name_from_path(path)
- # FIXME: Sucky way to detect namespaced classes
- if path.split('/').size > 3
- path =~ /\/?(\d+_)?(\w+)\/(\w+)$/
- "#{$2.camelize}::#{$3.camelize}"
- else
- path =~ /\/?(\d+_)?(\w+)$/
- $2.camelize
- end
- end
-
- # Asserts that the given module source file was generated.
- # It takes a path without the <tt>.rb</tt> part.
- # The contents of the class source file is passed to a block.
- def assert_generated_module(path)
- # FIXME: Sucky way to detect namespaced modules
- if path.split('/').size > 3
- path =~ /\/?(\w+)\/(\w+)$/
- module_name = "#{$1.camelize}::#{$2.camelize}"
- else
- path =~ /\/?(\w+)$/
- module_name = $1.camelize
+ def capture(stream)
+ begin
+ stream = stream.to_s
+ eval "$#{stream} = StringIO.new"
+ yield
+ result = eval("$#{stream}").string
+ ensure
+ eval("$#{stream} = #{stream.upcase}")
end
- assert_generated_file("#{path}.rb") do |body|
- assert_match /module #{module_name}/, body, "the file '#{path}.rb' should be a module"
- yield body if block_given?
- end
- end
-
- # Asserts that the given CSS stylesheet file was generated.
- # It takes a path without the <tt>.css</tt> part.
- # The contents of the stylesheet source file is passed to a block.
- def assert_generated_stylesheet(path)
- assert_generated_file("public/stylesheets/#{path}.css") do |body|
- yield body if block_given?
- end
- end
-
- # Asserts that the given YAML file was generated.
- # It takes a path without the <tt>.yml</tt> part.
- # The parsed YAML tree is passed to a block.
- def assert_generated_yaml(path)
- assert_generated_file("#{path}.yml") do |body|
- yaml = YAML.load(body)
- assert yaml, 'YAML data missing'
- yield yaml if block_given?
- end
- end
-
- # Asserts that the given fixtures YAML file was generated.
- # It takes a fixture name without the <tt>.yml</tt> part.
- # The parsed YAML tree is passed to a block.
- def assert_generated_fixtures_for(name)
- assert_generated_yaml "test/fixtures/#{name.to_s.underscore}" do |yaml|
- yield yaml if block_given?
- end
+ result
end
+ alias :silence :capture
- # Asserts that the given views were generated.
- # It takes a controller name and a list of views (including extensions).
- # The body of each view is passed to a block.
- def assert_generated_views_for(name, *actions)
- actions.each do |action|
- assert_generated_file("app/views/#{name.to_s.underscore}/#{action}") do |body|
- yield body if block_given?
- end
- end
- end
-
- def assert_generated_migration(name, parent = "ActiveRecord::Migration")
- file = Dir.glob("#{RAILS_ROOT}/db/migrate/*_#{name.to_s.underscore}.rb").first
- file = file.match(/db\/migrate\/[0-9]+_\w+/).to_s
- assert_generated_class file, parent do |body|
- assert_match /timestamps/, body, "should have timestamps defined"
- yield body if block_given?
- end
- end
-
- # Asserts that the given migration file was not generated.
- # It takes the name of the migration as a parameter.
- def assert_skipped_migration(name)
- migration_file = "#{RAILS_ROOT}/db/migrate/001_#{name.to_s.underscore}.rb"
- assert !File.exist?(migration_file), "should not create migration #{migration_file}"
- end
-
- # Asserts that the given resource was added to the routes.
- def assert_added_route_for(name)
- assert_generated_file("config/routes.rb") do |body|
- assert_match /map.resources :#{name.to_s.underscore}/, body,
- "should add route for :#{name.to_s.underscore}"
- end
- end
+ def assert_file(relative, content=nil)
+ absolute = File.join(destination_root, relative)
+ assert File.exists?(absolute)
- # Asserts that the given methods are defined in the body.
- # This does assume standard rails code conventions with regards to the source code.
- # The body of each individual method is passed to a block.
- def assert_has_method(body, *methods)
- methods.each do |name|
- assert body =~ /^ def #{name}(\(.+\))?\n((\n| .*\n)*) end/, "should have method #{name}"
- yield(name, $2) if block_given?
+ case content
+ when String
+ assert_equal content, File.read(absolute)
+ when Regexp
+ assert_match content, File.read(absolute)
end
end
- # Asserts that the given column is defined in the migration.
- def assert_generated_column(body, name, type)
- assert_match /t\.#{type.to_s} :#{name.to_s}/, body, "should have column #{name.to_s} defined"
+ def assert_no_file(relative, content=nil)
+ absolute = File.join(destination_root, relative)
+ assert !File.exists?(absolute)
end
end
diff --git a/railties/test/generators/rails_template_runner_test.rb b/railties/test/generators/rails_template_runner_test.rb
deleted file mode 100644
index 2da6bd59b5..0000000000
--- a/railties/test/generators/rails_template_runner_test.rb
+++ /dev/null
@@ -1,216 +0,0 @@
-require 'abstract_unit'
-require 'generators/generator_test_helper'
-
-class RailsTemplateRunnerTest < GeneratorTestCase
- def setup
- Rails::Generator::Base.use_application_sources!
- run_generator('app', [RAILS_ROOT])
- # generate empty template
- @template_path = File.join(RAILS_ROOT, 'template.rb')
- File.open(File.join(@template_path), 'w') {|f| f << '' }
-
- @git_plugin_uri = 'git://github.com/technoweenie/restful-authentication.git'
- @svn_plugin_uri = 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
- end
-
- def teardown
- super
- rm_rf "#{RAILS_ROOT}/README"
- rm_rf "#{RAILS_ROOT}/Rakefile"
- rm_rf "#{RAILS_ROOT}/doc"
- rm_rf "#{RAILS_ROOT}/lib"
- rm_rf "#{RAILS_ROOT}/log"
- rm_rf "#{RAILS_ROOT}/script"
- rm_rf "#{RAILS_ROOT}/vendor"
- rm_rf "#{RAILS_ROOT}/tmp"
- rm_rf "#{RAILS_ROOT}/Capfile"
- rm_rf @template_path
- end
-
- def test_initialize_should_load_template
- Rails::TemplateRunner.any_instance.expects(:load_template).with(@template_path)
- silence_generator do
- Rails::TemplateRunner.new(@template_path, RAILS_ROOT)
- end
- end
-
- def test_initialize_should_raise_error_on_missing_template_file
- assert_raise(RuntimeError) do
- silence_generator do
- Rails::TemplateRunner.new('non/existent/path/to/template.rb', RAILS_ROOT)
- end
- end
- end
-
- def test_file_should_write_data_to_file_path
- run_template_method(:file, 'lib/test_file.rb', 'heres test data')
- assert_generated_file_with_data 'lib/test_file.rb', 'heres test data'
- end
-
- def test_file_should_write_block_contents_to_file_path
- run_template_method(:file, 'lib/test_file.rb') { 'heres block data' }
- assert_generated_file_with_data 'lib/test_file.rb', 'heres block data'
- end
-
- def test_plugin_with_git_option_should_run_plugin_install
- expects_run_ruby_script_with_command("script/plugin install #{@git_plugin_uri}")
- run_template_method(:plugin, 'restful-authentication', :git => @git_plugin_uri)
- end
-
- def test_plugin_with_svn_option_should_run_plugin_install
- expects_run_ruby_script_with_command("script/plugin install #{@svn_plugin_uri}")
- run_template_method(:plugin, 'restful-authentication', :svn => @svn_plugin_uri)
- end
-
- def test_plugin_with_git_option_and_submodule_should_use_git_scm
- Rails::Git.expects(:run).with("submodule add #{@git_plugin_uri} vendor/plugins/rest_auth")
- run_template_method(:plugin, 'rest_auth', :git => @git_plugin_uri, :submodule => true)
- end
-
- def test_plugin_with_no_options_should_skip_method
- Rails::TemplateRunner.any_instance.expects(:run).never
- run_template_method(:plugin, 'rest_auth', {})
- end
-
- def test_gem_should_put_gem_dependency_in_enviroment
- run_template_method(:gem, 'will-paginate')
- assert_rails_initializer_includes("config.gem 'will-paginate'")
- end
-
- def test_gem_with_options_should_include_options_in_gem_dependency_in_environment
- run_template_method(:gem, 'mislav-will-paginate', :lib => 'will-paginate', :source => 'http://gems.github.com')
- assert_rails_initializer_includes("config.gem 'mislav-will-paginate', :lib => 'will-paginate', :source => 'http://gems.github.com'")
- end
-
- def test_gem_with_env_string_should_put_gem_dependency_in_specified_environment
- run_template_method(:gem, 'rspec', :env => 'test')
- assert_generated_file_with_data('config/environments/test.rb', "config.gem 'rspec'", 'test')
- end
-
- def test_gem_with_env_array_should_put_gem_dependency_in_specified_environments
- run_template_method(:gem, 'quietbacktrace', :env => %w[ development test ])
- assert_generated_file_with_data('config/environments/development.rb', "config.gem 'quietbacktrace'")
- assert_generated_file_with_data('config/environments/test.rb', "config.gem 'quietbacktrace'")
- end
-
- def test_gem_with_lib_option_set_to_false_should_put_gem_dependency_in_enviroment_correctly
- run_template_method(:gem, 'mislav-will-paginate', :lib => false, :source => 'http://gems.github.com')
- assert_rails_initializer_includes("config.gem 'mislav-will-paginate', :lib => false, :source => 'http://gems.github.com'")
- end
-
- def test_environment_should_include_data_in_environment_initializer_block
- load_paths = 'config.load_paths += %w["#{RAILS_ROOT}/app/extras"]'
- run_template_method(:environment, load_paths)
- assert_rails_initializer_includes(load_paths)
- end
-
- def test_environment_with_block_should_include_block_contents_in_environment_initializer_block
- run_template_method(:environment) do
- '# This wont be added'
- '# This will be added'
- end
- assert_rails_initializer_includes('# This will be added')
- end
-
- def test_git_with_symbol_should_run_command_using_git_scm
- Rails::Git.expects(:run).once.with('init')
- run_template_method(:git, :init)
- end
-
- def test_git_with_hash_should_run_each_command_using_git_scm
- Rails::Git.expects(:run).times(2)
- run_template_method(:git, {:init => '', :add => '.'})
- end
-
- def test_vendor_should_write_data_to_file_in_vendor
- run_template_method(:vendor, 'vendor_file.rb', '# vendor data')
- assert_generated_file_with_data('vendor/vendor_file.rb', '# vendor data')
- end
-
- def test_lib_should_write_data_to_file_in_lib
- run_template_method(:lib, 'my_library.rb', 'class MyLibrary')
- assert_generated_file_with_data('lib/my_library.rb', 'class MyLibrary')
- end
-
- def test_rakefile_should_write_date_to_file_in_lib_tasks
- run_template_method(:rakefile, 'myapp.rake', 'task :run => [:environment]')
- assert_generated_file_with_data('lib/tasks/myapp.rake', 'task :run => [:environment]')
- end
-
- def test_initializer_should_write_date_to_file_in_config_initializers
- run_template_method(:initializer, 'constants.rb', 'MY_CONSTANT = 42')
- assert_generated_file_with_data('config/initializers/constants.rb', 'MY_CONSTANT = 42')
- end
-
- def test_generate_should_run_script_generate_with_argument_and_options
- expects_run_ruby_script_with_command('script/generate model MyModel')
- run_template_method(:generate, 'model', 'MyModel')
- end
-
- def test_rake_should_run_rake_command_with_development_env
- expects_run_with_command('rake log:clear RAILS_ENV=development')
- run_template_method(:rake, 'log:clear')
- end
-
- def test_rake_with_env_option_should_run_rake_command_in_env
- expects_run_with_command('rake log:clear RAILS_ENV=production')
- run_template_method(:rake, 'log:clear', :env => 'production')
- end
-
- def test_rake_with_sudo_option_should_run_rake_command_with_sudo
- expects_run_with_command('sudo rake log:clear RAILS_ENV=development')
- run_template_method(:rake, 'log:clear', :sudo => true)
- end
-
- def test_capify_should_run_the_capify_command
- expects_run_with_command('capify .')
- run_template_method(:capify!)
- end
-
- def test_freeze_should_freeze_rails_edge
- expects_run_with_command('rake rails:freeze:edge')
- run_template_method(:freeze!)
- end
-
- def test_route_should_add_data_to_the_routes_block_in_config_routes
- route_command = "map.route '/login', :controller => 'sessions', :action => 'new'"
- run_template_method(:route, route_command)
- assert_generated_file_with_data 'config/routes.rb', route_command
- end
-
- def test_run_ruby_script_should_add_ruby_to_command_in_win32_environment
- ruby_command = RUBY_PLATFORM =~ /win32/ ? 'ruby ' : ''
- expects_run_with_command("#{ruby_command}script/generate model MyModel")
- run_template_method(:generate, 'model', 'MyModel')
- end
-
- protected
- def run_template_method(method_name, *args, &block)
- silence_generator do
- @template_runner = Rails::TemplateRunner.new(@template_path, RAILS_ROOT)
- @template_runner.send(method_name, *args, &block)
- end
- end
-
- def expects_run_with_command(command)
- Rails::TemplateRunner.any_instance.stubs(:run).once.with(command, false)
- end
-
- def expects_run_ruby_script_with_command(command)
- Rails::TemplateRunner.any_instance.stubs(:run_ruby_script).once.with(command,false)
- end
-
- def assert_rails_initializer_includes(data, message = nil)
- message ||= "Rails::Initializer should include #{data}"
- assert_generated_file 'config/environment.rb' do |body|
- assert_match(/#{Regexp.escape("Rails::Initializer.run do |config|")}.+#{Regexp.escape(data)}.+end/m, body, message)
- end
- end
-
- def assert_generated_file_with_data(file, data, message = nil)
- message ||= "#{file} should include '#{data}'"
- assert_generated_file(file) do |file|
- assert_match(/#{Regexp.escape(data)}/,file, message)
- end
- end
-end \ No newline at end of file
diff --git a/railties/test/rails_generator/generator_test_helper.rb b/railties/test/rails_generator/generator_test_helper.rb
new file mode 100644
index 0000000000..01bf1c90bd
--- /dev/null
+++ b/railties/test/rails_generator/generator_test_helper.rb
@@ -0,0 +1,303 @@
+require 'test/unit'
+require 'fileutils'
+
+# Mock out what we need from AR::Base
+module ActiveRecord
+ class Base
+ class << self
+ attr_accessor :pluralize_table_names, :timestamped_migrations
+ end
+ self.pluralize_table_names = true
+ self.timestamped_migrations = true
+ end
+
+ module ConnectionAdapters
+ class Column
+ attr_reader :name, :default, :type, :limit, :null, :sql_type, :precision, :scale
+
+ def initialize(name, default, sql_type = nil)
+ @name = name
+ @default = default
+ @type = @sql_type = sql_type
+ end
+
+ def human_name
+ @name.humanize
+ end
+ end
+ end
+end
+
+# Mock up necessities from ActionView
+module ActionView
+ module Helpers
+ module ActionRecordHelper; end
+ class InstanceTag; end
+ end
+end
+
+# Set RAILS_ROOT appropriately fixture generation
+tmp_dir = "#{File.dirname(__FILE__)}/../fixtures/tmp"
+
+if defined? RAILS_ROOT
+ RAILS_ROOT.replace tmp_dir
+else
+ RAILS_ROOT = tmp_dir
+end
+FileUtils.mkdir_p RAILS_ROOT
+
+$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../lib"
+require 'initializer'
+
+# Mocks out the configuration
+module Rails
+ def self.configuration
+ Rails::Configuration.new
+ end
+end
+
+require 'rails_generator'
+
+class GeneratorTestCase < Test::Unit::TestCase
+ include FileUtils
+
+ def setup
+ ActiveRecord::Base.pluralize_table_names = true
+
+ mkdir_p "#{RAILS_ROOT}/app/views/layouts"
+ mkdir_p "#{RAILS_ROOT}/config"
+ mkdir_p "#{RAILS_ROOT}/db"
+ mkdir_p "#{RAILS_ROOT}/test/fixtures"
+ mkdir_p "#{RAILS_ROOT}/public/stylesheets"
+
+ File.open("#{RAILS_ROOT}/config/routes.rb", 'w') do |f|
+ f << "ActionController::Routing::Routes.draw do |map|\n\nend"
+ end
+ end
+
+ def teardown
+ rm_rf "#{RAILS_ROOT}/app"
+ rm_rf "#{RAILS_ROOT}/test"
+ rm_rf "#{RAILS_ROOT}/config"
+ rm_rf "#{RAILS_ROOT}/db"
+ rm_rf "#{RAILS_ROOT}/public"
+ end
+
+ def test_truth
+ # don't complain, test/unit
+ end
+
+ # Instantiates the Generator.
+ def build_generator(name, params)
+ Rails::Generator::Base.instance(name, params)
+ end
+
+ # Runs the +create+ command (like the command line does).
+ def run_generator(name, params)
+ silence_generator do
+ build_generator(name, params).command(:create).invoke!
+ end
+ end
+
+ # Silences the logger temporarily and returns the output as a String.
+ def silence_generator
+ logger_original = Rails::Generator::Base.logger
+ myout = StringIO.new
+ Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(myout)
+ yield if block_given?
+ Rails::Generator::Base.logger = logger_original
+ myout.string
+ end
+
+ # Asserts that the given controller was generated.
+ # It takes a name or symbol without the <tt>_controller</tt> part and an optional super class.
+ # The contents of the class source file is passed to a block.
+ def assert_generated_controller_for(name, parent = "ApplicationController")
+ assert_generated_class "app/controllers/#{name.to_s.underscore}_controller", parent do |body|
+ yield body if block_given?
+ end
+ end
+
+ # Asserts that the given model was generated.
+ # It takes a name or symbol and an optional super class.
+ # The contents of the class source file is passed to a block.
+ def assert_generated_model_for(name, parent = "ActiveRecord::Base")
+ assert_generated_class "app/models/#{name.to_s.underscore}", parent do |body|
+ yield body if block_given?
+ end
+ end
+
+ # Asserts that the given helper was generated.
+ # It takes a name or symbol without the <tt>_helper</tt> part.
+ # The contents of the module source file is passed to a block.
+ def assert_generated_helper_for(name)
+ assert_generated_module "app/helpers/#{name.to_s.underscore}_helper" do |body|
+ yield body if block_given?
+ end
+ end
+
+ # Asserts that the given functional test was generated.
+ # It takes a name or symbol without the <tt>_controller_test</tt> part and an optional super class.
+ # The contents of the class source file is passed to a block.
+ def assert_generated_functional_test_for(name, parent = "ActionController::TestCase")
+ assert_generated_class "test/functional/#{name.to_s.underscore}_controller_test",parent do |body|
+ yield body if block_given?
+ end
+ end
+
+ # Asserts that the given helper test test was generated.
+ # It takes a name or symbol without the <tt>_helper_test</tt> part and an optional super class.
+ # The contents of the class source file is passed to a block.
+ def assert_generated_helper_test_for(name, parent = "ActionView::TestCase")
+ path = "test/unit/helpers/#{name.to_s.underscore}_helper_test"
+ # Have to pass the path without the "test/" part so that class_name_from_path will return a correct result
+ class_name = class_name_from_path(path.gsub(/^test\//, ''))
+
+ assert_generated_class path,parent,class_name do |body|
+ yield body if block_given?
+ end
+ end
+
+ # Asserts that the given unit test was generated.
+ # It takes a name or symbol without the <tt>_test</tt> part and an optional super class.
+ # The contents of the class source file is passed to a block.
+ def assert_generated_unit_test_for(name, parent = "ActiveSupport::TestCase")
+ assert_generated_class "test/unit/#{name.to_s.underscore}_test", parent do |body|
+ yield body if block_given?
+ end
+ end
+
+ # Asserts that the given file was generated.
+ # The contents of the file is passed to a block.
+ def assert_generated_file(path)
+ assert_file_exists(path)
+ File.open("#{RAILS_ROOT}/#{path}") do |f|
+ yield f.read if block_given?
+ end
+ end
+
+ # asserts that the given file exists
+ def assert_file_exists(path)
+ assert File.exist?("#{RAILS_ROOT}/#{path}"),
+ "The file '#{RAILS_ROOT}/#{path}' should exist"
+ end
+
+ # Asserts that the given class source file was generated.
+ # It takes a path without the <tt>.rb</tt> part and an optional super class.
+ # The contents of the class source file is passed to a block.
+ def assert_generated_class(path, parent = nil, class_name = class_name_from_path(path))
+ assert_generated_file("#{path}.rb") do |body|
+ assert_match /class #{class_name}#{parent.nil? ? '':" < #{parent}"}/, body, "the file '#{path}.rb' should be a class"
+ yield body if block_given?
+ end
+ end
+
+ def class_name_from_path(path)
+ # FIXME: Sucky way to detect namespaced classes
+ if path.split('/').size > 3
+ path =~ /\/?(\d+_)?(\w+)\/(\w+)$/
+ "#{$2.camelize}::#{$3.camelize}"
+ else
+ path =~ /\/?(\d+_)?(\w+)$/
+ $2.camelize
+ end
+ end
+
+ # Asserts that the given module source file was generated.
+ # It takes a path without the <tt>.rb</tt> part.
+ # The contents of the class source file is passed to a block.
+ def assert_generated_module(path)
+ # FIXME: Sucky way to detect namespaced modules
+ if path.split('/').size > 3
+ path =~ /\/?(\w+)\/(\w+)$/
+ module_name = "#{$1.camelize}::#{$2.camelize}"
+ else
+ path =~ /\/?(\w+)$/
+ module_name = $1.camelize
+ end
+
+ assert_generated_file("#{path}.rb") do |body|
+ assert_match /module #{module_name}/, body, "the file '#{path}.rb' should be a module"
+ yield body if block_given?
+ end
+ end
+
+ # Asserts that the given CSS stylesheet file was generated.
+ # It takes a path without the <tt>.css</tt> part.
+ # The contents of the stylesheet source file is passed to a block.
+ def assert_generated_stylesheet(path)
+ assert_generated_file("public/stylesheets/#{path}.css") do |body|
+ yield body if block_given?
+ end
+ end
+
+ # Asserts that the given YAML file was generated.
+ # It takes a path without the <tt>.yml</tt> part.
+ # The parsed YAML tree is passed to a block.
+ def assert_generated_yaml(path)
+ assert_generated_file("#{path}.yml") do |body|
+ yaml = YAML.load(body)
+ assert yaml, 'YAML data missing'
+ yield yaml if block_given?
+ end
+ end
+
+ # Asserts that the given fixtures YAML file was generated.
+ # It takes a fixture name without the <tt>.yml</tt> part.
+ # The parsed YAML tree is passed to a block.
+ def assert_generated_fixtures_for(name)
+ assert_generated_yaml "test/fixtures/#{name.to_s.underscore}" do |yaml|
+ yield yaml if block_given?
+ end
+ end
+
+ # Asserts that the given views were generated.
+ # It takes a controller name and a list of views (including extensions).
+ # The body of each view is passed to a block.
+ def assert_generated_views_for(name, *actions)
+ actions.each do |action|
+ assert_generated_file("app/views/#{name.to_s.underscore}/#{action}") do |body|
+ yield body if block_given?
+ end
+ end
+ end
+
+ def assert_generated_migration(name, parent = "ActiveRecord::Migration")
+ file = Dir.glob("#{RAILS_ROOT}/db/migrate/*_#{name.to_s.underscore}.rb").first
+ file = file.match(/db\/migrate\/[0-9]+_\w+/).to_s
+ assert_generated_class file, parent do |body|
+ assert_match /timestamps/, body, "should have timestamps defined"
+ yield body if block_given?
+ end
+ end
+
+ # Asserts that the given migration file was not generated.
+ # It takes the name of the migration as a parameter.
+ def assert_skipped_migration(name)
+ migration_file = "#{RAILS_ROOT}/db/migrate/001_#{name.to_s.underscore}.rb"
+ assert !File.exist?(migration_file), "should not create migration #{migration_file}"
+ end
+
+ # Asserts that the given resource was added to the routes.
+ def assert_added_route_for(name)
+ assert_generated_file("config/routes.rb") do |body|
+ assert_match /map.resources :#{name.to_s.underscore}/, body,
+ "should add route for :#{name.to_s.underscore}"
+ end
+ end
+
+ # Asserts that the given methods are defined in the body.
+ # This does assume standard rails code conventions with regards to the source code.
+ # The body of each individual method is passed to a block.
+ def assert_has_method(body, *methods)
+ methods.each do |name|
+ assert body =~ /^ def #{name}(\(.+\))?\n((\n| .*\n)*) end/, "should have method #{name}"
+ yield(name, $2) if block_given?
+ end
+ end
+
+ # Asserts that the given column is defined in the migration.
+ def assert_generated_column(body, name, type)
+ assert_match /t\.#{type.to_s} :#{name.to_s}/, body, "should have column #{name.to_s} defined"
+ end
+end
diff --git a/railties/test/generators/rails_controller_generator_test.rb b/railties/test/rails_generator/rails_controller_generator_test.rb
index 43fbe972e2..43fbe972e2 100644
--- a/railties/test/generators/rails_controller_generator_test.rb
+++ b/railties/test/rails_generator/rails_controller_generator_test.rb
diff --git a/railties/test/generators/rails_helper_generator_test.rb b/railties/test/rails_generator/rails_helper_generator_test.rb
index 8d05f555e6..8d05f555e6 100644
--- a/railties/test/generators/rails_helper_generator_test.rb
+++ b/railties/test/rails_generator/rails_helper_generator_test.rb
diff --git a/railties/test/generators/rails_mailer_generator_test.rb b/railties/test/rails_generator/rails_mailer_generator_test.rb
index de61e6736d..de61e6736d 100644
--- a/railties/test/generators/rails_mailer_generator_test.rb
+++ b/railties/test/rails_generator/rails_mailer_generator_test.rb
diff --git a/railties/test/generators/rails_model_generator_test.rb b/railties/test/rails_generator/rails_model_generator_test.rb
index aea2abafba..aea2abafba 100644
--- a/railties/test/generators/rails_model_generator_test.rb
+++ b/railties/test/rails_generator/rails_model_generator_test.rb
diff --git a/railties/test/generators/rails_model_subclass_generator_test.rb b/railties/test/rails_generator/rails_model_subclass_generator_test.rb
index 30066b5a3c..30066b5a3c 100644
--- a/railties/test/generators/rails_model_subclass_generator_test.rb
+++ b/railties/test/rails_generator/rails_model_subclass_generator_test.rb
diff --git a/railties/test/generators/rails_resource_generator_test.rb b/railties/test/rails_generator/rails_resource_generator_test.rb
index 1f5bd0ef1e..1f5bd0ef1e 100644
--- a/railties/test/generators/rails_resource_generator_test.rb
+++ b/railties/test/rails_generator/rails_resource_generator_test.rb
diff --git a/railties/test/generators/rails_scaffold_generator_test.rb b/railties/test/rails_generator/rails_scaffold_generator_test.rb
index 70829a77fd..70829a77fd 100644
--- a/railties/test/generators/rails_scaffold_generator_test.rb
+++ b/railties/test/rails_generator/rails_scaffold_generator_test.rb
diff --git a/railties/test/secret_key_generation_test.rb b/railties/test/secret_key_generation_test.rb
deleted file mode 100644
index 2c7c3d5dfe..0000000000
--- a/railties/test/secret_key_generation_test.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-require 'abstract_unit'
-
-# Must set before requiring generator libs.
-if defined?(RAILS_ROOT)
- RAILS_ROOT.replace "#{File.dirname(__FILE__)}/fixtures"
-else
- RAILS_ROOT = "#{File.dirname(__FILE__)}/fixtures"
-end
-
-$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
-
-require 'initializer'
-
-# Mocks out the configuration
-module Rails
- def self.configuration
- Rails::Configuration.new
- end
-end
-
-require 'rails_generator'
-require 'rails_generator/secret_key_generator'
-require 'rails_generator/generators/applications/app/app_generator'
-
-class SecretKeyGenerationTest < ActiveSupport::TestCase
- SECRET_KEY_MIN_LENGTH = 128
- APP_NAME = "foo"
-
- def setup
- @generator = Rails::SecretKeyGenerator.new(APP_NAME)
- end
-
- def test_secret_key_generation
- assert_deprecated /ActiveSupport::SecureRandom\.hex\(64\)/ do
- assert @generator.generate_secret.length >= SECRET_KEY_MIN_LENGTH
- end
- end
-end