global 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/tests.yml +28 -0
- data/.gitignore +8 -1
- data/.rspec +1 -0
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +11 -1
- data/README.md +9 -3
- data/Rakefile +1 -6
- data/global.gemspec +8 -15
- data/lib/global/backend/aws_parameter_store.rb +1 -1
- data/lib/global/backend/filesystem.rb +10 -7
- data/lib/global/backend/gcp_secret_manager.rb +1 -1
- data/lib/global/base.rb +1 -1
- data/lib/global/configuration.rb +34 -5
- data/lib/global/version.rb +1 -1
- data/spec/global/backend/aws_parameter_store_spec.rb +6 -6
- data/spec/global/backend/gcp_secret_manager_spec.rb +16 -18
- data/spec/global/configuration_spec.rb +85 -71
- data/spec/global_merge_backends_spec.rb +25 -0
- data/spec/global_spec.rb +43 -56
- data/spec/spec_helper.rb +2 -4
- metadata +13 -107
- data/.travis.yml +0 -22
- data/spec/merge_backends_spec.rb +0 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9b5acdeb3ad880ec202bb6754c307585a47ffc951982c2d19b85707c2bea17f8
|
|
4
|
+
data.tar.gz: 3c88ae1a5cd961d1d938fecf9598e0da1f87f9d5dc226a110c68bc329c633988
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 93a5195d7db98dc4f806e38428c9553aba5c7b54561f4db729b925145fb3fefa854ee4be3bd8a4a92a02425bd1e4e0203baaa4afcbe37fb33ad6e30ca4482267
|
|
7
|
+
data.tar.gz: bc9d92edd7715f96149c2a5d1ae456ce0e208c636a4f2ed562391d06d7b835c81572b8f6d31591b59aa24f1bf7ed4738e0bf81532f02efa218f98eb2af0b49bf
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Runs linter and tests
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
linters_and_tests:
|
|
7
|
+
runs-on: ${{ matrix.os }}-latest
|
|
8
|
+
continue-on-error: ${{ matrix.experimental == true }}
|
|
9
|
+
name: Linter and tests on ${{ matrix.os }}-ruby-${{ matrix.ruby-version }}
|
|
10
|
+
strategy:
|
|
11
|
+
matrix:
|
|
12
|
+
os: [ubuntu, macos]
|
|
13
|
+
ruby-version:
|
|
14
|
+
- 3.3
|
|
15
|
+
- 3.2
|
|
16
|
+
- 3.1
|
|
17
|
+
- 3.0
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v2
|
|
20
|
+
|
|
21
|
+
- name: Set up Ruby
|
|
22
|
+
uses: ruby/setup-ruby@v1
|
|
23
|
+
with:
|
|
24
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
25
|
+
bundler-cache: true
|
|
26
|
+
|
|
27
|
+
- name: Runs linter and tests
|
|
28
|
+
run: bundle exec rake
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
ADDED
data/Gemfile
CHANGED
|
@@ -2,5 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
|
-
# Specify your gem's dependencies in global.gemspec
|
|
6
5
|
gemspec
|
|
6
|
+
|
|
7
|
+
gem 'aws-sdk-ssm', '~> 1'
|
|
8
|
+
gem 'google-cloud-secret_manager', '~> 0'
|
|
9
|
+
|
|
10
|
+
gem 'rake', '>= 13'
|
|
11
|
+
gem 'rspec', '>= 3.0'
|
|
12
|
+
gem 'simplecov'
|
|
13
|
+
|
|
14
|
+
gem 'rubocop', '~> 1.68'
|
|
15
|
+
gem 'rubocop-rake'
|
|
16
|
+
gem 'rubocop-rspec'
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Global [](https://github.com/railsware/global/actions/workflows/tests.yml) [](https://codeclimate.com/github/railsware/global)
|
|
2
2
|
|
|
3
3
|
The 'global' gem provides accessor methods for your configuration data and share configuration across backend and frontend.
|
|
4
4
|
|
|
@@ -19,14 +19,14 @@ Refer to the documentation on your chosen backend class for other dependencies.
|
|
|
19
19
|
Refer to the documentation on your chosen backend class for configuration options.
|
|
20
20
|
|
|
21
21
|
```ruby
|
|
22
|
-
> Global.backend(:filesystem, environment: "YOUR_ENV_HERE",
|
|
22
|
+
> Global.backend(:filesystem, environment: "YOUR_ENV_HERE", path: "PATH_TO_DIRECTORY_WITH_FILES")
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
Or you can use `configure` block:
|
|
26
26
|
|
|
27
27
|
```ruby
|
|
28
28
|
Global.configure do |config|
|
|
29
|
-
config.backend :filesystem, environment: "YOUR_ENV_HERE",
|
|
29
|
+
config.backend :filesystem, environment: "YOUR_ENV_HERE", path: "PATH_TO_DIRECTORY_WITH_FILES"
|
|
30
30
|
# set up multiple backends and have them merged together:
|
|
31
31
|
config.backend :aws_parameter_store, prefix: '/prod/MyApp/'
|
|
32
32
|
config.backend :gcp_secret_manager, prefix: 'prod-myapp-', project_id: 'example'
|
|
@@ -252,6 +252,12 @@ Some steps you will need to follow:
|
|
|
252
252
|
- If you will use encrypted parameters: create a KMS key and allow the role to decrypt using the key.
|
|
253
253
|
- Create parameters in Parameter Store. Use encryption for sensitive data like private keys and API credentials.
|
|
254
254
|
|
|
255
|
+
#### Usage with Go
|
|
256
|
+
|
|
257
|
+
You can reuse the same configuration in your Go services. For this, we developed a Go module that loads the same configuration tree into Go structs.
|
|
258
|
+
|
|
259
|
+
See [github.com/railsware/go-global](https://github.com/railsware/go-global) for further instructions.
|
|
260
|
+
|
|
255
261
|
#### Configuration examples
|
|
256
262
|
|
|
257
263
|
Backend setup:
|
data/Rakefile
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'rubygems'
|
|
4
|
-
require 'bundler'
|
|
5
|
-
|
|
6
|
-
Bundler.require
|
|
7
|
-
|
|
8
|
-
require 'rspec/core/rake_task'
|
|
9
3
|
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
10
5
|
require 'rubocop/rake_task'
|
|
11
6
|
|
|
12
7
|
RSpec::Core::RakeTask.new(:spec)
|
data/global.gemspec
CHANGED
|
@@ -1,31 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
require 'global/version'
|
|
3
|
+
require_relative 'lib/global/version'
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |s|
|
|
7
6
|
s.name = 'global'
|
|
8
7
|
s.version = Global::VERSION
|
|
8
|
+
s.required_ruby_version = '>= 3.0.0'
|
|
9
9
|
s.authors = ['Railsware LLC']
|
|
10
10
|
s.email = 'contact@railsware.com'
|
|
11
|
-
|
|
12
11
|
s.description = 'Simple way to load your configs from yaml/aws/gcp'
|
|
12
|
+
|
|
13
|
+
s.homepage = 'https://github.com/railsware/global'
|
|
14
|
+
s.licenses = ['MIT']
|
|
13
15
|
s.summary = 'Simple way to load your configs from yaml/aws/gcp'
|
|
14
16
|
|
|
17
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
|
18
|
+
|
|
15
19
|
s.files = `git ls-files`.split("\n")
|
|
16
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
17
20
|
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
|
18
21
|
s.require_paths = ['lib']
|
|
19
22
|
|
|
20
|
-
s.
|
|
21
|
-
s.licenses = ['MIT']
|
|
22
|
-
|
|
23
|
-
s.add_development_dependency 'aws-sdk-ssm', '~> 1'
|
|
24
|
-
s.add_development_dependency 'google-cloud-secret_manager', '~> 0'
|
|
25
|
-
s.add_development_dependency 'rake', '~> 12.3.1'
|
|
26
|
-
s.add_development_dependency 'rspec', '>= 3.0'
|
|
27
|
-
s.add_development_dependency 'rubocop', '~> 0.81.0'
|
|
28
|
-
s.add_development_dependency 'simplecov', '~> 0.16.1'
|
|
29
|
-
|
|
30
|
-
s.add_runtime_dependency 'activesupport', '>= 2.0'
|
|
23
|
+
s.add_dependency 'activesupport', '>= 2.0'
|
|
31
24
|
end
|
|
@@ -95,7 +95,7 @@ module Global
|
|
|
95
95
|
def build_configuration_from_parameters(parameters)
|
|
96
96
|
configuration = {}
|
|
97
97
|
parameters.each do |parameter|
|
|
98
|
-
parameter_parts = parameter.name[@prefix.length
|
|
98
|
+
parameter_parts = parameter.name[@prefix.length..].split(PATH_SEPARATOR).map(&:to_sym)
|
|
99
99
|
param_container = parameter_parts[0..-2].reduce(configuration) do |container, part|
|
|
100
100
|
container[part] ||= {}
|
|
101
101
|
end
|
|
@@ -5,12 +5,12 @@ module Global
|
|
|
5
5
|
# Loads Global configuration from the filesystem
|
|
6
6
|
#
|
|
7
7
|
# Available options:
|
|
8
|
-
# - `
|
|
8
|
+
# - `path` (required): the directory with config files
|
|
9
9
|
# - `environment` (required): the environment to load
|
|
10
10
|
# - `yaml_whitelist_classes`: the set of classes that are permitted to unmarshal from the configuration files
|
|
11
11
|
#
|
|
12
12
|
# For Rails:
|
|
13
|
-
# - the `
|
|
13
|
+
# - the `path` is optional and defaults to `config/global`
|
|
14
14
|
# - the `environment` is optional and defaults to the current Rails environment
|
|
15
15
|
class Filesystem
|
|
16
16
|
|
|
@@ -60,11 +60,14 @@ module Global
|
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def load_yml_file(file)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
file_contents = ERB.new(File.read(file)).result
|
|
64
|
+
permitted_classes = [Date, Time, DateTime, Symbol].concat(@yaml_whitelist_classes)
|
|
65
|
+
|
|
66
|
+
if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('4')
|
|
67
|
+
YAML.safe_load(file_contents, permitted_classes: permitted_classes, aliases: true)
|
|
68
|
+
else
|
|
69
|
+
YAML.safe_load(file_contents, permitted_classes, [], true)
|
|
70
|
+
end
|
|
68
71
|
end
|
|
69
72
|
|
|
70
73
|
def load_from_directory(path)
|
|
@@ -108,7 +108,7 @@ module Global
|
|
|
108
108
|
key_name = get_gcp_key_name(parameter)
|
|
109
109
|
next unless key_name.start_with?(@prefix)
|
|
110
110
|
|
|
111
|
-
parameter_parts = key_name[@prefix.length
|
|
111
|
+
parameter_parts = key_name[@prefix.length..].split(PATH_SEPARATOR).map(&:to_sym)
|
|
112
112
|
param_container = parameter_parts[0..-2].reduce(configuration) do |container, part|
|
|
113
113
|
container[part] ||= {}
|
|
114
114
|
end
|
data/lib/global/base.rb
CHANGED
|
@@ -34,7 +34,7 @@ module Global
|
|
|
34
34
|
# and the configuration hashes will be merged.
|
|
35
35
|
#
|
|
36
36
|
# Configure with either:
|
|
37
|
-
# Global.backend :filesystem,
|
|
37
|
+
# Global.backend :filesystem, path: 'config', environment: Rails.env
|
|
38
38
|
# or:
|
|
39
39
|
# Global.backend YourConfigurationBackend.new
|
|
40
40
|
#
|
data/lib/global/configuration.rb
CHANGED
|
@@ -13,6 +13,21 @@ module Global
|
|
|
13
13
|
:member?, :[], :[]=, :to_hash, :to_json,
|
|
14
14
|
:inspect, :fetch
|
|
15
15
|
|
|
16
|
+
# rubocop:disable Lint/BooleanSymbol
|
|
17
|
+
# @see ActiveModel::Type::Boolean::FALSE_VALUES
|
|
18
|
+
FALSE_VALUES = [
|
|
19
|
+
false, 0,
|
|
20
|
+
'0', :'0',
|
|
21
|
+
'f', :f,
|
|
22
|
+
'F', :F,
|
|
23
|
+
'false', :false,
|
|
24
|
+
'FALSE', :FALSE,
|
|
25
|
+
'off', :off,
|
|
26
|
+
'OFF', :OFF
|
|
27
|
+
].to_set.freeze
|
|
28
|
+
private_constant :FALSE_VALUES
|
|
29
|
+
# rubocop:enable Lint/BooleanSymbol
|
|
30
|
+
|
|
16
31
|
def initialize(hash)
|
|
17
32
|
@hash = hash.respond_to?(:with_indifferent_access) ? hash.with_indifferent_access : hash
|
|
18
33
|
end
|
|
@@ -45,20 +60,34 @@ module Global
|
|
|
45
60
|
|
|
46
61
|
def respond_to_missing?(method_name, include_private = false)
|
|
47
62
|
method = normalize_key_by_method(method_name)
|
|
48
|
-
key?(method) || super
|
|
63
|
+
key?(method) || boolean_method?(method) || super
|
|
49
64
|
end
|
|
50
65
|
|
|
51
66
|
def method_missing(method, *args, &block)
|
|
52
|
-
|
|
53
|
-
if key?(
|
|
54
|
-
get_configuration_value(
|
|
67
|
+
normalized_method = normalize_key_by_method(method)
|
|
68
|
+
if key?(normalized_method)
|
|
69
|
+
value = get_configuration_value(normalized_method)
|
|
70
|
+
boolean_method?(method) ? cast_boolean(value) : value
|
|
55
71
|
else
|
|
56
72
|
super
|
|
57
73
|
end
|
|
58
74
|
end
|
|
59
75
|
|
|
76
|
+
def boolean_method?(method)
|
|
77
|
+
'?' == method.to_s[-1]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @see ActiveModel::Type::Boolean#cast_value
|
|
81
|
+
def cast_boolean(value)
|
|
82
|
+
if value == '' || value.nil?
|
|
83
|
+
false
|
|
84
|
+
else
|
|
85
|
+
!FALSE_VALUES.include?(value)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
60
89
|
def normalize_key_by_method(method)
|
|
61
|
-
|
|
90
|
+
boolean_method?(method) ? method.to_s[0..-2].to_sym : method
|
|
62
91
|
end
|
|
63
92
|
|
|
64
93
|
end
|
data/lib/global/version.rb
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'spec_helper'
|
|
4
3
|
require 'aws-sdk-ssm'
|
|
5
4
|
require 'global/backend/aws_parameter_store'
|
|
6
5
|
|
|
7
6
|
RSpec.describe Global::Backend::AwsParameterStore do
|
|
7
|
+
subject(:parameter_store) do
|
|
8
|
+
described_class.new(prefix: '/testapp/', client: client)
|
|
9
|
+
end
|
|
10
|
+
|
|
8
11
|
let(:client) do
|
|
9
12
|
Aws::SSM::Client.new(stub_responses: true)
|
|
10
13
|
end
|
|
11
|
-
subject do
|
|
12
|
-
described_class.new(prefix: '/testapp/', client: client)
|
|
13
|
-
end
|
|
14
14
|
|
|
15
|
-
it 'reads parameters from the parameter store' do
|
|
15
|
+
it 'reads parameters from the parameter store' do # rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
|
|
16
16
|
client.stub_responses(
|
|
17
17
|
:get_parameters_by_path,
|
|
18
18
|
[
|
|
@@ -37,7 +37,7 @@ RSpec.describe Global::Backend::AwsParameterStore do
|
|
|
37
37
|
}
|
|
38
38
|
]
|
|
39
39
|
)
|
|
40
|
-
expect(
|
|
40
|
+
expect(parameter_store.load).to eq(
|
|
41
41
|
foo: 'foo-value',
|
|
42
42
|
bar: {
|
|
43
43
|
baz: 'baz-value',
|
|
@@ -1,39 +1,37 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'spec_helper'
|
|
4
3
|
require 'google/cloud/secret_manager'
|
|
4
|
+
require 'google/cloud/secret_manager/v1'
|
|
5
5
|
require 'global/backend/gcp_secret_manager'
|
|
6
6
|
|
|
7
7
|
RSpec.describe Global::Backend::GcpSecretManager do
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
subject do
|
|
8
|
+
subject(:secret_manager) do
|
|
11
9
|
described_class.new(prefix: 'prod-myapp-', client: client, project_id: 'example')
|
|
12
10
|
end
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
@match_item = double
|
|
16
|
-
allow(@match_item).to receive(:name).and_return('prod-myapp-example-test_key')
|
|
12
|
+
let(:client) { instance_double(Google::Cloud::SecretManager::V1::SecretManagerService::Client) }
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
before do
|
|
15
|
+
# rubocop:disable RSpec/VerifiedDoubles
|
|
16
|
+
match_item = double(name: 'prod-myapp-example-test_key')
|
|
17
|
+
not_match_item = double(name: 'different_key')
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
secret_data = double(data: 'secret value')
|
|
20
|
+
secret_version_response = double(payload: secret_data)
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
allow(
|
|
26
|
-
allow(
|
|
22
|
+
page = instance_double(Gapic::PagedEnumerable)
|
|
23
|
+
allow(page).to receive(:next_page_token).and_return('')
|
|
24
|
+
allow(page).to receive(:each).and_yield(match_item).and_yield(not_match_item)
|
|
27
25
|
|
|
28
|
-
allow(client).to receive(:project_path).and_return('projects/example')
|
|
29
26
|
allow(client).to receive(:secret_version_path)
|
|
30
27
|
.with(project: 'example', secret: 'prod-myapp-example-test_key', secret_version: 'latest')
|
|
31
28
|
.and_return('some_key_path')
|
|
32
|
-
allow(client).to receive(:access_secret_version).with(name: 'some_key_path').and_return(
|
|
33
|
-
allow(client).to
|
|
29
|
+
allow(client).to receive(:access_secret_version).with(name: 'some_key_path').and_return(secret_version_response)
|
|
30
|
+
allow(client).to receive_messages(project_path: 'projects/example', list_secrets: page)
|
|
31
|
+
# rubocop:enable RSpec/VerifiedDoubles
|
|
34
32
|
end
|
|
35
33
|
|
|
36
34
|
it 'reads parameters from the secret manager' do
|
|
37
|
-
expect(
|
|
35
|
+
expect(secret_manager.load).to eq({ example: { test_key: 'secret value' }})
|
|
38
36
|
end
|
|
39
37
|
end
|
|
@@ -1,151 +1,165 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
3
|
RSpec.describe Global::Configuration do
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
subject(:configuration) { described_class.new hash }
|
|
5
|
+
|
|
6
|
+
let(:hash) do
|
|
7
|
+
{
|
|
8
|
+
'key' => 'value',
|
|
9
|
+
'boolean_key' => true,
|
|
10
|
+
'nested' => { 'key' => 'value' }
|
|
11
|
+
}
|
|
12
|
+
end
|
|
8
13
|
|
|
9
14
|
describe '#hash' do
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
it { is_expected.to eq(hash) }
|
|
15
|
+
it { expect(configuration.hash).to eq(hash) }
|
|
13
16
|
end
|
|
14
17
|
|
|
15
18
|
describe '#to_hash' do
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
it { is_expected.to eq(hash) }
|
|
19
|
+
it { expect(configuration.to_hash).to eq(hash) }
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
describe 'key?' do
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
it { is_expected.to be_truthy }
|
|
22
|
+
describe '#key?' do
|
|
23
|
+
it { expect(configuration.key?(:key)).to be(true) }
|
|
25
24
|
end
|
|
26
25
|
|
|
27
|
-
describe 'has_key?' do
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
it { is_expected.to be_truthy }
|
|
26
|
+
describe '#has_key?' do
|
|
27
|
+
it { expect(configuration).to have_key(:key) }
|
|
31
28
|
end
|
|
32
29
|
|
|
33
30
|
describe 'include?' do
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
it { is_expected.to be_truthy }
|
|
31
|
+
it { expect(configuration.include?(:key)).to be(true) }
|
|
37
32
|
end
|
|
38
33
|
|
|
39
34
|
describe 'member?' do
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
it { is_expected.to be_truthy }
|
|
35
|
+
it { expect(configuration.member?(:key)).to be(true) }
|
|
43
36
|
end
|
|
44
37
|
|
|
45
38
|
describe '#[]' do
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
it { is_expected.to eq('value') }
|
|
39
|
+
it { expect(configuration[:key]).to eq('value') }
|
|
49
40
|
end
|
|
50
41
|
|
|
51
42
|
describe '#[]=' do
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
it { is_expected.to eq('new_value') }
|
|
43
|
+
it 'sets new value' do
|
|
44
|
+
configuration[:new_key] = 'new_value'
|
|
45
|
+
expect(configuration[:new_key]).to eq('new_value')
|
|
46
|
+
end
|
|
57
47
|
end
|
|
58
48
|
|
|
59
49
|
describe '#inspect' do
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
it { is_expected.to eq(hash.inspect) }
|
|
50
|
+
it { expect(configuration.inspect).to eq(hash.inspect) }
|
|
63
51
|
end
|
|
64
52
|
|
|
65
53
|
describe '#filter' do
|
|
66
|
-
subject { configuration.filter(filter_options) }
|
|
54
|
+
subject(:filter) { configuration.filter(filter_options) }
|
|
67
55
|
|
|
68
56
|
context 'when include all' do
|
|
69
57
|
let(:filter_options) { { only: :all } }
|
|
70
58
|
|
|
71
|
-
it {
|
|
59
|
+
it { expect(filter).to eq('key' => 'value', 'boolean_key' => true, 'nested' => { 'key' => 'value' }) }
|
|
72
60
|
end
|
|
73
61
|
|
|
74
62
|
context 'when except all' do
|
|
75
63
|
let(:filter_options) { { except: :all } }
|
|
76
64
|
|
|
77
|
-
it {
|
|
65
|
+
it { expect(filter).to eq({}) }
|
|
78
66
|
end
|
|
79
67
|
|
|
80
68
|
context 'when except present' do
|
|
81
69
|
let(:filter_options) { { except: %w[key] } }
|
|
82
70
|
|
|
83
|
-
it {
|
|
71
|
+
it { expect(filter).to eq('boolean_key' => true, 'nested' => { 'key' => 'value' }) }
|
|
84
72
|
end
|
|
85
73
|
|
|
86
74
|
context 'when include present' do
|
|
87
75
|
let(:filter_options) { { only: %w[key] } }
|
|
88
76
|
|
|
89
|
-
it {
|
|
77
|
+
it { expect(filter).to eq('key' => 'value') }
|
|
90
78
|
end
|
|
91
79
|
|
|
92
80
|
context 'when empty options' do
|
|
93
81
|
let(:filter_options) { {} }
|
|
94
82
|
|
|
95
|
-
it {
|
|
83
|
+
it { expect(filter).to eq({}) }
|
|
96
84
|
end
|
|
97
85
|
end
|
|
98
86
|
|
|
99
87
|
describe '#method_missing' do
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
it { is_expected.to eq('value') }
|
|
88
|
+
it 'returns key value' do
|
|
89
|
+
expect(configuration.key).to eq('value')
|
|
104
90
|
end
|
|
105
91
|
|
|
106
|
-
|
|
107
|
-
|
|
92
|
+
it 'returns boolean key value' do
|
|
93
|
+
expect(configuration.boolean_key?).to be(true)
|
|
94
|
+
end
|
|
108
95
|
|
|
109
|
-
|
|
96
|
+
it 'raises on missing key' do
|
|
97
|
+
expect { configuration.some_key }.to raise_error(NoMethodError)
|
|
110
98
|
end
|
|
111
99
|
|
|
112
|
-
|
|
113
|
-
|
|
100
|
+
it 'raises on missing boolean key' do
|
|
101
|
+
expect { configuration.some_boolean_key? }.to raise_error(NoMethodError)
|
|
102
|
+
end
|
|
114
103
|
|
|
115
|
-
|
|
104
|
+
it 'returns nested key value' do
|
|
105
|
+
expect(configuration.nested.key).to eq('value')
|
|
116
106
|
end
|
|
117
107
|
end
|
|
118
108
|
|
|
119
|
-
describe '
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
109
|
+
describe 'predicate methods' do
|
|
110
|
+
let(:hash) do
|
|
111
|
+
{
|
|
112
|
+
false_string: 'false',
|
|
113
|
+
false_symbol: :false, # rubocop:disable Lint/BooleanSymbol
|
|
114
|
+
off_string: 'off',
|
|
115
|
+
zero_string: '0',
|
|
116
|
+
zero_integer: 0,
|
|
117
|
+
true_string: 'true',
|
|
118
|
+
true_symbol: :true, # rubocop:disable Lint/BooleanSymbol
|
|
119
|
+
on_string: 'on',
|
|
120
|
+
one_string: '1',
|
|
121
|
+
one_integer: 1,
|
|
122
|
+
random_string: ' Offset ',
|
|
123
|
+
empty_string: '',
|
|
124
|
+
nil_value: nil
|
|
125
|
+
}
|
|
124
126
|
end
|
|
125
127
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
it { expect(configuration.false_string?).to be(false) }
|
|
129
|
+
it { expect(configuration.false_symbol?).to be(false) }
|
|
130
|
+
it { expect(configuration.off_string?).to be(false) }
|
|
131
|
+
it { expect(configuration.zero_string?).to be(false) }
|
|
132
|
+
it { expect(configuration.zero_integer?).to be(false) }
|
|
133
|
+
it { expect(configuration.empty_string?).to be(false) }
|
|
134
|
+
it { expect(configuration.nil_value?).to be(false) }
|
|
135
|
+
|
|
136
|
+
it { expect(configuration.true_string?).to be(true) }
|
|
137
|
+
it { expect(configuration.true_symbol?).to be(true) }
|
|
138
|
+
it { expect(configuration.on_string?).to be(true) }
|
|
139
|
+
it { expect(configuration.one_string?).to be(true) }
|
|
140
|
+
it { expect(configuration.one_integer?).to be(true) }
|
|
141
|
+
it { expect(configuration.random_string?).to be(true) }
|
|
142
|
+
end
|
|
128
143
|
|
|
129
|
-
|
|
144
|
+
describe '#respond_to_missing?' do
|
|
145
|
+
it 'responds to key' do
|
|
146
|
+
expect(configuration.respond_to?(:key)).to be(true)
|
|
130
147
|
end
|
|
131
148
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
it { is_expected.to eq(true) }
|
|
149
|
+
it 'does not respond to unknown key' do
|
|
150
|
+
expect(configuration.respond_to?(:some_key)).to be(false)
|
|
136
151
|
end
|
|
137
152
|
|
|
138
|
-
|
|
139
|
-
|
|
153
|
+
it 'responds to nested key' do
|
|
154
|
+
expect(configuration.nested.respond_to?(:key)).to be(true)
|
|
155
|
+
end
|
|
140
156
|
|
|
141
|
-
|
|
157
|
+
it 'calls a method' do
|
|
158
|
+
expect(configuration.method(:key).call).to eq('value')
|
|
142
159
|
end
|
|
143
160
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
expect { configuration.method(:some_key) }.to raise_error(NameError)
|
|
147
|
-
end
|
|
161
|
+
it 'raised on a missing method call' do
|
|
162
|
+
expect { configuration.method(:some_key) }.to raise_error(NameError)
|
|
148
163
|
end
|
|
149
164
|
end
|
|
150
|
-
|
|
151
165
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Global do
|
|
4
|
+
subject(:global) { described_class }
|
|
5
|
+
|
|
6
|
+
describe 'merging backends' do
|
|
7
|
+
# rubocop:disable RSpec/VerifiedDoubles
|
|
8
|
+
let(:backend_alpha) { double('backend_alpha', load: { foo: 'foo', bar: 'bar-alpha' }) }
|
|
9
|
+
let(:backend_beta) { double('backend_beta', load: { 'bar' => 'bar-beta', 'baz' => 'baz' }) }
|
|
10
|
+
# rubocop:enable RSpec/VerifiedDoubles
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
global.backend backend_alpha
|
|
14
|
+
global.backend backend_beta
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'merges data from two backends together' do
|
|
18
|
+
expect(global.configuration.to_hash).to eq(
|
|
19
|
+
'foo' => 'foo',
|
|
20
|
+
'bar' => 'bar-beta',
|
|
21
|
+
'baz' => 'baz'
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/spec/global_spec.rb
CHANGED
|
@@ -1,65 +1,62 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
3
|
RSpec.describe Global do
|
|
6
|
-
|
|
7
4
|
let(:config_path) { File.join(Dir.pwd, 'spec/files') }
|
|
8
|
-
|
|
5
|
+
|
|
6
|
+
before do
|
|
9
7
|
described_class.configure do |config|
|
|
10
8
|
config.backend :filesystem, path: config_path, environment: 'test'
|
|
11
9
|
end
|
|
12
10
|
end
|
|
13
11
|
|
|
14
12
|
describe '.configuration' do
|
|
15
|
-
subject { described_class.configuration }
|
|
13
|
+
subject(:configuration) { described_class.configuration }
|
|
16
14
|
|
|
17
15
|
it { is_expected.to be_instance_of(Global::Configuration) }
|
|
18
16
|
|
|
19
17
|
context 'when load from directory' do
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
end
|
|
18
|
+
it 'loads configuration' do
|
|
19
|
+
expect(configuration.rspec_config.to_hash).to eq(
|
|
20
|
+
'default_value' => 'default value',
|
|
21
|
+
'test_value' => 'test value'
|
|
22
|
+
)
|
|
26
23
|
end
|
|
27
24
|
end
|
|
28
25
|
|
|
29
26
|
context 'when load from file' do
|
|
30
27
|
let(:config_path) { File.join(Dir.pwd, 'spec/files/rspec_config') }
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
it 'loads configuration' do
|
|
30
|
+
expect(configuration.to_hash).to eq(
|
|
31
|
+
'default_value' => 'default value',
|
|
32
|
+
'test_value' => 'test value'
|
|
33
|
+
)
|
|
37
34
|
end
|
|
38
35
|
end
|
|
39
36
|
|
|
40
37
|
context 'when nested directories' do
|
|
41
|
-
it { expect(
|
|
38
|
+
it { expect(configuration.rspec['config'].to_hash).to eq('default_value' => 'default nested value', 'test_value' => 'test nested value') }
|
|
42
39
|
end
|
|
43
40
|
|
|
44
41
|
context 'when boolean' do
|
|
45
|
-
it { expect(
|
|
46
|
-
it { expect(
|
|
42
|
+
it { expect(configuration.bool_config.works).to be(true) }
|
|
43
|
+
it { expect(configuration.bool_config.works?).to be(true) }
|
|
47
44
|
end
|
|
48
45
|
|
|
49
|
-
|
|
50
|
-
it { expect(
|
|
51
|
-
it { expect(
|
|
52
|
-
it { expect(
|
|
46
|
+
describe 'environment file' do
|
|
47
|
+
it { expect(configuration.aws.activated).to be(true) }
|
|
48
|
+
it { expect(configuration.aws.api_key).to eq('some api key') }
|
|
49
|
+
it { expect(configuration.aws.api_secret).to eq('some secret') }
|
|
53
50
|
end
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
it { expect(
|
|
57
|
-
it { expect {
|
|
52
|
+
describe 'skip files with dots in name' do
|
|
53
|
+
it { expect(configuration['aws.test']).to be_nil }
|
|
54
|
+
it { expect { configuration.fetch('aws.test') }.to raise_error(KeyError, /key not found/) }
|
|
58
55
|
end
|
|
59
56
|
end
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
subject { described_class.reload! }
|
|
58
|
+
describe '.reload!' do
|
|
59
|
+
subject(:reloaded_configuration) { described_class.reload! }
|
|
63
60
|
|
|
64
61
|
before do
|
|
65
62
|
described_class.configuration
|
|
@@ -67,49 +64,39 @@ RSpec.describe Global do
|
|
|
67
64
|
described_class.backend :filesystem, path: config_path, environment: 'development'
|
|
68
65
|
end
|
|
69
66
|
|
|
70
|
-
it
|
|
67
|
+
it 'returns configuration' do
|
|
68
|
+
expect(reloaded_configuration).to be_instance_of(Global::Configuration)
|
|
69
|
+
end
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
end
|
|
71
|
+
it 'reloads configuration' do
|
|
72
|
+
expect(reloaded_configuration.rspec_config.to_hash).to eq(
|
|
73
|
+
'default_value' => 'default value',
|
|
74
|
+
'test_value' => 'development value'
|
|
75
|
+
)
|
|
78
76
|
end
|
|
79
77
|
end
|
|
80
78
|
|
|
81
79
|
describe '.respond_to_missing?' do
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
it { is_expected.to be_truthy }
|
|
80
|
+
it 'responds to present config' do
|
|
81
|
+
expect(described_class.respond_to?(:rspec_config)).to be(true)
|
|
86
82
|
end
|
|
87
83
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
it { is_expected.to be_falsey }
|
|
84
|
+
it 'does not respond to missing config' do
|
|
85
|
+
expect(described_class.respond_to?(:some_file)).to be(false)
|
|
92
86
|
end
|
|
93
87
|
end
|
|
94
88
|
|
|
95
89
|
describe '.method_missing' do
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
it { is_expected.to be_kind_of(Global::Configuration) }
|
|
90
|
+
it 'returns configuration' do
|
|
91
|
+
expect(described_class.rspec_config).to be_a(Global::Configuration)
|
|
100
92
|
end
|
|
101
93
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
it { expect { subject }.to raise_error(NoMethodError) }
|
|
94
|
+
it 'raises on missing configuration' do
|
|
95
|
+
expect { described_class.some_file }.to raise_error(NoMethodError)
|
|
106
96
|
end
|
|
107
97
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
it { is_expected.to be_kind_of(Global::Configuration) }
|
|
98
|
+
it 'returns config with nested hash' do
|
|
99
|
+
expect(described_class.nested_config).to be_a(Global::Configuration)
|
|
112
100
|
end
|
|
113
|
-
|
|
114
101
|
end
|
|
115
102
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
4
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
5
|
-
require 'rspec'
|
|
6
|
-
require 'global'
|
|
7
3
|
require 'simplecov'
|
|
8
4
|
|
|
9
5
|
SimpleCov.start do
|
|
@@ -12,6 +8,8 @@ SimpleCov.start do
|
|
|
12
8
|
add_group 'Libraries', '/lib/'
|
|
13
9
|
end
|
|
14
10
|
|
|
11
|
+
require 'global'
|
|
12
|
+
|
|
15
13
|
RSpec.configure do |config|
|
|
16
14
|
config.disable_monkey_patching!
|
|
17
15
|
|
metadata
CHANGED
|
@@ -1,99 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: global
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Railsware LLC
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-12-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: aws-sdk-ssm
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - "~>"
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '1'
|
|
20
|
-
type: :development
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - "~>"
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '1'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: google-cloud-secret_manager
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - "~>"
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :development
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - "~>"
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: rake
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - "~>"
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: 12.3.1
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - "~>"
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: 12.3.1
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: rspec
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - ">="
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '3.0'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - ">="
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '3.0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: rubocop
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - "~>"
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: 0.81.0
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - "~>"
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: 0.81.0
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: simplecov
|
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - "~>"
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: 0.16.1
|
|
90
|
-
type: :development
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - "~>"
|
|
95
|
-
- !ruby/object:Gem::Version
|
|
96
|
-
version: 0.16.1
|
|
97
13
|
- !ruby/object:Gem::Dependency
|
|
98
14
|
name: activesupport
|
|
99
15
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -115,11 +31,12 @@ executables:
|
|
|
115
31
|
extensions: []
|
|
116
32
|
extra_rdoc_files: []
|
|
117
33
|
files:
|
|
34
|
+
- ".github/workflows/tests.yml"
|
|
118
35
|
- ".gitignore"
|
|
119
36
|
- ".rspec"
|
|
120
37
|
- ".rubocop.yml"
|
|
121
38
|
- ".ruby-version"
|
|
122
|
-
-
|
|
39
|
+
- CHANGELOG.md
|
|
123
40
|
- CODE_OF_CONDUCT.md
|
|
124
41
|
- Gemfile
|
|
125
42
|
- LICENSE.txt
|
|
@@ -143,14 +60,15 @@ files:
|
|
|
143
60
|
- spec/global/backend/aws_parameter_store_spec.rb
|
|
144
61
|
- spec/global/backend/gcp_secret_manager_spec.rb
|
|
145
62
|
- spec/global/configuration_spec.rb
|
|
63
|
+
- spec/global_merge_backends_spec.rb
|
|
146
64
|
- spec/global_spec.rb
|
|
147
|
-
- spec/merge_backends_spec.rb
|
|
148
65
|
- spec/spec_helper.rb
|
|
149
66
|
homepage: https://github.com/railsware/global
|
|
150
67
|
licenses:
|
|
151
68
|
- MIT
|
|
152
|
-
metadata:
|
|
153
|
-
|
|
69
|
+
metadata:
|
|
70
|
+
rubygems_mfa_required: 'true'
|
|
71
|
+
post_install_message:
|
|
154
72
|
rdoc_options: []
|
|
155
73
|
require_paths:
|
|
156
74
|
- lib
|
|
@@ -158,27 +76,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
158
76
|
requirements:
|
|
159
77
|
- - ">="
|
|
160
78
|
- !ruby/object:Gem::Version
|
|
161
|
-
version:
|
|
79
|
+
version: 3.0.0
|
|
162
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
81
|
requirements:
|
|
164
82
|
- - ">="
|
|
165
83
|
- !ruby/object:Gem::Version
|
|
166
84
|
version: '0'
|
|
167
85
|
requirements: []
|
|
168
|
-
rubygems_version: 3.
|
|
169
|
-
signing_key:
|
|
86
|
+
rubygems_version: 3.5.22
|
|
87
|
+
signing_key:
|
|
170
88
|
specification_version: 4
|
|
171
89
|
summary: Simple way to load your configs from yaml/aws/gcp
|
|
172
|
-
test_files:
|
|
173
|
-
- spec/files/aws.test.yml
|
|
174
|
-
- spec/files/aws.yml
|
|
175
|
-
- spec/files/bool_config.yml
|
|
176
|
-
- spec/files/nested_config.yml
|
|
177
|
-
- spec/files/rspec/config.yml
|
|
178
|
-
- spec/files/rspec_config.yml
|
|
179
|
-
- spec/global/backend/aws_parameter_store_spec.rb
|
|
180
|
-
- spec/global/backend/gcp_secret_manager_spec.rb
|
|
181
|
-
- spec/global/configuration_spec.rb
|
|
182
|
-
- spec/global_spec.rb
|
|
183
|
-
- spec/merge_backends_spec.rb
|
|
184
|
-
- spec/spec_helper.rb
|
|
90
|
+
test_files: []
|
data/.travis.yml
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
language: ruby
|
|
2
|
-
os: linux
|
|
3
|
-
dist: bionic
|
|
4
|
-
|
|
5
|
-
cache:
|
|
6
|
-
bundler: true
|
|
7
|
-
|
|
8
|
-
rvm:
|
|
9
|
-
- 2.4
|
|
10
|
-
- 2.5
|
|
11
|
-
- 2.6
|
|
12
|
-
- 2.7
|
|
13
|
-
- ruby-head
|
|
14
|
-
- jruby-head
|
|
15
|
-
|
|
16
|
-
notifications:
|
|
17
|
-
email: false
|
|
18
|
-
|
|
19
|
-
matrix:
|
|
20
|
-
allow_failures:
|
|
21
|
-
- rvm: ruby-head
|
|
22
|
-
- rvm: jruby-head
|
data/spec/merge_backends_spec.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
RSpec.describe Global do
|
|
6
|
-
describe 'merging backends' do
|
|
7
|
-
it 'merges data from two backends together' do
|
|
8
|
-
backend_alpha = double('backend_alpha')
|
|
9
|
-
allow(backend_alpha).to receive(:load).and_return(foo: 'foo', bar: 'bar-alpha')
|
|
10
|
-
described_class.backend backend_alpha
|
|
11
|
-
|
|
12
|
-
backend_beta = double('backend_beta')
|
|
13
|
-
allow(backend_beta).to receive(:load).and_return('bar' => 'bar-beta', 'baz' => 'baz')
|
|
14
|
-
described_class.backend backend_beta
|
|
15
|
-
|
|
16
|
-
expect(described_class.configuration.to_hash).to eq(
|
|
17
|
-
'foo' => 'foo',
|
|
18
|
-
'bar' => 'bar-beta',
|
|
19
|
-
'baz' => 'baz'
|
|
20
|
-
)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|