config 2.2.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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