aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib')
-rw-r--r--railties/lib/rails/command/helpers/pretty_credentials.rb55
-rw-r--r--railties/lib/rails/commands/credentials/USAGE15
-rw-r--r--railties/lib/rails/commands/credentials/credentials_command.rb57
-rw-r--r--railties/lib/rails/commands/credentials/credentials_command/diffing.rb41
-rw-r--r--railties/lib/rails/engine.rb1
-rw-r--r--railties/lib/rails/generators.rb5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt2
7 files changed, 89 insertions, 87 deletions
diff --git a/railties/lib/rails/command/helpers/pretty_credentials.rb b/railties/lib/rails/command/helpers/pretty_credentials.rb
deleted file mode 100644
index 873ed0e825..0000000000
--- a/railties/lib/rails/command/helpers/pretty_credentials.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# frozen_string_literal: true
-
-require "fileutils"
-
-module Rails
- module Command
- module Helpers
- module PrettyCredentials
- Error = Class.new(StandardError)
-
- def opt_in_pretty_credentials
- unless already_answered? || already_opted_in?
- answer = yes?("Would you like to make the credentials diff from git more readable in the future? [Y/n]")
- end
-
- opt_in! if answer
- FileUtils.touch(tracker) unless answer.nil?
- rescue Error
- say("Couldn't setup git to prettify the credentials diff")
- end
-
- private
- def already_answered?
- tracker.exist?
- end
-
- def already_opted_in?
- system_call("git config --get 'diff.rails_credentials.textconv'", accepted_codes: [0, 1])
- end
-
- def opt_in!
- system_call("git config diff.rails_credentials.textconv 'bin/rails credentials:show'", 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
- end
-
- def tracker
- Rails.root.join("tmp", "rails_pretty_credentials")
- end
-
- def system_call(command_line, accepted_codes:)
- result = system(command_line)
- raise(Error) if accepted_codes.exclude?($?.exitstatus)
- result
- end
- end
- end
- end
-end
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 772e105007..9cde44558b 100644
--- a/railties/lib/rails/commands/credentials/credentials_command.rb
+++ b/railties/lib/rails/commands/credentials/credentials_command.rb
@@ -1,18 +1,19 @@
# frozen_string_literal: true
+require "pathname"
require "active_support"
require "rails/command/helpers/editor"
-require "rails/command/helpers/pretty_credentials"
require "rails/command/environment_argument"
-require "pathname"
module Rails
module Command
class CredentialsCommand < Rails::Command::Base # :nodoc:
include Helpers::Editor
- include Helpers::PrettyCredentials
include EnvironmentArgument
+ require_relative "credentials_command/diffing"
+ include Diffing
+
self.environment_desc = "Uses credentials from config/credentials/:environment.yml.enc encrypted by config/credentials/:environment.key key"
no_commands do
@@ -31,35 +32,44 @@ 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."
- opt_in_pretty_credentials
rescue ActiveSupport::MessageEncryptor::InvalidMessage
say "Couldn't decrypt #{content_path}. Perhaps you passed the wrong key?"
end
- def show(git_textconv_path = nil)
- if git_textconv_path
- default_environment = extract_environment_from_path(git_textconv_path)
- fallback_message = File.read(git_textconv_path)
- end
-
- extract_environment_option_from_argument(default_environment: default_environment)
+ def show
+ extract_environment_option_from_argument(default_environment: nil)
require_application!
- say credentials(git_textconv_path).read.presence || fallback_message || missing_credentials_message
- rescue => e
- raise(e) unless git_textconv_path
- fallback_message
+ say credentials.read.presence || missing_credentials_message
+ end
+
+ option :enroll, type: :boolean, default: false,
+ desc: "Enrolls project in credential file diffing with `git diff`"
+
+ 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
+ else
+ require_application!
+ enroll_project_in_credentials_diffing if options[:enroll]
+ end
+ rescue ActiveSupport::MessageEncryptor::InvalidMessage
+ say credentials.content_path.read
end
private
- def credentials(content = nil)
- Rails.application.encrypted(content || content_path, key_path: key_path)
+ def credentials
+ Rails.application.encrypted(content_path, key_path: key_path)
end
def ensure_encryption_key_has_been_added
@@ -89,8 +99,9 @@ module Rails
end
end
+
def content_path
- options[:environment] ? "config/credentials/#{options[:environment]}.yml.enc" : "config/credentials.yml.enc"
+ @content_path ||= options[:environment] ? "config/credentials/#{options[:environment]}.yml.enc" : "config/credentials.yml.enc"
end
def key_path
@@ -98,15 +109,7 @@ module Rails
end
def extract_environment_from_path(path)
- regex = %r{
- ([A-Za-z0-9]+) # match the environment
- (?<!credentials) # don't match if file contains the word "credentials"
- # in such case, the environment should be the default one
- \.yml\.enc # look for `.yml.enc` file extension
- }x
- path.match(regex)
-
- Regexp.last_match(1)
+ available_environments.find { |env| path.include? env } if path.match?(/\.yml\.enc$/)
end
def encryption_key_file_generator
diff --git a/railties/lib/rails/commands/credentials/credentials_command/diffing.rb b/railties/lib/rails/commands/credentials/credentials_command/diffing.rb
new file mode 100644
index 0000000000..1d34c68074
--- /dev/null
+++ b/railties/lib/rails/commands/credentials/credentials_command/diffing.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Rails::Command::CredentialsCommand::Diffing # :nodoc:
+ 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
+
+ def ensure_rails_credentials_driver_is_set
+ set_driver if enrolled? && !driver_configured?
+ end
+
+ private
+ def enrolled?
+ gitattributes.read.match?(/config\/credentials(\/\*)?\.yml\.enc diff=rails_credentials/)
+ rescue Errno::ENOENT
+ false
+ end
+
+ def driver_configured?
+ system "git config --get diff.rails_credentials.textconv", out: File::NULL
+ end
+
+ def set_driver
+ puts "running"
+ system "git config diff.rails_credentials.textconv 'bin/rails credentials:diff'"
+ end
+
+ def gitattributes
+ Rails.root.join(".gitattributes")
+ end
+end
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index b4c0028b1f..f8f5ff443a 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -3,6 +3,7 @@
require "rails/railtie"
require "rails/engine/railties"
require "active_support/core_ext/module/delegation"
+require "active_support/core_ext/object/try"
require "pathname"
require "thread"
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 436315ce1e..aa7ef1077e 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -128,11 +128,6 @@ module Rails
end
end
- # Remove the color from output.
- def no_color!
- Thor::Base.shell = Thor::Shell::Basic
- end
-
# Returns an array of generator namespaces that are hidden.
# Generator namespaces may be hidden for a variety of reasons.
# Some are aliased such as "rails:migration" and can be
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
index c66e349442..41dabb87df 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
@@ -3,6 +3,8 @@
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
+require "active_support/core_ext/integer/time"
+
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
<%# Spring executes the reloaders when files change. %>