Refactor EnvironmentArgument to be automatic

This commit refactors `Rails::Command::EnvironmentArgument` to
automatically set an appropriate value for `options[:environment]`, even
when the `--environment` option is omitted.  Additionally,
`EnvironmentArgument` will automatically set `ENV["RAILS_ENV"]` when
`require_application!` (or `require_application_and_environment!`) is
called.
This commit is contained in:
Jonathan Hefner 2023-01-19 11:22:41 -06:00
parent bcc1eb727b
commit dad25b69fb
10 changed files with 42 additions and 71 deletions

View File

@ -9,31 +9,47 @@ module Rails
extend ActiveSupport::Concern
included do
no_commands do
class_attribute :environment_desc, default: "Specifies the environment to run this #{self.command_name} under (test/development/production)."
class_option :environment, aliases: "-e", type: :string,
desc: "The environment to run `#{self.command_name}` in (e.g. test / development / production)."
end
def initialize(...)
super
@environment_specified = options[:environment].present?
if !@environment_specified
self.options = options.merge(environment: Rails::Command.environment)
elsif !available_environments.include?(options[:environment])
self.options = options.merge(environment: expand_environment_name(options[:environment]))
end
class_option :environment, aliases: "-e", type: :string, desc: environment_desc
end
private
def extract_environment_option_from_argument(default_environment: Rails::Command.environment)
if options[:environment]
self.options = options.merge(environment: acceptable_environment(options[:environment]))
else
self.options = options.merge(environment: default_environment)
end
def require_application!
ENV["RAILS_ENV"] = environment
super
end
def acceptable_environment(env = nil)
if available_environments.include? env
env
else
%w( production development test ).detect { |e| /^#{env}/.match?(e) } || env
end
def environment
@environment ||= options[:environment]
end
def environment=(environment)
@environment = environment
end
def environment_specified?
@environment_specified
end
def available_environments
Dir["config/environments/*.rb"].map { |fname| File.basename(fname, ".*") }
@available_environments ||=
Dir["config/environments/*.rb"].map { |filename| File.basename(filename, ".*") }
end
def expand_environment_name(name)
%w[production development test].find { |full_name| full_name.start_with?(name) } || name
end
end
end

View File

@ -97,11 +97,6 @@ module Rails
end
def perform
extract_environment_option_from_argument
# RAILS_ENV needs to be set before config/application is required.
ENV["RAILS_ENV"] = options[:environment]
require_application_and_environment!
Rails::Console.start(Rails.application, options)
end

View File

@ -24,19 +24,16 @@ module Rails
desc "edit", "Opens the decrypted credentials in `$EDITOR` for editing"
def edit
environment_specified = options[:environment].present?
extract_environment_option_from_argument
ENV["RAILS_ENV"] = options[:environment]
require_application!
load_generators
if environment_specified
@content_path = "config/credentials/#{options[:environment]}.yml.enc" unless config.key?(:content_path)
@key_path = "config/credentials/#{options[:environment]}.key" unless config.key?(:key_path)
if environment_specified?
@content_path = "config/credentials/#{environment}.yml.enc" unless config.key?(:content_path)
@key_path = "config/credentials/#{environment}.key" unless config.key?(:key_path)
end
ensure_encryption_key_has_been_added
ensure_credentials_have_been_added(environment_specified)
ensure_credentials_have_been_added
ensure_diffing_driver_is_configured
change_credentials_in_system_editor
@ -44,8 +41,6 @@ module Rails
desc "show", "Shows the decrypted credentials"
def show
extract_environment_option_from_argument
ENV["RAILS_ENV"] = options[:environment]
require_application!
say credentials.read.presence || missing_credentials_message
@ -60,8 +55,7 @@ module Rails
desc "diff", "Enrolls/disenrolls in decrypted diffs of credentials using git"
def diff(content_path = nil)
if @content_path = content_path
extract_environment_option_from_argument(default_environment: extract_environment_from_path(content_path))
ENV["RAILS_ENV"] = options[:environment]
self.environment = extract_environment_from_path(content_path)
require_application!
say credentials.read.presence || credentials.content_path.read
@ -100,12 +94,12 @@ module Rails
encryption_key_file_generator.ignore_key_file(key_path)
end
def ensure_credentials_have_been_added(environment_specified)
def ensure_credentials_have_been_added
require "rails/generators/rails/credentials/credentials_generator"
Rails::Generators::CredentialsGenerator.new(
[content_path, key_path],
skip_secret_key_base: environment_specified && %w[development test].include?(options[:environment]),
skip_secret_key_base: environment_specified? && %w[development test].include?(environment),
quiet: true
).invoke_all
end

View File

@ -89,11 +89,6 @@ module Rails
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]
require_application_and_environment!
Rails::DBConsole.start(options)
end

View File

@ -9,9 +9,6 @@ module Rails
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|

View File

@ -7,8 +7,6 @@ module Rails
class RunnerCommand < Base # :nodoc:
include EnvironmentArgument
self.environment_desc = "The environment for the runner to operate under (test/development/production)"
no_commands do
def help
super
@ -22,15 +20,11 @@ module Rails
desc "runner", "Runs Ruby code in the context of your application"
def perform(code_or_file = nil, *command_argv)
extract_environment_option_from_argument
unless code_or_file
help
exit 1
end
ENV["RAILS_ENV"] = options[:environment]
require_application_and_environment!
Rails.application.load_runner

View File

@ -129,7 +129,6 @@ module Rails
end
def perform
extract_environment_option_from_argument
set_application_directory!
prepare_restart

View File

@ -184,8 +184,6 @@ class Rails::ConsoleTest < ActiveSupport::TestCase
end
def parse_arguments(args)
command = Rails::Command::ConsoleCommand.new([], args)
command.send(:extract_environment_option_from_argument)
command.options
Rails::Command::ConsoleCommand.new([], args).options
end
end

View File

@ -246,21 +246,6 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
end
def parse_arguments(args)
Rails::Command::DbconsoleCommand.class_eval do
alias_method :old_perform, :perform
define_method(:perform) do
extract_environment_option_from_argument
options
end
end
Rails::Command.invoke(:dbconsole, args)
ensure
Rails::Command::DbconsoleCommand.class_eval do
undef_method :perform
alias_method :perform, :old_perform
undef_method :old_perform
end
Rails::Command::DbconsoleCommand.new([], args).options
end
end

View File

@ -303,8 +303,6 @@ class Rails::Command::ServerCommandTest < ActiveSupport::TestCase
end
def parse_arguments(args = [])
command = Rails::Command::ServerCommand.new([], args)
command.send(:extract_environment_option_from_argument)
command.server_options
Rails::Command::ServerCommand.new([], args).server_options
end
end