Skip to content

Commit

Permalink
use Thor option parser in server commands parse
Browse files Browse the repository at this point in the history
The `ServerCommand` inherits Thor, but currently does not use Thor
option parser.
Therefore, if leave the argument of Thor as it is, it becomes an error by
the argument checking of Thor.
To avoid it, to use the Thor option parser instead of reimplementing it.

Fixes #26964
  • Loading branch information
y-yagi committed Dec 24, 2016
1 parent 4e73ffa commit 6547042
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 90 deletions.
121 changes: 67 additions & 54 deletions railties/lib/rails/commands/server/server_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,14 @@
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

def option_parser(options) # :nodoc:
OptionParser.new do |opts|
opts.banner = "Usage: rails server [puma, thin etc] [options]"

opts.separator ""
opts.separator "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
Rails::Command::ServerCommand.new([], args).server_options
end
end

def initialize(*)
super
def initialize(options = nil)
@default_options = options || {}
super(@default_options)
set_environment
end

Expand Down Expand Up @@ -90,15 +53,7 @@ def middleware
end

def default_options
super.merge(
Port: ENV.fetch("PORT", 3000).to_i,
Host: ENV.fetch("HOST", "localhost").dup,
DoNotReverseLookup: true,
environment: (ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development").dup,
daemonize: false,
caching: nil,
pid: Options::DEFAULT_PID_PATH,
restart_cmd: restart_command)
super.merge(@default_options)
end

private
Expand Down Expand Up @@ -140,21 +95,79 @@ def restart_command

module Command
class ServerCommand < Base # :nodoc:
def help
puts Rails::Server::Options.new.option_parser(Hash.new)
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.tap do |server|
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
79 changes: 43 additions & 36 deletions railties/test/commands/server_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,137 +7,144 @@ class Rails::ServerTest < ActiveSupport::TestCase
include EnvHelpers

def test_environment_with_server_option
args = ["thin", "-e", "production"]
options = Rails::Server::Options.new.parse!(args)
args = ["thin", "-e", "production"]
options = parse_arguments(args)
assert_equal "production", options[:environment]
assert_equal "thin", options[:server]
end

def test_environment_without_server_option
args = ["-e", "production"]
options = Rails::Server::Options.new.parse!(args)
args = ["-e", "production"]
options = parse_arguments(args)
assert_equal "production", options[:environment]
assert_nil options[:server]
end

def test_server_option_without_environment
args = ["thin"]
options = Rails::Server::Options.new.parse!(args)
assert_nil options[:environment]
assert_equal "thin", options[:server]
args = ["thin"]
with_rack_env nil do
with_rails_env nil do
options = parse_arguments(args)
assert_equal "development", options[:environment]
assert_equal "thin", options[:server]
end
end
end

def test_environment_with_rails_env
with_rack_env nil do
with_rails_env "production" do
server = Rails::Server.new
assert_equal "production", server.options[:environment]
options = parse_arguments
assert_equal "production", options[:environment]
end
end
end

def test_environment_with_rack_env
with_rails_env nil do
with_rack_env "production" do
server = Rails::Server.new
assert_equal "production", server.options[:environment]
options = parse_arguments
assert_equal "production", options[:environment]
end
end
end

def test_environment_with_port
switch_env "PORT", "1234" do
server = Rails::Server.new
assert_equal 1234, server.options[:Port]
options = parse_arguments
assert_equal 1234, options[:Port]
end
end

def test_environment_with_host
switch_env "HOST", "1.2.3.4" do
server = Rails::Server.new
assert_equal "1.2.3.4", server.options[:Host]
options = parse_arguments
assert_equal "1.2.3.4", options[:Host]
end
end

def test_caching_without_option
args = []
options = Rails::Server::Options.new.parse!(args)
merged_options = Rails::Server.new.default_options.merge(options)
assert_equal nil, merged_options[:caching]
options = parse_arguments(args)
assert_equal nil, options[:caching]
end

def test_caching_with_option
args = ["--dev-caching"]
options = Rails::Server::Options.new.parse!(args)
options = parse_arguments(args)
assert_equal true, options[:caching]

args = ["--no-dev-caching"]
options = Rails::Server::Options.new.parse!(args)
options = parse_arguments(args)
assert_equal false, options[:caching]
end

def test_log_stdout
with_rack_env nil do
with_rails_env nil do
args = []
options = Rails::Server::Options.new.parse!(args)
options = parse_arguments(args)
assert_equal true, options[:log_stdout]

args = ["-e", "development"]
options = Rails::Server::Options.new.parse!(args)
options = parse_arguments(args)
assert_equal true, options[:log_stdout]

args = ["-e", "production"]
options = Rails::Server::Options.new.parse!(args)
options = parse_arguments(args)
assert_equal false, options[:log_stdout]

with_rack_env "development" do
args = []
options = Rails::Server::Options.new.parse!(args)
options = parse_arguments(args)
assert_equal true, options[:log_stdout]
end

with_rack_env "production" do
args = []
options = Rails::Server::Options.new.parse!(args)
options = parse_arguments(args)
assert_equal false, options[:log_stdout]
end

with_rails_env "development" do
args = []
options = Rails::Server::Options.new.parse!(args)
options = parse_arguments(args)
assert_equal true, options[:log_stdout]
end

with_rails_env "production" do
args = []
options = Rails::Server::Options.new.parse!(args)
options = parse_arguments(args)
assert_equal false, options[:log_stdout]
end
end
end
end

def test_default_options
server = Rails::Server.new
old_default_options = server.default_options
old_default_options = parse_arguments

Dir.chdir("..") do
assert_equal old_default_options, server.default_options
default_options = parse_arguments
assert_equal old_default_options, default_options
end
end

def test_restart_command_contains_customized_options
original_args = ARGV.dup
args = ["-p", "4567"]
args = %w(-p 4567 -b 127.0.0.1 -c dummy_config.ru -d -e test -P tmp/server.pid -C)
ARGV.replace args

options = Rails::Server::Options.new.parse! args
server = Rails::Server.new options
expected = "bin/rails server -p 4567"
options = parse_arguments(args)
expected = "bin/rails server -p 4567 -b 127.0.0.1 -c dummy_config.ru -d -e test -P tmp/server.pid -C"

assert_equal expected, server.default_options[:restart_cmd]
assert_equal expected, options[:restart_cmd]
ensure
ARGV.replace original_args
end

private
def parse_arguments(args = [])
Rails::Command::ServerCommand.new([], args).server_options
end
end

0 comments on commit 6547042

Please sign in to comment.