Skip to content

Commit

Permalink
Merge pull request #45 from i7an/cast_booleans
Browse files Browse the repository at this point in the history
Cast boolean values
  • Loading branch information
le0pard authored Dec 4, 2024
2 parents a60ce90 + 66b555b commit 2d442e3
Show file tree
Hide file tree
Showing 20 changed files with 257 additions and 219 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ jobs:
strategy:
matrix:
os: [ubuntu, macos]
ruby-version: ['3.1', '3.0', '2.7', '2.6', '2.5']
ruby-version:
- 3.3
- 3.2
- 3.1
- 3.0
steps:
- uses: actions/checkout@v2

Expand Down
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@ Gemfile.lock
pkg/*
.rspec
coverage/**
.DS_Store
.DS_Store

.ruby-gemset
.ruby-version
.tool-versions

.vscode
.idea
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
--color
--require spec_helper
8 changes: 8 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
require:
- rubocop-rake
- rubocop-rspec

AllCops:
TargetRubyVersion: 3.0
NewCops: enable

Metrics/MethodLength:
Enabled: true
Max: 11
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## [3.0.0] - 2024-12-04

- Predicate methods now cast the value to a boolean
```ruby
Global.foo.enabled # => "0"
Global.foo.enabled? # => false
```
- Dropped Ruby 2.7 support
12 changes: 11 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,15 @@

source 'https://rubygems.org'

# Specify your gem's dependencies in global.gemspec
gemspec

gem 'aws-sdk-ssm', '~> 1'
gem 'google-cloud-secret_manager', '~> 0'

gem 'rake', '>= 13'
gem 'rspec', '>= 3.0'
gem 'simplecov'

gem 'rubocop', '~> 1.68'
gem 'rubocop-rake'
gem 'rubocop-rspec'
7 changes: 1 addition & 6 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
# frozen_string_literal: true

require 'rubygems'
require 'bundler'

Bundler.require

require 'rspec/core/rake_task'
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
require 'rubocop/rake_task'

RSpec::Core::RakeTask.new(:spec)
Expand Down
23 changes: 8 additions & 15 deletions global.gemspec
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
# frozen_string_literal: true

$LOAD_PATH.push File.expand_path('lib', __dir__)
require 'global/version'
require_relative 'lib/global/version'

Gem::Specification.new do |s|
s.name = 'global'
s.version = Global::VERSION
s.required_ruby_version = '>= 3.0.0'
s.authors = ['Railsware LLC']
s.email = '[email protected]'

s.description = 'Simple way to load your configs from yaml/aws/gcp'

s.homepage = 'https://github.com/railsware/global'
s.licenses = ['MIT']
s.summary = 'Simple way to load your configs from yaml/aws/gcp'

s.metadata['rubygems_mfa_required'] = 'true'

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
s.require_paths = ['lib']

s.homepage = 'https://github.com/railsware/global'
s.licenses = ['MIT']

s.add_development_dependency 'aws-sdk-ssm', '~> 1'
s.add_development_dependency 'google-cloud-secret_manager', '~> 0'
s.add_development_dependency 'rake', '~> 12.3.1'
s.add_development_dependency 'rspec', '>= 3.0'
s.add_development_dependency 'rubocop', '~> 0.81.0'
s.add_development_dependency 'simplecov', '~> 0.16.1'

s.add_runtime_dependency 'activesupport', '>= 2.0'
s.add_dependency 'activesupport', '>= 2.0'
end
2 changes: 1 addition & 1 deletion lib/global/backend/aws_parameter_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def load_parameters_from_ssm(next_token = nil)
def build_configuration_from_parameters(parameters)
configuration = {}
parameters.each do |parameter|
parameter_parts = parameter.name[@prefix.length..-1].split(PATH_SEPARATOR).map(&:to_sym)
parameter_parts = parameter.name[@prefix.length..].split(PATH_SEPARATOR).map(&:to_sym)
param_container = parameter_parts[0..-2].reduce(configuration) do |container, part|
container[part] ||= {}
end
Expand Down
2 changes: 1 addition & 1 deletion lib/global/backend/filesystem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def get_config_by_key(config, key)
end

def load_yml_file(file)
file_contents = ERB.new(IO.read(file)).result
file_contents = ERB.new(File.read(file)).result
permitted_classes = [Date, Time, DateTime, Symbol].concat(@yaml_whitelist_classes)

if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('4')
Expand Down
2 changes: 1 addition & 1 deletion lib/global/backend/gcp_secret_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def build_configuration_from_page(page)
key_name = get_gcp_key_name(parameter)
next unless key_name.start_with?(@prefix)

parameter_parts = key_name[@prefix.length..-1].split(PATH_SEPARATOR).map(&:to_sym)
parameter_parts = key_name[@prefix.length..].split(PATH_SEPARATOR).map(&:to_sym)
param_container = parameter_parts[0..-2].reduce(configuration) do |container, part|
container[part] ||= {}
end
Expand Down
31 changes: 28 additions & 3 deletions lib/global/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ class Configuration
:member?, :[], :[]=, :to_hash, :to_json,
:inspect, :fetch

# rubocop:disable Lint/BooleanSymbol
# @see ActiveModel::Type::Boolean::FALSE_VALUES
FALSE_VALUES = [
false, 0,
'0', :'0',
'f', :f,
'F', :F,
'false', :false,
'FALSE', :FALSE,
'off', :off,
'OFF', :OFF
].to_set.freeze
private_constant :FALSE_VALUES
# rubocop:enable Lint/BooleanSymbol

def initialize(hash)
@hash = hash.respond_to?(:with_indifferent_access) ? hash.with_indifferent_access : hash
end
Expand Down Expand Up @@ -49,9 +64,10 @@ def respond_to_missing?(method_name, include_private = false)
end

def method_missing(method, *args, &block)
method = normalize_key_by_method(method)
if key?(method)
get_configuration_value(method)
normalized_method = normalize_key_by_method(method)
if key?(normalized_method)
value = get_configuration_value(normalized_method)
boolean_method?(method) ? cast_boolean(value) : value
else
super
end
Expand All @@ -61,6 +77,15 @@ def boolean_method?(method)
'?' == method.to_s[-1]
end

# @see ActiveModel::Type::Boolean#cast_value
def cast_boolean(value)
if value == '' || value.nil?
false
else
!FALSE_VALUES.include?(value)
end
end

def normalize_key_by_method(method)
boolean_method?(method) ? method.to_s[0..-2].to_sym : method
end
Expand Down
2 changes: 1 addition & 1 deletion lib/global/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module Global

VERSION = '2.1.0'
VERSION = '3.0.0'

end
12 changes: 6 additions & 6 deletions spec/global/backend/aws_parameter_store_spec.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# frozen_string_literal: true

require 'spec_helper'
require 'aws-sdk-ssm'
require 'global/backend/aws_parameter_store'

RSpec.describe Global::Backend::AwsParameterStore do
subject(:parameter_store) do
described_class.new(prefix: '/testapp/', client: client)
end

let(:client) do
Aws::SSM::Client.new(stub_responses: true)
end
subject do
described_class.new(prefix: '/testapp/', client: client)
end

it 'reads parameters from the parameter store' do
it 'reads parameters from the parameter store' do # rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
client.stub_responses(
:get_parameters_by_path,
[
Expand All @@ -37,7 +37,7 @@
}
]
)
expect(subject.load).to eq(
expect(parameter_store.load).to eq(
foo: 'foo-value',
bar: {
baz: 'baz-value',
Expand Down
34 changes: 16 additions & 18 deletions spec/global/backend/gcp_secret_manager_spec.rb
Original file line number Diff line number Diff line change
@@ -1,39 +1,37 @@
# frozen_string_literal: true

require 'spec_helper'
require 'google/cloud/secret_manager'
require 'google/cloud/secret_manager/v1'
require 'global/backend/gcp_secret_manager'

RSpec.describe Global::Backend::GcpSecretManager do
let(:client) { double }

subject do
subject(:secret_manager) do
described_class.new(prefix: 'prod-myapp-', client: client, project_id: 'example')
end

before do
@match_item = double
allow(@match_item).to receive(:name).and_return('prod-myapp-example-test_key')
let(:client) { instance_double(Google::Cloud::SecretManager::V1::SecretManagerService::Client) }

@secret_data = double
allow(@secret_data).to receive_message_chain(:payload, :data).and_return('secret value')
before do
# rubocop:disable RSpec/VerifiedDoubles
match_item = double(name: 'prod-myapp-example-test_key')
not_match_item = double(name: 'different_key')

@not_match_item = double
allow(@not_match_item).to receive(:name).and_return('different_key')
secret_data = double(data: 'secret value')
secret_version_response = double(payload: secret_data)

@list = double
allow(@list).to receive(:next_page_token).and_return('')
allow(@list).to receive(:each).and_yield(@match_item).and_yield(@not_match_item)
page = instance_double(Gapic::PagedEnumerable)
allow(page).to receive(:next_page_token).and_return('')
allow(page).to receive(:each).and_yield(match_item).and_yield(not_match_item)

allow(client).to receive(:project_path).and_return('projects/example')
allow(client).to receive(:secret_version_path)
.with(project: 'example', secret: 'prod-myapp-example-test_key', secret_version: 'latest')
.and_return('some_key_path')
allow(client).to receive(:access_secret_version).with(name: 'some_key_path').and_return(@secret_data)
allow(client).to receive(:list_secrets).and_return(@list)
allow(client).to receive(:access_secret_version).with(name: 'some_key_path').and_return(secret_version_response)
allow(client).to receive_messages(project_path: 'projects/example', list_secrets: page)
# rubocop:enable RSpec/VerifiedDoubles
end

it 'reads parameters from the secret manager' do
expect(subject.load).to eq({ example: { test_key: 'secret value' }})
expect(secret_manager.load).to eq({ example: { test_key: 'secret value' }})
end
end
Loading

0 comments on commit 2d442e3

Please sign in to comment.