config 2.2.3 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2212e68e8bb8e15f821b9420db10ec3111edcaa43bffe5450ae850d5228b3107
4
- data.tar.gz: de9c513f5a6450a95e113071adf79c3d3b3e2f3485a018e14ab72241a2f419e0
3
+ metadata.gz: a9553d786b6f2a87d956e85494f9f8fd083e42076989e7c8217b84f72b1d6469
4
+ data.tar.gz: 592b1002dd18e793f444c2b4d00220c4cbbaf2f1e850d33c0d6c5bc5c41ae236
5
5
  SHA512:
6
- metadata.gz: ae72b6c10869bbca57d7c476e5ba7b48637b6c94c083176b2c7321710bd4daebe5f41c03d3daf69157dd3f599f63f11d74e19141e98716ae3ef20c8c33469ba3
7
- data.tar.gz: 07e79c9a667587218a3370c03e912c113795fa00a9f50350065834c91b9d858e03ee1447da078e6ec5af19c32faa5317f3a94b071478d4b96397317504891ac7
6
+ metadata.gz: 80c5e1c7de910d8f7592b0bf2d1ad322dbf8aa6565617ca1f5d0bdede78316073aa5afb5bf6e7cb33ce42bace7770f4cb8f8a86d4fd13a31fc0e900e58c6ae9c
7
+ data.tar.gz: 8fe4ecdb8069e910c36f68cb3a55863182797539638be36f7be622057174a45f4605427aaa0f145fd399a518131310059408812e9ff5dd391a1c7691b45624a7
data/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@
4
4
 
5
5
  ...
6
6
 
7
+ ## 3.0.0
8
+
9
+ ### BREAKING CHANGES
10
+
11
+ * After upgrade behaviour of `to_h` would change and match behaviour of `to_hash`. Check [#217](https://github.com/rubyconfig/config/issues/217#issuecomment-741953382) for more details.
12
+ * `Config::Options#load_env!` and `Config::Options#reload_env!` have been removed. If you need to reload settings after modifying the `ENV` hash, use `Config.reload!` or `Config::Options#reload!` instead.
13
+
14
+ ### Bug fixes
15
+
16
+ * Added alias `to_h` for `to_hash` ([#277](https://github.com/railsconfig/config/issues/277))
17
+
18
+ ### Changes
19
+
20
+ * Add `Config::Sources::EnvSource` for loading settings from flat `Hash`es with `String` keys and `String` values ([#299](https://github.com/railsconfig/config/pull/299))
21
+
7
22
  ## 2.2.3
8
23
 
9
24
  ### Bug fixes
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Config
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/config.svg)](http://badge.fury.io/rb/config)
3
+ [![Version](https://img.shields.io/gem/v/config)](https://rubygems.org/gems/config)
4
+ [![Downloads Total](https://img.shields.io/gem/dt/config)](https://rubygems.org/gems/config)
5
+ [![Build](https://img.shields.io/github/workflow/status/rubyconfig/config/tests)](https://rubygems.org/gems/config)
4
6
  [![Tests](https://github.com/rubyconfig/config/workflows/tests/badge.svg)](https://github.com/rubyconfig/config/actions?query=branch%3Amaster)
5
- [![Maintainability](https://api.codeclimate.com/v1/badges/85c206c13dce7de090af/maintainability)](https://codeclimate.com/github/rubyconfig/config/maintainability)
6
- [![Test Coverage](https://api.codeclimate.com/v1/badges/85c206c13dce7de090af/test_coverage)](https://codeclimate.com/github/rubyconfig/config/test_coverage)
7
7
  [![Financial Contributors on Open Collective](https://opencollective.com/rubyconfig/all/badge.svg?label=backers)](https://opencollective.com/rubyconfig)
8
8
 
9
9
  ## Summary
@@ -480,6 +480,50 @@ Settings.section.server # => 'google.com'
480
480
  Settings.section.ssl_enabled # => false
481
481
  ```
482
482
 
483
+ ### Working with AWS Secrets Manager
484
+
485
+ It is possible to parse variables stored in an AWS Secrets Manager Secret as if they were environment variables by using `Config::Sources::EnvSource`.
486
+
487
+ For example, the plaintext secret might look like this:
488
+
489
+ ```json
490
+ {
491
+ "Settings.foo": "hello",
492
+ "Settings.bar": "world",
493
+ }
494
+ ```
495
+
496
+ In order to load those settings, fetch the settings from AWS Secrets Manager, parse the plaintext as JSON, pass the resulting `Hash` into a new `EnvSource`, load the new source, and reload.
497
+
498
+ ```ruby
499
+ # fetch secrets from AWS
500
+ client = Aws::SecretsManager::Client.new
501
+ response = client.get_secret_value(secret_id: "#{ENV['ENVIRONMENT']}/my_application")
502
+ secrets = JSON.parse(response.secret_string)
503
+
504
+ # load secrets into config
505
+ secret_source = Config::Sources::EnvSource.new(secrets)
506
+ Settings.add_source!(secret_source)
507
+ Settings.reload!
508
+ ```
509
+
510
+ In this case, the following settings will be available:
511
+
512
+ ```ruby
513
+ Settings.foo # => "hello"
514
+ Settings.bar # => "world"
515
+ ```
516
+
517
+ By default, `EnvSource` will use configuration for `env_prefix`, `env_separator`, `env_converter`, and `env_parse_values`, but any of these can be overridden in the constructor.
518
+
519
+ ```ruby
520
+ secret_source = Config::Sources::EnvSource.new(secrets,
521
+ prefix: 'MyConfig',
522
+ separator: '__',
523
+ converter: nil,
524
+ parse_values: false)
525
+ ```
526
+
483
527
  ## Contributing
484
528
 
485
529
  You are very warmly welcome to help. Please follow our [contribution guidelines](CONTRIBUTING.md)
data/lib/config.rb CHANGED
@@ -4,6 +4,7 @@ require 'config/configuration'
4
4
  require 'config/version'
5
5
  require 'config/sources/yaml_source'
6
6
  require 'config/sources/hash_source'
7
+ require 'config/sources/env_source'
7
8
  require 'config/validation/schema'
8
9
  require 'deep_merge'
9
10
 
@@ -41,6 +42,8 @@ module Config
41
42
  config.add_source!(file.to_s)
42
43
  end
43
44
 
45
+ config.add_source!(Sources::EnvSource.new(ENV)) if Config.use_env
46
+
44
47
  config.load!
45
48
  config
46
49
  end
@@ -31,47 +31,6 @@ module Config
31
31
  @config_sources.unshift(source)
32
32
  end
33
33
 
34
- def reload_env!
35
- return self if ENV.nil? || ENV.empty?
36
-
37
- hash = Hash.new
38
-
39
- ENV.each do |variable, value|
40
- separator = Config.env_separator
41
- prefix = (Config.env_prefix || Config.const_name).to_s.split(separator)
42
-
43
- keys = variable.to_s.split(separator)
44
-
45
- next if keys.shift(prefix.size) != prefix
46
-
47
- keys.map! { |key|
48
- case Config.env_converter
49
- when :downcase then
50
- key.downcase.to_sym
51
- when nil then
52
- key.to_sym
53
- else
54
- raise "Invalid ENV variables name converter: #{Config.env_converter}"
55
- end
56
- }
57
-
58
- leaf = keys[0...-1].inject(hash) { |h, key|
59
- h[key] ||= {}
60
- }
61
-
62
- unless leaf.is_a?(Hash)
63
- conflicting_key = (prefix + keys[0...-1]).join(separator)
64
- raise "Environment variable #{variable} conflicts with variable #{conflicting_key}"
65
- end
66
-
67
- leaf[keys.last] = Config.env_parse_values ? __value(value) : value
68
- end
69
-
70
- merge!(hash)
71
- end
72
-
73
- alias :load_env! :reload_env!
74
-
75
34
  # look through all our sources and rebuild the configuration
76
35
  def reload!
77
36
  conf = {}
@@ -96,7 +55,6 @@ module Config
96
55
  # swap out the contents of the OStruct with a hash (need to recursively convert)
97
56
  marshal_load(__convert(conf).marshal_dump)
98
57
 
99
- reload_env! if Config.use_env
100
58
  validate!
101
59
 
102
60
  self
@@ -123,6 +81,8 @@ module Config
123
81
  result
124
82
  end
125
83
 
84
+ alias :to_h :to_hash
85
+
126
86
  def each(*args, &block)
127
87
  marshal_dump.each(*args, &block)
128
88
  end
@@ -221,17 +181,5 @@ module Config
221
181
  end
222
182
  s
223
183
  end
224
-
225
- # Try to convert string to a correct type
226
- def __value(v)
227
- case v
228
- when 'false'
229
- false
230
- when 'true'
231
- true
232
- else
233
- Integer(v) rescue Float(v) rescue v
234
- end
235
- end
236
184
  end
237
185
  end
@@ -0,0 +1,73 @@
1
+ module Config
2
+ module Sources
3
+ # Allows settings to be loaded from a "flat" hash with string keys, like ENV.
4
+ class EnvSource
5
+ attr_reader :prefix
6
+ attr_reader :separator
7
+ attr_reader :converter
8
+ attr_reader :parse_values
9
+
10
+ def initialize(env,
11
+ prefix: Config.env_prefix || Config.const_name,
12
+ separator: Config.env_separator,
13
+ converter: Config.env_converter,
14
+ parse_values: Config.env_parse_values)
15
+ @env = env
16
+ @prefix = prefix.to_s.split(separator)
17
+ @separator = separator
18
+ @converter = converter
19
+ @parse_values = parse_values
20
+ end
21
+
22
+ def load
23
+ return {} if @env.nil? || @env.empty?
24
+
25
+ hash = Hash.new
26
+
27
+ @env.each do |variable, value|
28
+ keys = variable.to_s.split(separator)
29
+
30
+ next if keys.shift(prefix.size) != prefix
31
+
32
+ keys.map! { |key|
33
+ case converter
34
+ when :downcase then
35
+ key.downcase
36
+ when nil then
37
+ key
38
+ else
39
+ raise "Invalid ENV variables name converter: #{converter}"
40
+ end
41
+ }
42
+
43
+ leaf = keys[0...-1].inject(hash) { |h, key|
44
+ h[key] ||= {}
45
+ }
46
+
47
+ unless leaf.is_a?(Hash)
48
+ conflicting_key = (prefix + keys[0...-1]).join(separator)
49
+ raise "Environment variable #{variable} conflicts with variable #{conflicting_key}"
50
+ end
51
+
52
+ leaf[keys.last] = parse_values ? __value(value) : value
53
+ end
54
+
55
+ hash
56
+ end
57
+
58
+ private
59
+
60
+ # Try to convert string to a correct type
61
+ def __value(v)
62
+ case v
63
+ when 'false'
64
+ false
65
+ when 'true'
66
+ true
67
+ else
68
+ Integer(v) rescue Float(v) rescue v
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,3 +1,3 @@
1
1
  module Config
2
- VERSION = '2.2.3'.freeze
2
+ VERSION = '3.0.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: config
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.3
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Kuczynski
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-12-09 00:00:00.000000000 Z
13
+ date: 2021-02-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: deep_merge
@@ -36,82 +36,82 @@ dependencies:
36
36
  name: dry-validation
37
37
  requirement: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
40
- - !ruby/object:Gem::Version
41
- version: '1.0'
42
39
  - - ">="
43
40
  - !ruby/object:Gem::Version
44
41
  version: 1.0.0
42
+ - - "~>"
43
+ - !ruby/object:Gem::Version
44
+ version: '1.0'
45
45
  type: :runtime
46
46
  prerelease: false
47
47
  version_requirements: !ruby/object:Gem::Requirement
48
48
  requirements:
49
- - - "~>"
50
- - !ruby/object:Gem::Version
51
- version: '1.0'
52
49
  - - ">="
53
50
  - !ruby/object:Gem::Version
54
51
  version: 1.0.0
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '12.0'
62
59
  - - ">="
63
60
  - !ruby/object:Gem::Version
64
61
  version: 12.0.0
62
+ - - "~>"
63
+ - !ruby/object:Gem::Version
64
+ version: '12.0'
65
65
  type: :development
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
68
68
  requirements:
69
- - - "~>"
70
- - !ruby/object:Gem::Version
71
- version: '12.0'
72
69
  - - ">="
73
70
  - !ruby/object:Gem::Version
74
71
  version: 12.0.0
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '12.0'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: appraisal
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '2.3'
82
79
  - - ">="
83
80
  - !ruby/object:Gem::Version
84
81
  version: 2.3.0
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: '2.3'
85
85
  type: :development
86
86
  prerelease: false
87
87
  version_requirements: !ruby/object:Gem::Requirement
88
88
  requirements:
89
- - - "~>"
90
- - !ruby/object:Gem::Version
91
- version: '2.3'
92
89
  - - ">="
93
90
  - !ruby/object:Gem::Version
94
91
  version: 2.3.0
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '2.3'
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: rspec
97
97
  requirement: !ruby/object:Gem::Requirement
98
98
  requirements:
99
- - - "~>"
100
- - !ruby/object:Gem::Version
101
- version: '3.9'
102
99
  - - ">="
103
100
  - !ruby/object:Gem::Version
104
101
  version: 3.9.0
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '3.9'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - "~>"
110
- - !ruby/object:Gem::Version
111
- version: '3.9'
112
109
  - - ">="
113
110
  - !ruby/object:Gem::Version
114
111
  version: 3.9.0
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '3.9'
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: bootsnap
117
117
  requirement: !ruby/object:Gem::Requirement
@@ -158,22 +158,22 @@ dependencies:
158
158
  name: mdl
159
159
  requirement: !ruby/object:Gem::Requirement
160
160
  requirements:
161
- - - "~>"
162
- - !ruby/object:Gem::Version
163
- version: '0.9'
164
161
  - - ">="
165
162
  - !ruby/object:Gem::Version
166
163
  version: 0.9.0
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '0.9'
167
167
  type: :development
168
168
  prerelease: false
169
169
  version_requirements: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: '0.9'
174
171
  - - ">="
175
172
  - !ruby/object:Gem::Version
176
173
  version: 0.9.0
174
+ - - "~>"
175
+ - !ruby/object:Gem::Version
176
+ version: '0.9'
177
177
  - !ruby/object:Gem::Dependency
178
178
  name: rubocop
179
179
  requirement: !ruby/object:Gem::Requirement
@@ -215,6 +215,7 @@ files:
215
215
  - lib/config/integrations/sinatra.rb
216
216
  - lib/config/options.rb
217
217
  - lib/config/rack/reloader.rb
218
+ - lib/config/sources/env_source.rb
218
219
  - lib/config/sources/hash_source.rb
219
220
  - lib/config/sources/yaml_source.rb
220
221
  - lib/config/tasks/heroku.rake
@@ -250,7 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
251
  - !ruby/object:Gem::Version
251
252
  version: '0'
252
253
  requirements: []
253
- rubygems_version: 3.1.2
254
+ rubygems_version: 3.0.3
254
255
  signing_key:
255
256
  specification_version: 4
256
257
  summary: Effortless multi-environment settings in Rails, Sinatra, Pandrino and others