diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a3c8d2..8d15bfa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: 3.2 + ruby-version: 3.3 - name: Bundle install run: bundle install - name: Run RuboCop @@ -33,7 +33,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: 3.2 + ruby-version: 3.3 - name: Install grepfruit run: gem install grepfruit - name: Run grepfruit @@ -48,12 +48,10 @@ jobs: strategy: matrix: ruby: - - "3.2" - "3.3" - "3.4" - "4.0" rails: - - "~> 7.1.0" - "~> 7.2.0" - "~> 8.0.0" - "~> 8.1.0" diff --git a/.rubocop.yml b/.rubocop.yml index da8fc15..9684966 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,8 +9,8 @@ plugins: - rubocop-thread_safety AllCops: - TargetRailsVersion: 7.1 - TargetRubyVersion: 3.2 + TargetRailsVersion: 7.2 + TargetRubyVersion: 3.3 NewCops: enable Layout/IndentationConsistency: diff --git a/CHANGELOG.md b/CHANGELOG.md index d65f8bf..6807d18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## v2.0.0 + +- Dropped support for Ruby 3.2 +- Dropped support for Rails 7.1 +- Improved error messages and input validation +- Added `Kreds.env_show` method +- `Kreds.env_fetch!` now raises `InvalidArgumentError` when called with no keys + ## v1.1.7 - Added support for Ruby 4 diff --git a/Gemfile b/Gemfile index 6674ba3..99454c2 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source "https://rubygems.org" gemspec -rails_version = ENV.fetch("RAILS_VERSION", "~> 7.1") +rails_version = ENV.fetch("RAILS_VERSION", "~> 7.2") gem "byebug" gem "rails", rails_version diff --git a/README.md b/README.md index 9ee4a91..33fb3e1 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,10 @@ Rails.application.credentials.fetch(:recaptcha).fetch(:key) # Kreds (clear, human-readable errors): Kreds.fetch!(:recaptcha, :site_key) -# => Blank value in credentials: [:recaptcha][:site_key] (Kreds::BlankCredentialsError) +# => Blank value in credentials: :recaptcha => :site_key (Kreds::BlankCredentialsError) Kreds.fetch!(:recaptcha, :key) -# => Credentials key not found: [:recaptcha][:key] (Kreds::UnknownCredentialsError) +# => Credentials key not found: :recaptcha => :key (Kreds::UnknownCredentialsError) ``` ## Table of Contents @@ -139,6 +139,18 @@ Useful for debugging and exploring available credentials in the Rails console. ```ruby Kreds.show +# => { production: { aws: { access_key_id: "...", secret_access_key: "..." } }, ... } +``` + +**`Kreds.env_show`** + +Like `show`, but scoped to the current Rails environment. + +**Returns:** Hash containing credentials for `Rails.env` + +```ruby +# In production, returns credentials[:production] +Kreds.env_show # => { aws: { access_key_id: "...", secret_access_key: "..." }, ... } ``` diff --git a/kreds.gemspec b/kreds.gemspec index da6cce1..c3340ef 100644 --- a/kreds.gemspec +++ b/kreds.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |spec| spec.summary = "The missing shorthand for Rails credentials" spec.description = "Simpler and safer Rails credentials access with blank value detection and clear error messages" spec.license = "MIT" - spec.required_ruby_version = ">= 3.2", "< 4.1" + spec.required_ruby_version = ">= 3.3", "< 4.1" spec.files = [ "kreds.gemspec", "README.md", "CHANGELOG.md", "LICENSE.txt" @@ -24,5 +24,5 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] - spec.add_dependency "rails", ">= 7.1", "< 8.2" + spec.add_dependency "rails", ">= 7.2", "< 8.2" end diff --git a/lib/kreds/fetch.rb b/lib/kreds/fetch.rb index 6c42199..866ce26 100644 --- a/lib/kreds/fetch.rb +++ b/lib/kreds/fetch.rb @@ -14,7 +14,7 @@ def fetch!(*keys, var: nil, &) end def env_fetch!(*keys, var: nil, &) - fetch!(Rails.env, *keys, var:, &) + fetch!(Rails.env, *Kreds::Inputs.process(keys, as: :symbol_array), var:, &) end def var!(var, &) @@ -33,7 +33,7 @@ def fetch_key(hash, key, path, keys) value = hash.fetch(key) raise Kreds::BlankCredentialsError, "Blank value in credentials: #{path_to_s(path)}" if value.blank? - raise Kreds::UnknownCredentialsError, "Credentials key not found: #{path_to_s(path)}[:#{keys[path.size]}]" unless value.is_a?(Hash) || keys == path + raise Kreds::UnknownCredentialsError, "Credentials key not found: #{path_to_s(path.append(keys[path.size]))}" unless value.is_a?(Hash) || keys == path value rescue KeyError @@ -41,7 +41,7 @@ def fetch_key(hash, key, path, keys) end def fallback_to_var(error, var, &) - return raise_or_yield(error, &) if var.blank? + return raise_or_yield(error, &) if var.nil? var!(var, &) rescue Kreds::BlankEnvironmentVariableError, Kreds::UnknownEnvironmentVariableError => e @@ -53,7 +53,7 @@ def raise_or_yield(error, &) end def path_to_s(path) - "[:#{path.join("][:")}]" + path.map(&:inspect).join(" => ") end end end diff --git a/lib/kreds/show.rb b/lib/kreds/show.rb index a7833b9..87e6ccc 100644 --- a/lib/kreds/show.rb +++ b/lib/kreds/show.rb @@ -1,7 +1,11 @@ module Kreds module Show def show - Rails.application.credentials.as_json.deep_symbolize_keys + Rails.application.credentials.config.to_h + end + + def env_show + show[Rails.env.to_sym] || {} end end end diff --git a/lib/kreds/version.rb b/lib/kreds/version.rb index 235b265..bceed1a 100644 --- a/lib/kreds/version.rb +++ b/lib/kreds/version.rb @@ -1,3 +1,3 @@ module Kreds - VERSION = "1.1.7".freeze + VERSION = "2.0.0".freeze end diff --git a/spec/kreds_spec.rb b/spec/kreds_spec.rb index 880745a..b6a5b2e 100644 --- a/spec/kreds_spec.rb +++ b/spec/kreds_spec.rb @@ -14,6 +14,22 @@ end end + describe ".env_show" do + it "returns credentials for the current environment" do + expect(described_class.env_show).to eq({ foo: [1, 2, 3] }) + end + + it "returns empty hash for an environment not in credentials" do + allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new("staging")) + expect(described_class.env_show).to eq({}) + end + + it "returns the raw value when environment entry is not a hash" do + allow(described_class).to receive(:show).and_return({ test: "not_a_hash" }) + expect(described_class.env_show).to eq("not_a_hash") + end + end + describe ".fetch!" do describe "input validation" do it "raises error for empty keys" do @@ -38,17 +54,17 @@ it "raises error for missing end key" do expect { described_class.fetch!(:foo, :bar, :bad) } - .to raise_error(Kreds::UnknownCredentialsError, "Credentials key not found: [:foo][:bar][:bad]") + .to raise_error(Kreds::UnknownCredentialsError, "Credentials key not found: :foo => :bar => :bad") end it "raises error for missing middle key" do expect { described_class.fetch!(:foo, :bad, :baz) } - .to raise_error(Kreds::UnknownCredentialsError, "Credentials key not found: [:foo][:bad]") + .to raise_error(Kreds::UnknownCredentialsError, "Credentials key not found: :foo => :bad") end it "raises error for blank value" do expect { described_class.fetch!(:bad) } - .to raise_error(Kreds::BlankCredentialsError, "Blank value in credentials: [:bad]") + .to raise_error(Kreds::BlankCredentialsError, "Blank value in credentials: :bad") end end @@ -116,7 +132,7 @@ context "when handling edge cases" do it "raises error when trying to access non-hash as hash" do expect { described_class.fetch!(:foo, :bar, :baz, :extra) } - .to raise_error(Kreds::UnknownCredentialsError, "Credentials key not found: [:foo][:bar][:baz][:extra]") + .to raise_error(Kreds::UnknownCredentialsError, "Credentials key not found: :foo => :bar => :baz => :extra") end it "works with single key" do @@ -128,7 +144,7 @@ describe ".env_fetch!" do it "raises error for invalid key types" do expect { described_class.env_fetch!(:foo, 42) } - .to raise_error(Kreds::InvalidArgumentError, "Expected an array of symbols or strings, got `[\"test\", :foo, 42]`") + .to raise_error(Kreds::InvalidArgumentError, "Expected an array of symbols or strings, got `[:foo, 42]`") end it "raises error for invalid var type when fallback is needed" do @@ -137,8 +153,9 @@ end context "without var" do - it "returns entire test environment hash when no keys provided" do - expect(described_class.env_fetch!).to eq({ foo: [1, 2, 3] }) + it "raises error for empty keys" do + expect { described_class.env_fetch! } + .to raise_error(Kreds::InvalidArgumentError, "Expected an array of symbols or strings, got `[]`") end it "returns specific value from test environment" do @@ -147,7 +164,7 @@ it "raises error for missing key in test environment" do expect { described_class.env_fetch!(:foo, :bar, :bad) } - .to raise_error(Kreds::UnknownCredentialsError, "Credentials key not found: [:test][:foo][:bar]") + .to raise_error(Kreds::UnknownCredentialsError, "Credentials key not found: :test => :foo => :bar") end end