aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails/commands
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib/rails/commands')
-rw-r--r--railties/lib/rails/commands/application.rb17
-rw-r--r--railties/lib/rails/commands/application/application_command.rb29
-rw-r--r--railties/lib/rails/commands/commands_tasks.rb180
-rw-r--r--railties/lib/rails/commands/console/console_command.rb (renamed from railties/lib/rails/commands/console.rb)55
-rw-r--r--railties/lib/rails/commands/console_helper.rb34
-rw-r--r--railties/lib/rails/commands/dbconsole.rb173
-rw-r--r--railties/lib/rails/commands/dbconsole/dbconsole_command.rb155
-rw-r--r--railties/lib/rails/commands/destroy.rb11
-rw-r--r--railties/lib/rails/commands/destroy/destroy_command.rb21
-rw-r--r--railties/lib/rails/commands/generate.rb13
-rw-r--r--railties/lib/rails/commands/generate/generate_command.rb23
-rw-r--r--railties/lib/rails/commands/help/USAGE27
-rw-r--r--railties/lib/rails/commands/help/help_command.rb13
-rw-r--r--railties/lib/rails/commands/new/new_command.rb15
-rw-r--r--railties/lib/rails/commands/plugin.rb23
-rw-r--r--railties/lib/rails/commands/plugin/plugin_command.rb43
-rw-r--r--railties/lib/rails/commands/rake/rake_command.rb49
-rw-r--r--railties/lib/rails/commands/rake_proxy.rb34
-rw-r--r--railties/lib/rails/commands/runner.rb69
-rw-r--r--railties/lib/rails/commands/runner/USAGE17
-rw-r--r--railties/lib/rails/commands/runner/runner_command.rb46
-rw-r--r--railties/lib/rails/commands/server.rb139
-rw-r--r--railties/lib/rails/commands/server/server_command.rb173
-rw-r--r--railties/lib/rails/commands/test.rb9
-rw-r--r--railties/lib/rails/commands/test/test_command.rb20
-rw-r--r--railties/lib/rails/commands/version/version_command.rb9
26 files changed, 672 insertions, 725 deletions
diff --git a/railties/lib/rails/commands/application.rb b/railties/lib/rails/commands/application.rb
deleted file mode 100644
index c998e6b6a8..0000000000
--- a/railties/lib/rails/commands/application.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require 'rails/generators'
-require 'rails/generators/rails/app/app_generator'
-
-module Rails
- module Generators
- class AppGenerator # :nodoc:
- # We want to exit on failure to be kind to other libraries
- # This is only when accessing via CLI
- def self.exit_on_failure?
- true
- end
- end
- end
-end
-
-args = Rails::Generators::ARGVScrubber.new(ARGV).prepare!
-Rails::Generators::AppGenerator.start args
diff --git a/railties/lib/rails/commands/application/application_command.rb b/railties/lib/rails/commands/application/application_command.rb
new file mode 100644
index 0000000000..7675d3b3d1
--- /dev/null
+++ b/railties/lib/rails/commands/application/application_command.rb
@@ -0,0 +1,29 @@
+require "rails/generators"
+require "rails/generators/rails/app/app_generator"
+
+module Rails
+ module Generators
+ class AppGenerator # :nodoc:
+ # We want to exit on failure to be kind to other libraries
+ # This is only when accessing via CLI
+ def self.exit_on_failure?
+ true
+ end
+ end
+ end
+
+ module Command
+ class ApplicationCommand < Base # :nodoc:
+ hide_command!
+
+ def help
+ perform # Punt help output to the generator.
+ end
+
+ def perform(*args)
+ Rails::Generators::AppGenerator.start \
+ Rails::Generators::ARGVScrubber.new(args).prepare!
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/commands_tasks.rb b/railties/lib/rails/commands/commands_tasks.rb
deleted file mode 100644
index da3b9452d5..0000000000
--- a/railties/lib/rails/commands/commands_tasks.rb
+++ /dev/null
@@ -1,180 +0,0 @@
-require 'rails/commands/rake_proxy'
-
-module Rails
- # This is a class which takes in a rails command and initiates the appropriate
- # initiation sequence.
- #
- # Warning: This class mutates ARGV because some commands require manipulating
- # it before they are run.
- class CommandsTasks # :nodoc:
- include Rails::RakeProxy
-
- attr_reader :argv
-
- HELP_MESSAGE = <<-EOT
-Usage: rails COMMAND [ARGS]
-
-The most common rails commands are:
- generate Generate new code (short-cut alias: "g")
- console Start the Rails console (short-cut alias: "c")
- server Start the Rails server (short-cut alias: "s")
- test Run tests (short-cut alias: "t")
- dbconsole Start a console for the database specified in config/database.yml
- (short-cut alias: "db")
- new Create a new Rails application. "rails new my_app" creates a
- new application called MyApp in "./my_app"
-
-All commands can be run with -h (or --help) for more information.
-
-In addition to those commands, there are:
-EOT
-
- ADDITIONAL_COMMANDS = [
- [ 'destroy', 'Undo code generated with "generate" (short-cut alias: "d")' ],
- [ 'plugin new', 'Generates skeleton for developing a Rails plugin' ],
- [ 'runner',
- 'Run a piece of code in the application environment (short-cut alias: "r")' ]
- ]
-
- COMMAND_WHITELIST = %w(plugin generate destroy console server dbconsole runner new version help test)
-
- def initialize(argv)
- @argv = argv
- end
-
- def run_command!(command)
- command = parse_command(command)
-
- if COMMAND_WHITELIST.include?(command)
- send(command)
- else
- run_rake_task(command)
- end
- end
-
- def plugin
- require_command!("plugin")
- end
-
- def generate
- generate_or_destroy(:generate)
- end
-
- def destroy
- generate_or_destroy(:destroy)
- end
-
- def console
- require_command!("console")
- options = Rails::Console.parse_arguments(argv)
-
- # RAILS_ENV needs to be set before config/application is required
- ENV['RAILS_ENV'] = options[:environment] if options[:environment]
-
- # shift ARGV so IRB doesn't freak
- shift_argv!
-
- require_application_and_environment!
- Rails::Console.start(Rails.application, options)
- end
-
- def server
- set_application_directory!
- require_command!("server")
-
- Rails::Server.new.tap do |server|
- # We need to require application after the server sets environment,
- # otherwise the --environment option given to the server won't propagate.
- require APP_PATH
- Dir.chdir(Rails.application.root)
- server.start
- end
- end
-
- def test
- require_command!("test")
- end
-
- def dbconsole
- require_command!("dbconsole")
- Rails::DBConsole.start
- end
-
- def runner
- require_command!("runner")
- end
-
- def new
- if %w(-h --help).include?(argv.first)
- require_command!("application")
- else
- exit_with_initialization_warning!
- end
- end
-
- def version
- argv.unshift '--version'
- require_command!("application")
- end
-
- def help
- write_help_message
- write_commands ADDITIONAL_COMMANDS + formatted_rake_tasks
- end
-
- private
-
- def exit_with_initialization_warning!
- puts "Can't initialize a new Rails application within the directory of another, please change to a non-Rails directory first.\n"
- puts "Type 'rails' for help."
- exit(1)
- end
-
- def shift_argv!
- argv.shift if argv.first && argv.first[0] != '-'
- end
-
- def require_command!(command)
- require "rails/commands/#{command}"
- end
-
- def generate_or_destroy(command)
- require 'rails/generators'
- require_application_and_environment!
- Rails.application.load_generators
- require_command!(command)
- end
-
- # Change to the application's path if there is no config.ru file in current directory.
- # This allows us to run `rails server` from other directories, but still get
- # the main config.ru and properly set the tmp directory.
- def set_application_directory!
- Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exist?(File.expand_path("config.ru"))
- end
-
- def require_application_and_environment!
- require APP_PATH
- Rails.application.require_environment!
- end
-
- def write_help_message
- puts HELP_MESSAGE
- end
-
- def write_commands(commands)
- width = commands.map { |name, _| name.size }.max || 10
- commands.each { |command| printf(" %-#{width}s %s\n", *command) }
- end
-
- def parse_command(command)
- case command
- when '--version', '-v'
- 'version'
- when '--help', '-h'
- 'help'
- else
- command
- end
- end
- end
-end
diff --git a/railties/lib/rails/commands/console.rb b/railties/lib/rails/commands/console/console_command.rb
index a4ab31f793..62e3aa19df 100644
--- a/railties/lib/rails/commands/console.rb
+++ b/railties/lib/rails/commands/console/console_command.rb
@@ -1,12 +1,10 @@
-require 'optparse'
-require 'irb'
-require 'irb/completion'
-require 'rails/commands/console_helper'
+require "irb"
+require "irb/completion"
+
+require "rails/command/environment_argument"
module Rails
class Console
- include ConsoleHelper
-
module BacktraceCleaner
def filter_backtrace(bt)
if result = super
@@ -15,26 +13,13 @@ module Rails
end
end
- class << self
- def parse_arguments(arguments)
- options = {}
-
- OptionParser.new do |opt|
- opt.banner = "Usage: rails console [environment] [options]"
- opt.on('-s', '--sandbox', 'Rollback database modifications on exit.') { |v| options[:sandbox] = v }
- opt.on("-e", "--environment=name", String,
- "Specifies the environment to run this console under (test/development/production).",
- "Default: development") { |v| options[:environment] = v.strip }
- opt.parse!(arguments)
- end
-
- set_options_env(arguments, options)
- end
+ def self.start(*args)
+ new(*args).start
end
attr_reader :options, :app, :console
- def initialize(app, options={})
+ def initialize(app, options = {})
@app = app
@options = options
@@ -53,7 +38,7 @@ module Rails
end
def environment
- options[:environment] ||= super
+ options[:environment]
end
alias_method :environment?, :environment
@@ -77,4 +62,28 @@ module Rails
console.start
end
end
+
+ module Command
+ class ConsoleCommand < Base # :nodoc:
+ include EnvironmentArgument
+
+ class_option :sandbox, aliases: "-s", type: :boolean, default: false,
+ desc: "Rollback database modifications on exit."
+
+ class_option :environment, aliases: "-e", type: :string,
+ desc: "Specifies the environment to run this console under (test/development/production)."
+
+ def perform
+ extract_environment_option_from_argument
+
+ # RAILS_ENV needs to be set before config/application is required.
+ ENV["RAILS_ENV"] = options[:environment]
+
+ ARGV.clear # Clear ARGV so IRB doesn't freak.
+
+ require_application_and_environment!
+ Rails::Console.start(Rails.application, options)
+ end
+ end
+ end
end
diff --git a/railties/lib/rails/commands/console_helper.rb b/railties/lib/rails/commands/console_helper.rb
deleted file mode 100644
index 8ee0b60012..0000000000
--- a/railties/lib/rails/commands/console_helper.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-require 'active_support/concern'
-
-module Rails
- module ConsoleHelper # :nodoc:
- extend ActiveSupport::Concern
-
- module ClassMethods
- def start(*args)
- new(*args).start
- end
-
- private
- def set_options_env(arguments, options)
- if arguments.first && arguments.first[0] != '-'
- env = arguments.first
- if available_environments.include? env
- options[:environment] = env
- else
- options[:environment] = %w(production development test).detect { |e| e =~ /^#{env}/ } || env
- end
- end
- options
- end
-
- def available_environments
- Dir['config/environments/*.rb'].map { |fname| File.basename(fname, '.*') }
- end
- end
-
- def environment
- ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
- end
- end
-end \ No newline at end of file
diff --git a/railties/lib/rails/commands/dbconsole.rb b/railties/lib/rails/commands/dbconsole.rb
deleted file mode 100644
index 2c36edfa3f..0000000000
--- a/railties/lib/rails/commands/dbconsole.rb
+++ /dev/null
@@ -1,173 +0,0 @@
-require 'erb'
-require 'yaml'
-require 'optparse'
-require 'rails/commands/console_helper'
-
-module Rails
- class DBConsole
- include ConsoleHelper
-
- attr_reader :arguments
-
- class << self
- def parse_arguments(arguments)
- options = {}
-
- OptionParser.new do |opt|
- opt.banner = "Usage: rails dbconsole [environment] [options]"
- opt.on("-p", "--include-password", "Automatically provide the password from database.yml") do |v|
- options['include_password'] = true
- end
-
- opt.on("--mode [MODE]", ['html', 'list', 'line', 'column'],
- "Automatically put the sqlite3 database in the specified mode (html, list, line, column).") do |mode|
- options['mode'] = mode
- end
-
- opt.on("--header") do |h|
- options['header'] = h
- end
-
- opt.on("-h", "--help", "Show this help message.") do
- puts opt
- exit
- end
-
- opt.on("-e", "--environment=name", String,
- "Specifies the environment to run this console under (test/development/production).",
- "Default: development"
- ) { |v| options[:environment] = v.strip }
-
- opt.parse!(arguments)
- abort opt.to_s unless (0..1).include?(arguments.size)
- end
-
- set_options_env(arguments, options)
- end
- end
-
- def initialize(arguments = ARGV)
- @arguments = arguments
- end
-
- def start
- options = self.class.parse_arguments(arguments)
- ENV['RAILS_ENV'] = options[:environment] || environment
-
- case config["adapter"]
- when /^(jdbc)?mysql/
- args = {
- 'host' => '--host',
- 'port' => '--port',
- 'socket' => '--socket',
- 'username' => '--user',
- 'encoding' => '--default-character-set',
- 'sslca' => '--ssl-ca',
- 'sslcert' => '--ssl-cert',
- 'sslcapath' => '--ssl-capath',
- 'sslcipher' => '--ssl-cipher',
- 'sslkey' => '--ssl-key'
- }.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact
-
- if config['password'] && options['include_password']
- args << "--password=#{config['password']}"
- elsif config['password'] && !config['password'].to_s.empty?
- args << "-p"
- end
-
- args << config['database']
-
- find_cmd_and_exec(['mysql', 'mysql5'], *args)
-
- when /^postgres|^postgis/
- ENV['PGUSER'] = config["username"] if config["username"]
- ENV['PGHOST'] = config["host"] if config["host"]
- ENV['PGPORT'] = config["port"].to_s if config["port"]
- ENV['PGPASSWORD'] = config["password"].to_s if config["password"] && options['include_password']
- find_cmd_and_exec('psql', config["database"])
-
- when "sqlite3"
- args = []
-
- args << "-#{options['mode']}" if options['mode']
- args << "-header" if options['header']
- args << File.expand_path(config['database'], Rails.respond_to?(:root) ? Rails.root : nil)
-
- find_cmd_and_exec('sqlite3', *args)
-
- when "oracle", "oracle_enhanced"
- logon = ""
-
- if config['username']
- logon = config['username']
- logon << "/#{config['password']}" if config['password'] && options['include_password']
- logon << "@#{config['database']}" if config['database']
- end
-
- find_cmd_and_exec('sqlplus', logon)
-
- when "sqlserver"
- args = []
-
- args += ["-D", "#{config['database']}"] if config['database']
- args += ["-U", "#{config['username']}"] if config['username']
- args += ["-P", "#{config['password']}"] if config['password']
-
- if config['host']
- host_arg = "#{config['host']}"
- host_arg << ":#{config['port']}" if config['port']
- args += ["-S", host_arg]
- end
-
- find_cmd_and_exec("sqsh", *args)
-
- else
- abort "Unknown command-line client for #{config['database']}."
- end
- end
-
- def config
- @config ||= begin
- if configurations[environment].blank?
- raise ActiveRecord::AdapterNotSpecified, "'#{environment}' database is not configured. Available configuration: #{configurations.inspect}"
- else
- configurations[environment]
- end
- end
- end
-
- def environment
- Rails.respond_to?(:env) ? Rails.env : super
- end
-
- protected
- def configurations
- require APP_PATH
- ActiveRecord::Base.configurations = Rails.application.config.database_configuration
- ActiveRecord::Base.configurations
- end
-
- def find_cmd_and_exec(commands, *args)
- commands = Array(commands)
-
- dirs_on_path = ENV['PATH'].to_s.split(File::PATH_SEPARATOR)
- unless (ext = RbConfig::CONFIG['EXEEXT']).empty?
- commands = commands.map{|cmd| "#{cmd}#{ext}"}
- end
-
- full_path_command = nil
- found = commands.detect do |cmd|
- dirs_on_path.detect do |path|
- full_path_command = File.join(path, cmd)
- File.file?(full_path_command) && File.executable?(full_path_command)
- end
- end
-
- if found
- exec full_path_command, *args
- else
- abort("Couldn't find database client: #{commands.join(', ')}. Check your $PATH and try again.")
- end
- end
- end
-end
diff --git a/railties/lib/rails/commands/dbconsole/dbconsole_command.rb b/railties/lib/rails/commands/dbconsole/dbconsole_command.rb
new file mode 100644
index 0000000000..588fb06b15
--- /dev/null
+++ b/railties/lib/rails/commands/dbconsole/dbconsole_command.rb
@@ -0,0 +1,155 @@
+require "rails/command/environment_argument"
+
+module Rails
+ class DBConsole
+ def self.start(*args)
+ new(*args).start
+ end
+
+ def initialize(options = {})
+ @options = options
+ end
+
+ def start
+ ENV["RAILS_ENV"] = @options[:environment] || environment
+
+ case config["adapter"]
+ when /^(jdbc)?mysql/
+ args = {
+ "host" => "--host",
+ "port" => "--port",
+ "socket" => "--socket",
+ "username" => "--user",
+ "encoding" => "--default-character-set",
+ "sslca" => "--ssl-ca",
+ "sslcert" => "--ssl-cert",
+ "sslcapath" => "--ssl-capath",
+ "sslcipher" => "--ssl-cipher",
+ "sslkey" => "--ssl-key"
+ }.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact
+
+ if config["password"] && @options["include_password"]
+ args << "--password=#{config['password']}"
+ elsif config["password"] && !config["password"].to_s.empty?
+ args << "-p"
+ end
+
+ args << config["database"]
+
+ find_cmd_and_exec(["mysql", "mysql5"], *args)
+
+ when /^postgres|^postgis/
+ ENV["PGUSER"] = config["username"] if config["username"]
+ ENV["PGHOST"] = config["host"] if config["host"]
+ ENV["PGPORT"] = config["port"].to_s if config["port"]
+ ENV["PGPASSWORD"] = config["password"].to_s if config["password"] && @options["include_password"]
+ find_cmd_and_exec("psql", config["database"])
+
+ when "sqlite3"
+ args = []
+
+ args << "-#{@options['mode']}" if @options["mode"]
+ args << "-header" if @options["header"]
+ args << File.expand_path(config["database"], Rails.respond_to?(:root) ? Rails.root : nil)
+
+ find_cmd_and_exec("sqlite3", *args)
+
+ when "oracle", "oracle_enhanced"
+ logon = ""
+
+ if config["username"]
+ logon = config["username"]
+ logon << "/#{config['password']}" if config["password"] && @options["include_password"]
+ logon << "@#{config['database']}" if config["database"]
+ end
+
+ find_cmd_and_exec("sqlplus", logon)
+
+ when "sqlserver"
+ args = []
+
+ args += ["-D", "#{config['database']}"] if config["database"]
+ args += ["-U", "#{config['username']}"] if config["username"]
+ args += ["-P", "#{config['password']}"] if config["password"]
+
+ if config["host"]
+ host_arg = "#{config['host']}"
+ host_arg << ":#{config['port']}" if config["port"]
+ args += ["-S", host_arg]
+ end
+
+ find_cmd_and_exec("sqsh", *args)
+
+ else
+ abort "Unknown command-line client for #{config['database']}."
+ end
+ end
+
+ def config
+ @config ||= begin
+ if configurations[environment].blank?
+ raise ActiveRecord::AdapterNotSpecified, "'#{environment}' database is not configured. Available configuration: #{configurations.inspect}"
+ else
+ configurations[environment]
+ end
+ end
+ end
+
+ def environment
+ Rails.respond_to?(:env) ? Rails.env : Rails::Command.environment
+ end
+
+ private
+ def configurations # :doc:
+ require APP_PATH
+ ActiveRecord::Base.configurations = Rails.application.config.database_configuration
+ ActiveRecord::Base.configurations
+ end
+
+ def find_cmd_and_exec(commands, *args) # :doc:
+ commands = Array(commands)
+
+ dirs_on_path = ENV["PATH"].to_s.split(File::PATH_SEPARATOR)
+ unless (ext = RbConfig::CONFIG["EXEEXT"]).empty?
+ commands = commands.map { |cmd| "#{cmd}#{ext}" }
+ end
+
+ full_path_command = nil
+ found = commands.detect do |cmd|
+ dirs_on_path.detect do |path|
+ full_path_command = File.join(path, cmd)
+ File.file?(full_path_command) && File.executable?(full_path_command)
+ end
+ end
+
+ if found
+ exec full_path_command, *args
+ else
+ abort("Couldn't find database client: #{commands.join(', ')}. Check your $PATH and try again.")
+ end
+ end
+ end
+
+ module Command
+ class DbconsoleCommand < Base # :nodoc:
+ include EnvironmentArgument
+
+ class_option :include_password, aliases: "-p", type: :boolean,
+ desc: "Automatically provide the password from database.yml"
+
+ class_option :mode, enum: %w( html list line column ), type: :string,
+ desc: "Automatically put the sqlite3 database in the specified mode (html, list, line, column)."
+
+ class_option :header, type: :string
+
+ class_option :environment, aliases: "-e", type: :string,
+ desc: "Specifies the environment to run this console under (test/development/production)."
+
+ def perform
+ extract_environment_option_from_argument
+
+ Rails::DBConsole.start(options)
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/destroy.rb b/railties/lib/rails/commands/destroy.rb
deleted file mode 100644
index ce26cc3fde..0000000000
--- a/railties/lib/rails/commands/destroy.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require 'rails/generators'
-
-#if no argument/-h/--help is passed to rails destroy command, then
-#it generates the help associated.
-if [nil, "-h", "--help"].include?(ARGV.first)
- Rails::Generators.help 'destroy'
- exit
-end
-
-name = ARGV.shift
-Rails::Generators.invoke name, ARGV, behavior: :revoke, destination_root: Rails.root
diff --git a/railties/lib/rails/commands/destroy/destroy_command.rb b/railties/lib/rails/commands/destroy/destroy_command.rb
new file mode 100644
index 0000000000..5b552b2070
--- /dev/null
+++ b/railties/lib/rails/commands/destroy/destroy_command.rb
@@ -0,0 +1,21 @@
+require "rails/generators"
+
+module Rails
+ module Command
+ class DestroyCommand < Base # :nodoc:
+ def help
+ Rails::Generators.help self.class.command_name
+ end
+
+ def perform(*)
+ generator = args.shift
+ return help unless generator
+
+ require_application_and_environment!
+ Rails.application.load_generators
+
+ Rails::Generators.invoke generator, args, behavior: :revoke, destination_root: Rails.root
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/generate.rb b/railties/lib/rails/commands/generate.rb
deleted file mode 100644
index 926c36b967..0000000000
--- a/railties/lib/rails/commands/generate.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require 'rails/generators'
-
-#if no argument/-h/--help is passed to rails generate command, then
-#it generates the help associated.
-if [nil, "-h", "--help"].include?(ARGV.first)
- Rails::Generators.help 'generate'
- exit
-end
-
-name = ARGV.shift
-
-root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
-Rails::Generators.invoke name, ARGV, behavior: :invoke, destination_root: root
diff --git a/railties/lib/rails/commands/generate/generate_command.rb b/railties/lib/rails/commands/generate/generate_command.rb
new file mode 100644
index 0000000000..aa8dab71b0
--- /dev/null
+++ b/railties/lib/rails/commands/generate/generate_command.rb
@@ -0,0 +1,23 @@
+require "rails/generators"
+
+module Rails
+ module Command
+ class GenerateCommand < Base # :nodoc:
+ def help
+ Rails::Generators.help self.class.command_name
+ end
+
+ def perform(*)
+ generator = args.shift
+ return help unless generator
+
+ require_application_and_environment!
+ load_generators
+
+ ARGV.shift
+
+ Rails::Generators.invoke generator, args, behavior: :invoke, destination_root: Rails::Command.root
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/help/USAGE b/railties/lib/rails/commands/help/USAGE
new file mode 100644
index 0000000000..348f41861f
--- /dev/null
+++ b/railties/lib/rails/commands/help/USAGE
@@ -0,0 +1,27 @@
+Usage: bin/rails COMMAND [args] [options]
+<% if engine? %>
+The common Rails commands available for engines are:
+ generate Generate new code (short-cut alias: "g")
+ destroy Undo code generated with "generate" (short-cut alias: "d")
+ test Run tests (short-cut alias: "t")
+
+All commands can be run with -h for more information.
+
+If you want to run any commands that need to be run in context
+of the application, like `bin/rails server` or `bin/rails console`,
+you should do it from the application's directory (typically test/dummy).
+<% else %>
+The most common rails commands are:
+ generate Generate new code (short-cut alias: "g")
+ console Start the Rails console (short-cut alias: "c")
+ server Start the Rails server (short-cut alias: "s")
+ test Run tests (short-cut alias: "t")
+ dbconsole Start a console for the database specified in config/database.yml
+ (short-cut alias: "db")
+ new Create a new Rails application. "rails new my_app" creates a
+ new application called MyApp in "./my_app"
+
+All commands can be run with -h (or --help) for more information.
+<% end %>
+In addition to those commands, there are:
+
diff --git a/railties/lib/rails/commands/help/help_command.rb b/railties/lib/rails/commands/help/help_command.rb
new file mode 100644
index 0000000000..90d37217fc
--- /dev/null
+++ b/railties/lib/rails/commands/help/help_command.rb
@@ -0,0 +1,13 @@
+module Rails
+ module Command
+ class HelpCommand < Base # :nodoc:
+ hide_command!
+
+ def help(*)
+ puts self.class.desc
+
+ Rails::Command.print_commands
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/new/new_command.rb b/railties/lib/rails/commands/new/new_command.rb
new file mode 100644
index 0000000000..74d1fa5021
--- /dev/null
+++ b/railties/lib/rails/commands/new/new_command.rb
@@ -0,0 +1,15 @@
+module Rails
+ module Command
+ class NewCommand < Base # :nodoc:
+ def help
+ Rails::Command.invoke :application, [ "--help" ]
+ end
+
+ def perform(*)
+ puts "Can't initialize a new Rails application within the directory of another, please change to a non-Rails directory first.\n"
+ puts "Type 'rails' for help."
+ exit 1
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/plugin.rb b/railties/lib/rails/commands/plugin.rb
deleted file mode 100644
index 52d8966ead..0000000000
--- a/railties/lib/rails/commands/plugin.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-if ARGV.first != "new"
- ARGV[0] = "--help"
-else
- ARGV.shift
- unless ARGV.delete("--no-rc")
- customrc = ARGV.index{ |x| x.include?("--rc=") }
- railsrc = if customrc
- File.expand_path(ARGV.delete_at(customrc).gsub(/--rc=/, ""))
- else
- File.join(File.expand_path("~"), '.railsrc')
- end
- if File.exist?(railsrc)
- extra_args_string = File.read(railsrc)
- extra_args = extra_args_string.split(/\n+/).flat_map(&:split)
- puts "Using #{extra_args.join(" ")} from #{railsrc}"
- ARGV.insert(1, *extra_args)
- end
- end
-end
-
-require 'rails/generators'
-require 'rails/generators/rails/plugin/plugin_generator'
-Rails::Generators::PluginGenerator.start
diff --git a/railties/lib/rails/commands/plugin/plugin_command.rb b/railties/lib/rails/commands/plugin/plugin_command.rb
new file mode 100644
index 0000000000..b40ab006af
--- /dev/null
+++ b/railties/lib/rails/commands/plugin/plugin_command.rb
@@ -0,0 +1,43 @@
+module Rails
+ module Command
+ class PluginCommand < Base # :nodoc:
+ hide_command!
+
+ def help
+ run_plugin_generator %w( --help )
+ end
+
+ def self.banner(*) # :nodoc:
+ "#{executable} new [options]"
+ end
+
+ class_option :rc, type: :string, default: File.join("~", ".railsrc"),
+ desc: "Initialize the plugin command with previous defaults. Uses .railsrc in your home directory by default."
+
+ class_option :no_rc, desc: "Skip evaluating .railsrc."
+
+ def perform(type = nil, *plugin_args)
+ plugin_args << "--help" unless type == "new"
+
+ unless options.key?("no_rc") # Thor's not so indifferent access hash.
+ railsrc = File.expand_path(options[:rc])
+
+ if File.exist?(railsrc)
+ extra_args = File.read(railsrc).split(/\n+/).flat_map(&:split)
+ puts "Using #{extra_args.join(" ")} from #{railsrc}"
+ plugin_args.insert(1, *extra_args)
+ end
+ end
+
+ run_plugin_generator plugin_args
+ end
+
+ private
+ def run_plugin_generator(plugin_args)
+ require "rails/generators"
+ require "rails/generators/rails/plugin/plugin_generator"
+ Rails::Generators::PluginGenerator.start plugin_args
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/rake/rake_command.rb b/railties/lib/rails/commands/rake/rake_command.rb
new file mode 100644
index 0000000000..075b1fd23d
--- /dev/null
+++ b/railties/lib/rails/commands/rake/rake_command.rb
@@ -0,0 +1,49 @@
+module Rails
+ module Command
+ class RakeCommand < Base # :nodoc:
+ extend Rails::Command::Actions
+
+ namespace "rake"
+
+ class << self
+ def printing_commands
+ formatted_rake_tasks.map(&:first)
+ end
+
+ def perform(task, *)
+ require_rake
+
+ ARGV.unshift(task) # Prepend the task, so Rake knows how to run it.
+
+ Rake.application.standard_exception_handling do
+ Rake.application.init("rails")
+ Rake.application.load_rakefile
+ Rake.application.top_level
+ end
+ end
+
+ private
+ def rake_tasks
+ require_rake
+
+ return @rake_tasks if defined?(@rake_tasks)
+
+ require_application_and_environment!
+
+ Rake::TaskManager.record_task_metadata = true
+ Rake.application.instance_variable_set(:@name, "rails")
+ load_tasks
+ @rake_tasks = Rake.application.tasks.select(&:comment)
+ end
+
+ def formatted_rake_tasks
+ rake_tasks.map { |t| [ t.name_with_args, t.comment ] }
+ end
+
+ def require_rake
+ require "rake" # Defer booting Rake until we know it's needed.
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/rake_proxy.rb b/railties/lib/rails/commands/rake_proxy.rb
deleted file mode 100644
index f7d5df6b2f..0000000000
--- a/railties/lib/rails/commands/rake_proxy.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-require 'rake'
-require 'active_support'
-
-module Rails
- module RakeProxy #:nodoc:
- private
- def run_rake_task(command)
- ARGV.unshift(command) # Prepend the command, so Rake knows how to run it.
-
- Rake.application.standard_exception_handling do
- Rake.application.init('rails')
- Rake.application.load_rakefile
- Rake.application.top_level
- end
- end
-
- def rake_tasks
- return @rake_tasks if defined?(@rake_tasks)
-
- ActiveSupport::Deprecation.silence do
- require_application_and_environment!
- end
-
- Rake::TaskManager.record_task_metadata = true
- Rake.application.instance_variable_set(:@name, 'rails')
- Rails.application.load_tasks
- @rake_tasks = Rake.application.tasks.select(&:comment)
- end
-
- def formatted_rake_tasks
- rake_tasks.map { |t| [ t.name_with_args, t.comment ] }
- end
- end
-end
diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb
deleted file mode 100644
index f9c183ac86..0000000000
--- a/railties/lib/rails/commands/runner.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-require 'optparse'
-
-options = { environment: (ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development").dup }
-code_or_file = nil
-command = 'bin/rails runner'
-
-if ARGV.first.nil?
- ARGV.push "-h"
-end
-
-ARGV.clone.options do |opts|
- opts.banner = "Usage: rails runner [options] [<'Some.ruby(code)'> | <filename.rb>]"
-
- opts.separator ""
-
- opts.on("-e", "--environment=name", String,
- "Specifies the environment for the runner to operate under (test/development/production).",
- "Default: development") { |v| options[:environment] = v }
-
- opts.separator ""
-
- opts.on("-h", "--help",
- "Show this help message.") { $stdout.puts opts; exit }
-
- opts.separator ""
- opts.separator "Examples: "
-
- opts.separator " rails runner 'puts Rails.env'"
- opts.separator " This runs the code `puts Rails.env` after loading the app"
- opts.separator ""
- opts.separator " rails runner path/to/filename.rb"
- opts.separator " This runs the Ruby file located at `path/to/filename.rb` after loading the app"
-
- if RbConfig::CONFIG['host_os'] !~ /mswin|mingw/
- opts.separator ""
- opts.separator "You can also use runner as a shebang line for your executables:"
- opts.separator " -------------------------------------------------------------"
- opts.separator " #!/usr/bin/env #{File.expand_path(command)}"
- opts.separator ""
- opts.separator " Product.all.each { |p| p.price *= 2 ; p.save! }"
- opts.separator " -------------------------------------------------------------"
- end
-
- opts.order! { |o| code_or_file ||= o } rescue retry
-end
-
-ARGV.delete(code_or_file)
-
-ENV["RAILS_ENV"] = options[:environment]
-
-require APP_PATH
-Rails.application.require_environment!
-Rails.application.load_runner
-
-if code_or_file.nil?
- $stderr.puts "Run '#{command} -h' for help."
- exit 1
-elsif File.exist?(code_or_file)
- $0 = code_or_file
- Kernel.load code_or_file
-else
- begin
- eval(code_or_file, binding, __FILE__, __LINE__)
- rescue SyntaxError, NameError
- $stderr.puts "Please specify a valid ruby command or the path of a script to run."
- $stderr.puts "Run '#{command} -h' for help."
- exit 1
- end
-end
diff --git a/railties/lib/rails/commands/runner/USAGE b/railties/lib/rails/commands/runner/USAGE
new file mode 100644
index 0000000000..b2a6e8493d
--- /dev/null
+++ b/railties/lib/rails/commands/runner/USAGE
@@ -0,0 +1,17 @@
+Examples:
+
+Run `puts Rails.env` after loading the app:
+
+ <%= executable %> 'puts Rails.env'
+
+Run the Ruby file located at `path/to/filename.rb` after loading the app:
+
+ <%= executable %> path/to/filename.rb
+
+<% unless Gem.win_platform? %>
+You can also use the runner command as a shebang line for your executables:
+
+ #!/usr/bin/env <%= File.expand_path(executable) %>
+
+ Product.all.each { |p| p.price *= 2 ; p.save! }
+<% end %>
diff --git a/railties/lib/rails/commands/runner/runner_command.rb b/railties/lib/rails/commands/runner/runner_command.rb
new file mode 100644
index 0000000000..4989a7837d
--- /dev/null
+++ b/railties/lib/rails/commands/runner/runner_command.rb
@@ -0,0 +1,46 @@
+module Rails
+ module Command
+ class RunnerCommand < Base # :nodoc:
+ class_option :environment, aliases: "-e", type: :string,
+ default: Rails::Command.environment.dup,
+ desc: "The environment for the runner to operate under (test/development/production)"
+
+ def help
+ super
+ puts self.class.desc
+ end
+
+ def self.banner(*)
+ "#{super} [<'Some.ruby(code)'> | <filename.rb>]"
+ end
+
+ def perform(code_or_file = nil, *file_argv)
+ unless code_or_file
+ help
+ exit 1
+ end
+
+ ENV["RAILS_ENV"] = options[:environment]
+
+ require_application_and_environment!
+ Rails.application.load_runner
+
+ if File.exist?(code_or_file)
+ $0 = code_or_file
+ ARGV.replace(file_argv)
+ Kernel.load code_or_file
+ else
+ begin
+ eval(code_or_file, binding, __FILE__, __LINE__)
+ rescue SyntaxError, NameError => error
+ $stderr.puts "Please specify a valid ruby command or the path of a script to run."
+ $stderr.puts "Run '#{self.class.executable} -h' for help."
+ $stderr.puts
+ $stderr.puts error
+ exit 1
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
deleted file mode 100644
index 7418dff18b..0000000000
--- a/railties/lib/rails/commands/server.rb
+++ /dev/null
@@ -1,139 +0,0 @@
-require 'fileutils'
-require 'optparse'
-require 'action_dispatch'
-require 'rails'
-require 'rails/dev_caching'
-
-module Rails
- class Server < ::Rack::Server
- class Options
- DEFAULT_PID_PATH = File.expand_path("tmp/pids/server.pid").freeze
-
- def parse!(args)
- args, options = args.dup, {}
-
- option_parser(options).parse! args
-
- options[:log_stdout] = options[:daemonize].blank? && (options[:environment] || Rails.env) == "development"
- options[:server] = args.shift
- options
- end
-
- private
-
- def option_parser(options)
- OptionParser.new do |opts|
- opts.banner = "Usage: rails server [mongrel, thin etc] [options]"
- opts.on("-p", "--port=port", Integer,
- "Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v }
- opts.on("-b", "--binding=IP", String,
- "Binds Rails to the specified IP.", "Default: localhost") { |v| options[:Host] = v }
- opts.on("-c", "--config=file", String,
- "Uses a custom rackup configuration.") { |v| options[:config] = v }
- opts.on("-d", "--daemon", "Runs server as a Daemon.") { options[:daemonize] = true }
- opts.on("-e", "--environment=name", String,
- "Specifies the environment to run this server under (test/development/production).",
- "Default: development") { |v| options[:environment] = v }
- opts.on("-P", "--pid=pid", String,
- "Specifies the PID file.",
- "Default: tmp/pids/server.pid") { |v| options[:pid] = v }
- opts.on("-C", "--[no-]dev-caching",
- "Specifies whether to perform caching in development.",
- "true or false") { |v| options[:caching] = v }
-
- opts.separator ""
-
- opts.on("-h", "--help", "Shows this help message.") { puts opts; exit }
- end
- end
- end
-
- def initialize(*)
- super
- set_environment
- end
-
- # TODO: this is no longer required but we keep it for the moment to support older config.ru files.
- def app
- @app ||= begin
- app = super
- app.respond_to?(:to_app) ? app.to_app : app
- end
- end
-
- def opt_parser
- Options.new
- end
-
- def set_environment
- ENV["RAILS_ENV"] ||= options[:environment]
- end
-
- def start
- print_boot_information
- trap(:INT) { exit }
- create_tmp_directories
- setup_dev_caching
- log_to_stdout if options[:log_stdout]
-
- super
- ensure
- # The '-h' option calls exit before @options is set.
- # If we call 'options' with it unset, we get double help banners.
- puts 'Exiting' unless @options && options[:daemonize]
- end
-
- def middleware
- Hash.new([])
- end
-
- def default_options
- super.merge({
- Port: ENV.fetch('PORT', 3000).to_i,
- DoNotReverseLookup: true,
- environment: (ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development").dup,
- daemonize: false,
- caching: nil,
- pid: Options::DEFAULT_PID_PATH,
- restart_cmd: restart_command
- })
- end
-
- private
-
- def setup_dev_caching
- if options[:environment] == "development"
- Rails::DevCaching.enable_by_argument(options[:caching])
- end
- end
-
- def print_boot_information
- url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}"
- puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
- puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}"
- puts "=> Run `rails server -h` for more startup options"
- end
-
- def create_tmp_directories
- %w(cache pids sockets).each do |dir_to_make|
- FileUtils.mkdir_p(File.join(Rails.root, 'tmp', dir_to_make))
- end
- end
-
- def log_to_stdout
- wrapped_app # touch the app so the logger is set up
-
- console = ActiveSupport::Logger.new(STDOUT)
- console.formatter = Rails.logger.formatter
- console.level = Rails.logger.level
-
- unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDOUT)
- Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
- end
- end
-
- def restart_command
- "bin/rails server #{ARGV.join(' ')}"
- end
- end
-end
diff --git a/railties/lib/rails/commands/server/server_command.rb b/railties/lib/rails/commands/server/server_command.rb
new file mode 100644
index 0000000000..15c636103b
--- /dev/null
+++ b/railties/lib/rails/commands/server/server_command.rb
@@ -0,0 +1,173 @@
+require "fileutils"
+require "optparse"
+require "action_dispatch"
+require "rails"
+require "rails/dev_caching"
+
+module Rails
+ class Server < ::Rack::Server
+ class Options
+ def parse!(args)
+ Rails::Command::ServerCommand.new([], args).server_options
+ end
+ end
+
+ def initialize(options = nil)
+ @default_options = options || {}
+ super(@default_options)
+ set_environment
+ end
+
+ # TODO: this is no longer required but we keep it for the moment to support older config.ru files.
+ def app
+ @app ||= begin
+ app = super
+ app.respond_to?(:to_app) ? app.to_app : app
+ end
+ end
+
+ def opt_parser
+ Options.new
+ end
+
+ def set_environment
+ ENV["RAILS_ENV"] ||= options[:environment]
+ end
+
+ def start
+ print_boot_information
+ trap(:INT) { exit }
+ create_tmp_directories
+ setup_dev_caching
+ log_to_stdout if options[:log_stdout]
+
+ super
+ ensure
+ # The '-h' option calls exit before @options is set.
+ # If we call 'options' with it unset, we get double help banners.
+ puts "Exiting" unless @options && options[:daemonize]
+ end
+
+ def middleware
+ Hash.new([])
+ end
+
+ def default_options
+ super.merge(@default_options)
+ end
+
+ private
+ def setup_dev_caching
+ if options[:environment] == "development"
+ Rails::DevCaching.enable_by_argument(options[:caching])
+ end
+ end
+
+ def print_boot_information
+ url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}"
+ puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
+ puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}"
+ puts "=> Run `rails server -h` for more startup options"
+ end
+
+ def create_tmp_directories
+ %w(cache pids sockets).each do |dir_to_make|
+ FileUtils.mkdir_p(File.join(Rails.root, "tmp", dir_to_make))
+ end
+ end
+
+ def log_to_stdout
+ wrapped_app # touch the app so the logger is set up
+
+ console = ActiveSupport::Logger.new(STDOUT)
+ console.formatter = Rails.logger.formatter
+ console.level = Rails.logger.level
+
+ unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDOUT)
+ Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
+ end
+ end
+
+ def restart_command
+ "bin/rails server #{ARGV.join(' ')}"
+ end
+ end
+
+ module Command
+ class ServerCommand < Base # :nodoc:
+ DEFAULT_PID_PATH = File.expand_path("tmp/pids/server.pid").freeze
+
+ class_option :port, aliases: "-p", type: :numeric,
+ desc: "Runs Rails on the specified port.", banner: :port, default: 3000
+ class_option :binding, aliases: "-b", type: :string, default: "localhost",
+ desc: "Binds Rails to the specified IP.", banner: :IP
+ class_option :config, aliases: "-c", type: :string, default: "config.ru",
+ desc: "Uses a custom rackup configuration.", banner: :file
+ class_option :daemon, aliases: "-d", type: :boolean, default: false,
+ desc: "Runs server as a Daemon."
+ class_option :environment, aliases: "-e", type: :string,
+ desc: "Specifies the environment to run this server under (development/test/production).", banner: :name
+ class_option :pid, aliases: "-P", type: :string, default: DEFAULT_PID_PATH,
+ desc: "Specifies the PID file."
+ class_option "dev-caching", aliases: "-C", type: :boolean, default: nil,
+ desc: "Specifies whether to perform caching in development."
+
+ def initialize(args = [], local_options = {}, config = {})
+ @original_options = local_options
+ super
+ @server = self.args.shift
+ @log_stdout = options[:daemon].blank? && (options[:environment] || Rails.env) == "development"
+ end
+
+ def perform
+ set_application_directory!
+ Rails::Server.new(server_options).tap do |server|
+ # Require application after server sets environment to propagate
+ # the --environment option.
+ require APP_PATH
+ Dir.chdir(Rails.application.root)
+ server.start
+ end
+ end
+
+ no_commands do
+ def server_options
+ {
+ server: @server,
+ log_stdout: @log_stdout,
+ Port: port,
+ Host: host,
+ DoNotReverseLookup: true,
+ config: options[:config],
+ environment: environment,
+ daemonize: options[:daemon],
+ pid: options[:pid],
+ caching: options["dev-caching"],
+ restart_cmd: restart_command
+ }
+ end
+ end
+
+ private
+ def port
+ ENV.fetch("PORT", options[:port]).to_i
+ end
+
+ def host
+ ENV.fetch("HOST", options[:binding])
+ end
+
+ def environment
+ options[:environment] || Rails::Command.environment
+ end
+
+ def restart_command
+ "bin/rails server #{@server} #{@original_options.join(" ")}"
+ end
+
+ def self.banner(*)
+ "rails server [puma, thin etc] [options]"
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/test.rb b/railties/lib/rails/commands/test.rb
deleted file mode 100644
index dd069f081f..0000000000
--- a/railties/lib/rails/commands/test.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require "rails/test_unit/minitest_plugin"
-
-if defined?(ENGINE_ROOT)
- $: << File.expand_path('test', ENGINE_ROOT)
-else
- $: << File.expand_path('../../test', APP_PATH)
-end
-
-exit Minitest.run(ARGV)
diff --git a/railties/lib/rails/commands/test/test_command.rb b/railties/lib/rails/commands/test/test_command.rb
new file mode 100644
index 0000000000..7bf8f61137
--- /dev/null
+++ b/railties/lib/rails/commands/test/test_command.rb
@@ -0,0 +1,20 @@
+require "rails/command"
+require "rails/test_unit/minitest_plugin"
+
+module Rails
+ module Command
+ class TestCommand < Base # :nodoc:
+ def help
+ perform # Hand over help printing to minitest.
+ end
+
+ def perform(*)
+ $LOAD_PATH << Rails::Command.root.join("test")
+
+ Minitest.run_via[:rails] = true
+
+ require "active_support/testing/autorun"
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/version/version_command.rb b/railties/lib/rails/commands/version/version_command.rb
new file mode 100644
index 0000000000..ac745594ee
--- /dev/null
+++ b/railties/lib/rails/commands/version/version_command.rb
@@ -0,0 +1,9 @@
+module Rails
+ module Command
+ class VersionCommand < Base # :nodoc:
+ def perform
+ Rails::Command.invoke :application, [ "--version" ]
+ end
+ end
+ end
+end