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/console/console_command.rb6
-rw-r--r--railties/lib/rails/commands/credentials/USAGE20
-rw-r--r--railties/lib/rails/commands/credentials/credentials_command.rb75
-rw-r--r--railties/lib/rails/commands/db/system/change/change_command.rb20
-rw-r--r--railties/lib/rails/commands/dbconsole/dbconsole_command.rb28
-rw-r--r--railties/lib/rails/commands/dev/dev_command.rb17
-rw-r--r--railties/lib/rails/commands/encrypted/USAGE28
-rw-r--r--railties/lib/rails/commands/encrypted/encrypted_command.rb5
-rw-r--r--railties/lib/rails/commands/help/help_command.rb2
-rw-r--r--railties/lib/rails/commands/initializers/initializers_command.rb23
-rw-r--r--railties/lib/rails/commands/new/new_command.rb4
-rw-r--r--railties/lib/rails/commands/plugin/plugin_command.rb2
-rw-r--r--railties/lib/rails/commands/runner/runner_command.rb22
-rw-r--r--railties/lib/rails/commands/secrets/USAGE6
-rw-r--r--railties/lib/rails/commands/secrets/secrets_command.rb6
-rw-r--r--railties/lib/rails/commands/server/server_command.rb34
16 files changed, 225 insertions, 73 deletions
diff --git a/railties/lib/rails/commands/console/console_command.rb b/railties/lib/rails/commands/console/console_command.rb
index e35faa5b01..7a9eaefea1 100644
--- a/railties/lib/rails/commands/console/console_command.rb
+++ b/railties/lib/rails/commands/console/console_command.rb
@@ -26,6 +26,12 @@ module Rails
@options = options
app.sandbox = sandbox?
+
+ if sandbox? && app.config.disable_sandbox
+ puts "Error: Unable to start console in sandbox mode as sandbox mode is disabled (config.disable_sandbox is true)."
+ exit 1
+ end
+
app.load_console
@console = app.config.console || IRB
diff --git a/railties/lib/rails/commands/credentials/USAGE b/railties/lib/rails/commands/credentials/USAGE
index 85877c71b7..c8d3fb9eda 100644
--- a/railties/lib/rails/commands/credentials/USAGE
+++ b/railties/lib/rails/commands/credentials/USAGE
@@ -14,7 +14,7 @@ that just contains the secret_key_base used by MessageVerifiers/MessageEncryptor
signing and encrypting cookies.
For applications created prior to Rails 5.2, we'll automatically generate a new
-credentials file in `config/credentials.yml.enc` the first time you run `bin/rails credentials:edit`.
+credentials file in `config/credentials.yml.enc` the first time you run `rails credentials:edit`.
If you didn't have a master key saved in `config/master.key`, that'll be created too.
Don't lose this master key! Put it in a password manager your team can access.
@@ -38,3 +38,21 @@ the encrypted credentials.
When the temporary file is next saved the contents are encrypted and written to
`config/credentials.yml.enc` while the file itself is destroyed to prevent credentials
from leaking.
+
+=== Environment Specific Credentials
+
+The `credentials` command supports passing an `--environment` option to create an
+environment specific override. That override will take precedence over the
+global `config/credentials.yml.enc` file when running in that environment. So:
+
+ rails credentials:edit --environment development
+
+will create `config/credentials/development.yml.enc` with the corresponding
+encryption key in `config/credentials/development.key` if the credentials file
+doesn't exist.
+
+The encryption key can also be put in `ENV["RAILS_MASTER_KEY"]`, which takes
+precedence over the file encryption key.
+
+In addition to that, the default credentials lookup paths can be overridden through
+`config.credentials.content_path` and `config.credentials.key_path`.
diff --git a/railties/lib/rails/commands/credentials/credentials_command.rb b/railties/lib/rails/commands/credentials/credentials_command.rb
index fa54c0362a..e23a1b3008 100644
--- a/railties/lib/rails/commands/credentials/credentials_command.rb
+++ b/railties/lib/rails/commands/credentials/credentials_command.rb
@@ -2,11 +2,15 @@
require "active_support"
require "rails/command/helpers/editor"
+require "rails/command/environment_argument"
module Rails
module Command
class CredentialsCommand < Rails::Command::Base # :nodoc:
include Helpers::Editor
+ include EnvironmentArgument
+
+ self.environment_desc = "Uses credentials from config/credentials/:environment.yml.enc encrypted by config/credentials/:environment.key key"
no_commands do
def help
@@ -17,47 +21,84 @@ module Rails
end
def edit
- require_application_and_environment!
+ extract_environment_option_from_argument(default_environment: nil)
+ require_application!
ensure_editor_available(command: "bin/rails credentials:edit") || (return)
- ensure_master_key_has_been_added if Rails.application.credentials.key.nil?
+
+ ensure_encryption_key_has_been_added if credentials.key.nil?
ensure_credentials_have_been_added
catch_editing_exceptions do
change_credentials_in_system_editor
end
- say "New credentials encrypted and saved."
+ say "File encrypted and saved."
+ rescue ActiveSupport::MessageEncryptor::InvalidMessage
+ say "Couldn't decrypt #{content_path}. Perhaps you passed the wrong key?"
end
def show
- require_application_and_environment!
+ extract_environment_option_from_argument(default_environment: nil)
+ require_application!
- say Rails.application.credentials.read.presence || missing_credentials_message
+ say credentials.read.presence || missing_credentials_message
end
private
- def ensure_master_key_has_been_added
- master_key_generator.add_master_key_file
- master_key_generator.ignore_master_key_file
+ def credentials
+ Rails.application.encrypted(content_path, key_path: key_path)
+ end
+
+ def ensure_encryption_key_has_been_added
+ encryption_key_file_generator.add_key_file(key_path)
+ encryption_key_file_generator.ignore_key_file(key_path)
end
def ensure_credentials_have_been_added
- credentials_generator.add_credentials_file_silently
+ if options[:environment]
+ encrypted_file_generator.add_encrypted_file_silently(content_path, key_path)
+ else
+ credentials_generator.add_credentials_file_silently
+ end
end
def change_credentials_in_system_editor
- Rails.application.credentials.change do |tmp_path|
+ credentials.change do |tmp_path|
system("#{ENV["EDITOR"]} #{tmp_path}")
end
end
+ def missing_credentials_message
+ if credentials.key.nil?
+ "Missing '#{key_path}' to decrypt credentials. See `rails credentials:help`"
+ else
+ "File '#{content_path}' does not exist. Use `rails credentials:edit` to change that."
+ end
+ end
+
+
+ def content_path
+ options[:environment] ? "config/credentials/#{options[:environment]}.yml.enc" : "config/credentials.yml.enc"
+ end
- def master_key_generator
+ def key_path
+ options[:environment] ? "config/credentials/#{options[:environment]}.key" : "config/master.key"
+ end
+
+
+ def encryption_key_file_generator
+ require "rails/generators"
+ require "rails/generators/rails/encryption_key_file/encryption_key_file_generator"
+
+ Rails::Generators::EncryptionKeyFileGenerator.new
+ end
+
+ def encrypted_file_generator
require "rails/generators"
- require "rails/generators/rails/master_key/master_key_generator"
+ require "rails/generators/rails/encrypted_file/encrypted_file_generator"
- Rails::Generators::MasterKeyGenerator.new
+ Rails::Generators::EncryptedFileGenerator.new
end
def credentials_generator
@@ -66,14 +107,6 @@ module Rails
Rails::Generators::CredentialsGenerator.new
end
-
- def missing_credentials_message
- if Rails.application.credentials.key.nil?
- "Missing master key to decrypt credentials. See bin/rails credentials:help"
- else
- "No credentials have been added yet. Use bin/rails credentials:edit to change that."
- end
- end
end
end
end
diff --git a/railties/lib/rails/commands/db/system/change/change_command.rb b/railties/lib/rails/commands/db/system/change/change_command.rb
new file mode 100644
index 0000000000..760c229c07
--- /dev/null
+++ b/railties/lib/rails/commands/db/system/change/change_command.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require "rails/generators"
+require "rails/generators/rails/db/system/change/change_generator"
+
+module Rails
+ module Command
+ module Db
+ module System
+ class ChangeCommand < Base # :nodoc:
+ class_option :to, desc: "The database system to switch to."
+
+ def perform
+ Rails::Generators::Db::System::ChangeGenerator.start
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/dbconsole/dbconsole_command.rb b/railties/lib/rails/commands/dbconsole/dbconsole_command.rb
index 806b7de6d6..72f3235ce3 100644
--- a/railties/lib/rails/commands/dbconsole/dbconsole_command.rb
+++ b/railties/lib/rails/commands/dbconsole/dbconsole_command.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/deprecation"
+require "active_support/core_ext/string/filters"
require "rails/command/environment_argument"
module Rails
@@ -75,7 +77,7 @@ module Rails
args += ["-P", "#{config['password']}"] if config["password"]
if config["host"]
- host_arg = "#{config['host']}".dup
+ host_arg = +"#{config['host']}"
host_arg << ":#{config['port']}" if config["port"]
args += ["-S", host_arg]
end
@@ -89,15 +91,15 @@ module Rails
def config
@config ||= begin
- # We need to check whether the user passed the connection the
+ # We need to check whether the user passed the database the
# first time around to show a consistent error message to people
# relying on 2-level database configuration.
- if @options["connection"] && configurations[connection].blank?
- raise ActiveRecord::AdapterNotSpecified, "'#{connection}' connection is not configured. Available configuration: #{configurations.inspect}"
- elsif configurations[environment].blank? && configurations[connection].blank?
+ if @options["database"] && configurations[database].blank?
+ raise ActiveRecord::AdapterNotSpecified, "'#{database}' database is not configured. Available configuration: #{configurations.inspect}"
+ elsif configurations[environment].blank? && configurations[database].blank?
raise ActiveRecord::AdapterNotSpecified, "'#{environment}' database is not configured. Available configuration: #{configurations.inspect}"
else
- configurations[connection] || configurations[environment].presence
+ configurations[database] || configurations[environment].presence
end
end
end
@@ -106,8 +108,8 @@ module Rails
Rails.respond_to?(:env) ? Rails.env : Rails::Command.environment
end
- def connection
- @options.fetch(:connection, "primary")
+ def database
+ @options.fetch(:database, "primary")
end
private
@@ -156,12 +158,22 @@ module Rails
class_option :connection, aliases: "-c", type: :string,
desc: "Specifies the connection to use."
+ class_option :database, aliases: "--db", type: :string,
+ desc: "Specifies the database to use."
+
def perform
extract_environment_option_from_argument
# RAILS_ENV needs to be set before config/application is required.
ENV["RAILS_ENV"] = options[:environment]
+ if options["connection"]
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ `connection` option is deprecated and will be removed in Rails 6.1. Please use `database` option instead.
+ MSG
+ options["database"] = options["connection"]
+ end
+
require_application_and_environment!
Rails::DBConsole.start(options)
end
diff --git a/railties/lib/rails/commands/dev/dev_command.rb b/railties/lib/rails/commands/dev/dev_command.rb
new file mode 100644
index 0000000000..a3f02f3172
--- /dev/null
+++ b/railties/lib/rails/commands/dev/dev_command.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require "rails/dev_caching"
+
+module Rails
+ module Command
+ class DevCommand < Base # :nodoc:
+ def help
+ say "rails dev:cache # Toggle development mode caching on/off."
+ end
+
+ def cache
+ Rails::DevCaching.enable_by_file
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/encrypted/USAGE b/railties/lib/rails/commands/encrypted/USAGE
new file mode 100644
index 0000000000..253eec2378
--- /dev/null
+++ b/railties/lib/rails/commands/encrypted/USAGE
@@ -0,0 +1,28 @@
+=== Storing Encrypted Files in Source Control
+
+The Rails `encrypted` commands provide access to encrypted files or configurations.
+See the `Rails.application.encrypted` documentation for using them in your app.
+
+=== Encryption Keys
+
+By default, Rails looks for the encryption key in `config/master.key` or
+`ENV["RAILS_MASTER_KEY"]`, but that lookup can be overridden with `--key`:
+
+ rails encrypted:edit config/encrypted_file.yml.enc --key config/encrypted_file.key
+
+Don't commit the key! Add it to your source control's ignore file. If you use
+Git, Rails handles this for you.
+
+=== Editing Files
+
+To edit or create an encrypted file use:
+
+ rails encrypted:edit config/encrypted_file.yml.enc
+
+This opens a temporary file in `$EDITOR` with the decrypted contents for editing.
+
+=== Viewing Files
+
+To print the decrypted contents of an encrypted file use:
+
+ rails encrypted:show config/encrypted_file.yml.enc
diff --git a/railties/lib/rails/commands/encrypted/encrypted_command.rb b/railties/lib/rails/commands/encrypted/encrypted_command.rb
index 3bc8f76ce4..f10a07cdf8 100644
--- a/railties/lib/rails/commands/encrypted/encrypted_command.rb
+++ b/railties/lib/rails/commands/encrypted/encrypted_command.rb
@@ -16,6 +16,7 @@ module Rails
def help
say "Usage:\n #{self.class.banner}"
say ""
+ say self.class.desc
end
end
@@ -76,9 +77,9 @@ module Rails
def missing_encrypted_message(key:, key_path:, file_path:)
if key.nil?
- "Missing '#{key_path}' to decrypt data. See bin/rails encrypted:help"
+ "Missing '#{key_path}' to decrypt data. See `rails encrypted:help`"
else
- "File '#{file_path}' does not exist. Use bin/rails encrypted:edit #{file_path} to change that."
+ "File '#{file_path}' does not exist. Use `rails encrypted:edit #{file_path}` to change that."
end
end
end
diff --git a/railties/lib/rails/commands/help/help_command.rb b/railties/lib/rails/commands/help/help_command.rb
index 8e5b4d68d3..9df34e9b79 100644
--- a/railties/lib/rails/commands/help/help_command.rb
+++ b/railties/lib/rails/commands/help/help_command.rb
@@ -6,7 +6,7 @@ module Rails
hide_command!
def help(*)
- puts self.class.desc
+ say self.class.desc
Rails::Command.print_commands
end
diff --git a/railties/lib/rails/commands/initializers/initializers_command.rb b/railties/lib/rails/commands/initializers/initializers_command.rb
new file mode 100644
index 0000000000..bd2f3bed67
--- /dev/null
+++ b/railties/lib/rails/commands/initializers/initializers_command.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require "rails/command/environment_argument"
+
+module Rails
+ module Command
+ class InitializersCommand < Base # :nodoc:
+ include EnvironmentArgument
+
+ desc "initializers", "Print out all defined initializers in the order they are invoked by Rails."
+ def perform
+ extract_environment_option_from_argument
+ ENV["RAILS_ENV"] = options[:environment]
+
+ require_application_and_environment!
+
+ Rails.application.initializers.tsort_each do |initializer|
+ say "#{initializer.context_class}.#{initializer.name}"
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/new/new_command.rb b/railties/lib/rails/commands/new/new_command.rb
index d73d64d899..a4f2081510 100644
--- a/railties/lib/rails/commands/new/new_command.rb
+++ b/railties/lib/rails/commands/new/new_command.rb
@@ -10,8 +10,8 @@ module Rails
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."
+ say "Can't initialize a new Rails application within the directory of another, please change to a non-Rails directory first.\n"
+ say "Type 'rails' for help."
exit 1
end
end
diff --git a/railties/lib/rails/commands/plugin/plugin_command.rb b/railties/lib/rails/commands/plugin/plugin_command.rb
index 2b192abf9b..96187aa952 100644
--- a/railties/lib/rails/commands/plugin/plugin_command.rb
+++ b/railties/lib/rails/commands/plugin/plugin_command.rb
@@ -26,7 +26,7 @@ module Rails
if File.exist?(railsrc)
extra_args = File.read(railsrc).split(/\n+/).flat_map(&:split)
- puts "Using #{extra_args.join(" ")} from #{railsrc}"
+ say "Using #{extra_args.join(" ")} from #{railsrc}"
plugin_args.insert(1, *extra_args)
end
end
diff --git a/railties/lib/rails/commands/runner/runner_command.rb b/railties/lib/rails/commands/runner/runner_command.rb
index 30fbf04982..40fb5e4d89 100644
--- a/railties/lib/rails/commands/runner/runner_command.rb
+++ b/railties/lib/rails/commands/runner/runner_command.rb
@@ -1,16 +1,18 @@
# frozen_string_literal: true
+require "rails/command/environment_argument"
+
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)"
+ include EnvironmentArgument
+
+ self.environment_desc = "The environment for the runner to operate under (test/development/production)"
no_commands do
def help
super
- puts self.class.desc
+ say self.class.desc
end
end
@@ -19,6 +21,8 @@ module Rails
end
def perform(code_or_file = nil, *command_argv)
+ extract_environment_option_from_argument
+
unless code_or_file
help
exit 1
@@ -39,11 +43,11 @@ module Rails
else
begin
eval(code_or_file, TOPLEVEL_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
+ rescue SyntaxError, NameError => e
+ error "Please specify a valid ruby command or the path of a script to run."
+ error "Run '#{self.class.executable} -h' for help."
+ error ""
+ error e
exit 1
end
end
diff --git a/railties/lib/rails/commands/secrets/USAGE b/railties/lib/rails/commands/secrets/USAGE
index 96e322fe91..e205cdc001 100644
--- a/railties/lib/rails/commands/secrets/USAGE
+++ b/railties/lib/rails/commands/secrets/USAGE
@@ -7,7 +7,7 @@ with the code.
=== Setup
-Run `bin/rails secrets:setup` to opt in and generate the `config/secrets.yml.key`
+Run `rails secrets:setup` to opt in and generate the `config/secrets.yml.key`
and `config/secrets.yml.enc` files.
The latter contains all the keys to be encrypted while the former holds the
@@ -45,12 +45,12 @@ the key. Add this:
config.read_encrypted_secrets = true
-to the environment you'd like to read encrypted secrets. `bin/rails secrets:setup`
+to the environment you'd like to read encrypted secrets. `rails secrets:setup`
inserts this into the production environment by default.
=== Editing Secrets
-After `bin/rails secrets:setup`, run `bin/rails secrets:edit`.
+After `rails secrets:setup`, run `rails secrets:edit`.
That command opens a temporary file in `$EDITOR` with the decrypted contents of
`config/secrets.yml.enc` to edit the encrypted secrets.
diff --git a/railties/lib/rails/commands/secrets/secrets_command.rb b/railties/lib/rails/commands/secrets/secrets_command.rb
index a36ccf314c..2eebc0f35f 100644
--- a/railties/lib/rails/commands/secrets/secrets_command.rb
+++ b/railties/lib/rails/commands/secrets/secrets_command.rb
@@ -22,7 +22,7 @@ module Rails
if ENV["EDITOR"].to_s.empty?
say "No $EDITOR to open decrypted secrets in. Assign one like this:"
say ""
- say %(EDITOR="mate --wait" bin/rails secrets:edit)
+ say %(EDITOR="mate --wait" rails secrets:edit)
say ""
say "For editors that fork and exit immediately, it's important to pass a wait flag,"
say "otherwise the secrets will be saved immediately with no chance to edit."
@@ -42,7 +42,7 @@ module Rails
rescue Rails::Secrets::MissingKeyError => error
say error.message
rescue Errno::ENOENT => error
- if error.message =~ /secrets\.yml\.enc/
+ if /secrets\.yml\.enc/.match?(error.message)
deprecate_in_favor_of_credentials_and_exit
else
raise
@@ -56,7 +56,7 @@ module Rails
private
def deprecate_in_favor_of_credentials_and_exit
say "Encrypted secrets is deprecated in favor of credentials. Run:"
- say "bin/rails credentials:help"
+ say "rails credentials:help"
exit 1
end
diff --git a/railties/lib/rails/commands/server/server_command.rb b/railties/lib/rails/commands/server/server_command.rb
index 2c5440d9ec..982b83ead5 100644
--- a/railties/lib/rails/commands/server/server_command.rb
+++ b/railties/lib/rails/commands/server/server_command.rb
@@ -6,6 +6,7 @@ require "rails"
require "active_support/deprecation"
require "active_support/core_ext/string/filters"
require "rails/dev_caching"
+require "rails/command/environment_argument"
module Rails
class Server < ::Rack::Server
@@ -21,19 +22,6 @@ module Rails
set_environment
end
- def app
- @app ||= begin
- app = super
- if app.is_a?(Class)
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
- Using `Rails::Application` subclass to start the server is deprecated and will be removed in Rails 6.0.
- Please change `run #{app}` to `run Rails.application` in config.ru.
- MSG
- end
- app.respond_to?(:to_app) ? app.to_app : app
- end
- end
-
def opt_parser
Options.new
end
@@ -104,12 +92,14 @@ module Rails
module Command
class ServerCommand < Base # :nodoc:
+ include EnvironmentArgument
+
# Hard-coding a bunch of handlers here as we don't have a public way of
# querying them from the Rack::Handler registry.
RACK_SERVERS = %w(cgi fastcgi webrick lsws scgi thin puma unicorn)
DEFAULT_PORT = 3000
- DEFAULT_PID_PATH = "tmp/pids/server.pid".freeze
+ DEFAULT_PID_PATH = "tmp/pids/server.pid"
argument :using, optional: true
@@ -122,8 +112,6 @@ module Rails
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 :using, aliases: "-u", type: :string,
desc: "Specifies the Rack server used to run the application (thin/puma/webrick).", banner: :name
class_option :pid, aliases: "-P", type: :string, default: DEFAULT_PID_PATH,
@@ -143,6 +131,7 @@ module Rails
end
def perform
+ extract_environment_option_from_argument
set_application_directory!
prepare_restart
@@ -234,8 +223,8 @@ module Rails
if ENV["HOST"] && !ENV["BINDING"]
ActiveSupport::Deprecation.warn(<<-MSG.squish)
- Using the `HOST` environment to specify the IP is deprecated and will be removed in Rails 6.1.
- Please use `BINDING` environment instead.
+ Using the `HOST` environment variable to specify the IP is deprecated and will be removed in Rails 6.1.
+ Please use `BINDING` environment variable instead.
MSG
return ENV["HOST"]
@@ -268,7 +257,7 @@ module Rails
end
def self.banner(*)
- "rails server [thin/puma/webrick] [options]"
+ "rails server -u [thin/puma/webrick] [options]"
end
def prepare_restart
@@ -277,7 +266,7 @@ module Rails
def deprecate_positional_rack_server_and_rewrite_to_option(original_options)
if using
- ActiveSupport::Deprecation.warn(<<~MSG)
+ ActiveSupport::Deprecation.warn(<<~MSG.squish)
Passing the Rack server name as a regular argument is deprecated
and will be removed in the next Rails version. Please, use the -u
option instead.
@@ -286,7 +275,7 @@ module Rails
original_options.concat [ "-u", using ]
else
# Use positional internally to get around Thor's immutable options.
- # TODO: Replace `using` occurences with `options[:using]` after deprecation removal.
+ # TODO: Replace `using` occurrences with `options[:using]` after deprecation removal.
@using = options[:using]
end
end
@@ -302,9 +291,10 @@ module Rails
MSG
else
suggestion = Rails::Command::Spellchecker.suggest(server, from: RACK_SERVERS)
+ suggestion_msg = "Maybe you meant #{suggestion.inspect}?" if suggestion
<<~MSG
- Could not find server "#{server}". Maybe you meant #{suggestion.inspect}?
+ Could not find server "#{server}". #{suggestion_msg}
Run `rails server --help` for more options.
MSG
end