diff options
Diffstat (limited to 'railties/lib/rails/commands/credentials')
3 files changed, 53 insertions, 38 deletions
diff --git a/railties/lib/rails/commands/credentials/USAGE b/railties/lib/rails/commands/credentials/USAGE index c8d3fb9eda..6b896ab02a 100644 --- a/railties/lib/rails/commands/credentials/USAGE +++ b/railties/lib/rails/commands/credentials/USAGE @@ -30,6 +30,21 @@ You could prepend that to your server's start command like this: RAILS_MASTER_KEY="very-secret-and-secure" server.start +=== Set up Git to Diff Credentials + +Rails provides `rails credentials:diff --enable` to instruct Git to call `rails credentials:diff` +when `git diff` is run on a credentials file. + +Running the command enrolls the project such that all credentials files use the +"rails_credentials" diff driver in .gitattributes. + +Additionally since Git requires the driver itself to be set up in a config file +that isn't tracked Rails automatically ensures it's configured when running +`credentials:edit`. + +Otherwise each co-worker would have to run enable manually, including on each new +repo clone. + === Editing Credentials This will open a temporary file in `$EDITOR` with the decrypted contents to edit diff --git a/railties/lib/rails/commands/credentials/credentials_command.rb b/railties/lib/rails/commands/credentials/credentials_command.rb index d1054f8b63..9cde44558b 100644 --- a/railties/lib/rails/commands/credentials/credentials_command.rb +++ b/railties/lib/rails/commands/credentials/credentials_command.rb @@ -32,13 +32,13 @@ module Rails ensure_encryption_key_has_been_added if credentials.key.nil? ensure_credentials_have_been_added + ensure_rails_credentials_driver_is_set catch_editing_exceptions do change_credentials_in_system_editor end say "File encrypted and saved." - enable_credentials_diffing rescue ActiveSupport::MessageEncryptor::InvalidMessage say "Couldn't decrypt #{content_path}. Perhaps you passed the wrong key?" end @@ -50,14 +50,20 @@ module Rails say credentials.read.presence || missing_credentials_message end - def diff(content_path) - @content_path = content_path + option :enroll, type: :boolean, default: false, + desc: "Enrolls project in credential file diffing with `git diff`" - extract_environment_option_from_argument(default_environment: extract_environment_from_path(content_path)) - require_application! + def diff(content_path = nil) + if @content_path = content_path + extract_environment_option_from_argument(default_environment: extract_environment_from_path(content_path)) + require_application! - say credentials.read.presence || credentials.content_path.read - rescue + say credentials.read.presence || credentials.content_path.read + else + require_application! + enroll_project_in_credentials_diffing if options[:enroll] + end + rescue ActiveSupport::MessageEncryptor::InvalidMessage say credentials.content_path.read end diff --git a/railties/lib/rails/commands/credentials/credentials_command/diffing.rb b/railties/lib/rails/commands/credentials/credentials_command/diffing.rb index 1598ecaa8d..1d34c68074 100644 --- a/railties/lib/rails/commands/credentials/credentials_command/diffing.rb +++ b/railties/lib/rails/commands/credentials/credentials_command/diffing.rb @@ -1,47 +1,41 @@ # frozen_string_literal: true module Rails::Command::CredentialsCommand::Diffing # :nodoc: - class Error < StandardError; end - - def enable_credentials_diffing - unless already_answered? || enabled? - answer = yes?("Would you like to make the credentials diff from git more readable in the future? [Y/n]") + def enroll_project_in_credentials_diffing + if enrolled? + true + else + gitattributes.write(<<~end_of_template, mode: "a") + config/credentials/*.yml.enc diff=rails_credentials + config/credentials.yml.enc diff=rails_credentials + end_of_template + + say "Project successfully enrolled!" + say "Rails ensures the rails_credentials diff driver is set when running `credentials:edit`. See `credentials:help` for more." end + end - enable if answer - FileUtils.touch(tracker) unless answer.nil? - rescue Error - say "Couldn't setup git to enable credentials diffing" + def ensure_rails_credentials_driver_is_set + set_driver if enrolled? && !driver_configured? end private - def already_answered? - tracker.exist? + def enrolled? + gitattributes.read.match?(/config\/credentials(\/\*)?\.yml\.enc diff=rails_credentials/) + rescue Errno::ENOENT + false end - def enabled? - system_call("git config --get 'diff.rails_credentials.textconv'", accepted_codes: [0, 1]) - end - - def enable - system_call("git config diff.rails_credentials.textconv 'bin/rails credentials:diff'", accepted_codes: [0]) - - git_attributes = Rails.root.join(".gitattributes") - File.open(git_attributes, "a+") do |file| - file.write(<<~EOM) - config/credentials/*.yml.enc diff=rails_credentials - config/credentials.yml.enc diff=rails_credentials - EOM - end + def driver_configured? + system "git config --get diff.rails_credentials.textconv", out: File::NULL end - def tracker - Rails.root.join("tmp", "rails_pretty_credentials") + def set_driver + puts "running" + system "git config diff.rails_credentials.textconv 'bin/rails credentials:diff'" end - def system_call(command_line, accepted_codes:) - result = system(command_line) - raise(Error) if accepted_codes.exclude?($?.exitstatus) - result + def gitattributes + Rails.root.join(".gitattributes") end end |