New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use Thor option parser in server commands parse #26977
Conversation
r? @pixeltrix (@rails-bot has picked a reviewer for you, use r? to override) |
r? @kaspth |
Can we use the Thor option parser instead of reimplementing it? |
If I am not mistaken, it is possible. I will try. |
794b098
to
4597b09
Compare
def initialize(*) | ||
super | ||
def initialize(options = nil) | ||
super(options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does not only super
work here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not. See my comment about Rack::Server
interop.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we keep the default in the description?
class_option :port, aliases: "-p", type: :numeric, | ||
desc: "Runs Rails on the specified port.", banner: :port | ||
class_option :binding, aliases: "-b", type: :string, | ||
desc: "Binds Rails to the specified IP.", banner: :IP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing about the default
private | ||
|
||
def parse_arguments(args) | ||
Rails::Command::ServerCommand.class_eval do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you can asset those things only initializing a command object. Rails::Command::ServerCommand.new
should expose everything you can.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, I had to do something similar for the other commands. But if we can make it happen, great 👍
end | ||
|
||
def environment | ||
options[:environment] || (ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote a Rails::Command.environment
method for this.
end | ||
|
||
def restart_command | ||
"bin/rails server #{ARGV.join(' ')}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the command infrastructure guarantees argv to be unharmed. We should add one test that uses every option and ensures every one option is present in the rerun command.
ensure | ||
ARGV.replace original_args | ||
end | ||
|
||
private | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✂️
private | ||
|
||
def parse_arguments(args) | ||
Rails::Command::ServerCommand.class_eval do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, I had to do something similar for the other commands. But if we can make it happen, great 👍
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 (test/development/production).", banner: :name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(development/test/production)
is the usual order we'd write this in.
@@ -89,18 +41,6 @@ def middleware | |||
Hash.new([]) | |||
end | |||
|
|||
def default_options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I didn't pursue writing these options using Thor in the first place was that Rails::Server
interops with Rack::Server
in certain ways as seen by the super
here.
Thus, since some of the methods you removed were also public, I figured they were part of Rails::Server
's public API and to remove them we'd need to go through a deprecation cycle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for pointing out!
I fixed that Rails::Server
's public API can be used as before. How about that?
def initialize(*) | ||
super | ||
def initialize(options = nil) | ||
super(options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not. See my comment about Rack::Server
interop.
options | ||
end | ||
|
||
def option_parser(options) # :nodoc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also a method that's overriden from Rack::Server
.
@kasper's the best person to review this.
|
My bad, looks like this PR is fixing only the |
@guilleiguaran correct. I'll handle the |
I was misunderstanding. Option parser is necessary even in the rack server. Therefore, I restored |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think we're getting close ✌️
end | ||
|
||
def restart_command | ||
"bin/rails server #{ARGV.join(' ')}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to be careful when mentioning ARGV
in commands. I think this should be:
"bin/rails server #{@server} #{args.join(" ")}"
(Note that it needs to use double quoted strings here too.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this context, the args
variable does not contain any arguments.
Therefore, kept the argument in the constructor and used it.
# Require application after server sets environment to propagate | ||
# the --environment option. | ||
require APP_PATH | ||
Dir.chdir(Rails.application.root) | ||
server.start | ||
end | ||
end | ||
|
||
def server_options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Thor any public instance method is a command, so we'd need to wrap this in a no_commands do
block.
def initialize(*) | ||
super | ||
def initialize(options = nil) | ||
@default_options = options.nil? ? {} : options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about this? @default_options = options || {}
|
||
def option_parser(options) # :nodoc: | ||
OptionParser.new do |opts| | ||
opts.banner = "Usage: rails server [puma, thin etc] [options]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we port over the server argument with this:
argument :server, optional: true, banner: '[puma, thin etc]'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If argument
used, need to specify the "server" argument twice to specify server(e.g. ./bin/rails server server webrick
).
Therefore, override .banner
instead.
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 rails#26964
Thanks for reviewing! I updated commit! |
Way cool, thanks! |
Thanks!! |
I am running Rails 5.1.1 and I get an error that looks like the same thing. What am I missing? To fix this, I worked another dev and we updated the Gemfile.lock and I changed, under railties, thor (~> 0.20.0), then I ran #bundle update thor , then I was able to execute the rails command above. |
`optparse` is unused since rails#26977.
Summary
In master, when start rails server with arguments, it will fail.
The
ServerCommand
inherits Thor, but it does not use Thor is theparse of the argument.
Therefore, if leave the argument of Thor as it is, it becomes an error by the
argument checking of Thor.
To avoid it, to clear the argument of Thor.
Fixes #26964