Skip to content
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

Allow to pass a connection to the dbconsole command #29358

Merged
merged 3 commits into from Jul 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions railties/CHANGELOG.md
@@ -1,3 +1,29 @@
* Properly expand shortcuts for environment's name running the `console`
and `dbconsole` commands.

*Robin Dupret*

* Passing the environment's name as a regular argument to the
`rails dbconsole` and `rails console` commands is deprecated.
The `-e` option should be used instead.

Previously:

$ bin/rails dbconsole production

Now:

$ bin/rails dbconsole -e production

*Robin Dupret*, *Kasper Timm Hansen*

* Allow to pass a custom connection name to the `rails dbconsole`
command when using a 3-level database configuration.

$ bin/rails dbconsole -c replica

*Robin Dupret*, *Jeremy Daer*

* Skip unused components when running `bin/rails app:update`.

If the initial app generation skipped Action Cable, Active Record etc.,
Expand Down
13 changes: 12 additions & 1 deletion railties/lib/rails/command/environment_argument.rb
Expand Up @@ -7,13 +7,24 @@ module EnvironmentArgument #:nodoc:

included do
argument :environment, optional: true, banner: "environment"

class_option :environment, aliases: "-e", type: :string,
desc: "Specifies the environment to run this console under (test/development/production)."
end

private
def extract_environment_option_from_argument
if environment
self.options = options.merge(environment: acceptable_environment(environment))
elsif !options[:environment]

ActiveSupport::Deprecation.warn "Passing the environment's name as a " \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much cleaner to have this straight in here 👏

"regular argument is deprecated and " \
"will be removed in the next Rails " \
"version. Please, use the -e option " \
"instead."
elsif options[:environment]
self.options = options.merge(environment: acceptable_environment(options[:environment]))
else
self.options = options.merge(environment: Rails::Command.environment)
end
end
Expand Down
3 changes: 0 additions & 3 deletions railties/lib/rails/commands/console/console_command.rb
Expand Up @@ -70,9 +70,6 @@ class ConsoleCommand < Base # :nodoc:
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 initialize(args = [], local_options = {}, config = {})
console_options = []

Expand Down
17 changes: 13 additions & 4 deletions railties/lib/rails/commands/dbconsole/dbconsole_command.rb
Expand Up @@ -87,10 +87,15 @@ def start

def config
@config ||= begin
if configurations[environment].blank?
# We need to check whether the user passed the connection 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?
raise ActiveRecord::AdapterNotSpecified, "'#{environment}' database is not configured. Available configuration: #{configurations.inspect}"
else
configurations[environment]
configurations[environment].presence || configurations[connection]
end
end
end
Expand All @@ -99,6 +104,10 @@ def environment
Rails.respond_to?(:env) ? Rails.env : Rails::Command.environment
end

def connection
@options.fetch(:connection, "primary")
end

private
def configurations # :doc:
require APP_PATH
Expand Down Expand Up @@ -142,8 +151,8 @@ class DbconsoleCommand < Base # :nodoc:

class_option :header, type: :boolean

class_option :environment, aliases: "-e", type: :string,
desc: "Specifies the environment to run this console under (test/development/production)."
class_option :connection, aliases: "-c", type: :string,
desc: "Specifies the connection to use."

def perform
extract_environment_option_from_argument
Expand Down
29 changes: 21 additions & 8 deletions railties/test/commands/console_test.rb
Expand Up @@ -47,7 +47,7 @@ def test_start_with_sandbox
end

def test_console_with_environment
start ["-e production"]
start ["-e", "production"]
assert_match(/\sproduction\s/, output)
end

Expand Down Expand Up @@ -82,24 +82,35 @@ def test_e_option
assert_match(/\sspecial-production\s/, output)
end

def test_e_option_is_properly_expanded
start ["-e", "prod"]
assert_match(/\sproduction\s/, output)
end

def test_environment_option
start ["--environment=special-production"]
assert_match(/\sspecial-production\s/, output)
end

def test_rails_env_is_production_when_first_argument_is_p
start ["p"]
assert_match(/\sproduction\s/, output)
assert_deprecated do
start ["p"]
assert_match(/\sproduction\s/, output)
end
end

def test_rails_env_is_test_when_first_argument_is_t
start ["t"]
assert_match(/\stest\s/, output)
assert_deprecated do
start ["t"]
assert_match(/\stest\s/, output)
end
end

def test_rails_env_is_development_when_argument_is_d
start ["d"]
assert_match(/\sdevelopment\s/, output)
assert_deprecated do
start ["d"]
assert_match(/\sdevelopment\s/, output)
end
end

def test_rails_env_is_dev_when_argument_is_dev_and_dev_env_is_present
Expand All @@ -111,7 +122,9 @@ def test_rails_env_is_dev_when_argument_is_dev_and_dev_env_is_present
end
end

assert_match("dev", parse_arguments(["dev"])[:environment])
assert_deprecated do
assert_match("dev", parse_arguments(["dev"])[:environment])
end
ensure
Rails::Command::ConsoleCommand.class_eval do
undef_method :available_environments
Expand Down
59 changes: 56 additions & 3 deletions railties/test/commands/dbconsole_test.rb
Expand Up @@ -98,14 +98,24 @@ def test_env
end

def test_rails_env_is_development_when_argument_is_dev
assert_deprecated do
stub_available_environments([ "development", "test" ]) do
assert_match("development", parse_arguments([ "dev" ])[:environment])
end
end
end

def test_rails_env_is_development_when_environment_option_is_dev
stub_available_environments([ "development", "test" ]) do
assert_match("development", parse_arguments([ "dev" ])[:environment])
assert_match("development", parse_arguments([ "-e", "dev" ])[:environment])
end
end

def test_rails_env_is_dev_when_argument_is_dev_and_dev_env_is_present
stub_available_environments([ "dev" ]) do
assert_match("dev", parse_arguments([ "dev" ])[:environment])
assert_deprecated do
stub_available_environments([ "dev" ]) do
assert_match("dev", parse_arguments([ "dev" ])[:environment])
end
end
end

Expand Down Expand Up @@ -200,6 +210,49 @@ def test_unknown_command_line_client
assert_match(/Unknown command-line client for db/, output)
end

def test_primary_is_automatically_picked_with_3_level_configuration
sample_config = {
"test" => {
"primary" => {
"adapter" => "postgresql"
}
}
}

app_db_config(sample_config) do
assert_equal "postgresql", Rails::DBConsole.new.config["adapter"]
end
end

def test_specifying_a_custom_connection_and_environment
stub_available_environments(["development"]) do
dbconsole = parse_arguments(["-c", "custom", "-e", "development"])

assert_equal "development", dbconsole[:environment]
assert_equal "custom", dbconsole.connection
end
end

def test_specifying_a_missing_connection
app_db_config({}) do
e = assert_raises(ActiveRecord::AdapterNotSpecified) do
Rails::Command.invoke(:dbconsole, ["-c", "i_do_not_exist"])
end

assert_includes e.message, "'i_do_not_exist' connection is not configured."
end
end

def test_specifying_a_missing_environment
app_db_config({}) do
e = assert_raises(ActiveRecord::AdapterNotSpecified) do
Rails::Command.invoke(:dbconsole)
end

assert_includes e.message, "'test' database is not configured."
end
end

def test_print_help_short
stdout = capture(:stdout) do
Rails::Command.invoke(:dbconsole, ["-h"])
Expand Down