config 2.2.2 → 3.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/README.md +69 -6
- data/lib/config/options.rb +0 -49
- data/lib/config/sources/env_source.rb +73 -0
- data/lib/config/sources/yaml_source.rb +8 -2
- data/lib/config/version.rb +1 -1
- data/lib/config.rb +5 -1
- data/lib/generators/config/templates/config.rb +3 -0
- metadata +28 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df10a2302fd2bd1f1199e97150b44d3f58a28915533dd7579bf58ed6fb77d7dd
|
4
|
+
data.tar.gz: 3fe17720f82d92766fd81b6f4dfcdeea1824ca7aa8a71302d4430496cf5921a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9818ca58226256e90282c8dd1e92d1cac9ad77331e31a8073e811a5be36ada096914030da47ac8df2e57a8dcfcaa0d4d20b5a58ffd934602ac9b02356b53f51
|
7
|
+
data.tar.gz: 680d6f2b9002d1ede073b391ff747c47fe5bf13f87689dbed1e59b3f8a3abb031449069593e8de01086b62631a43936e3f461008340ed88d23b39a35ab29a2d2
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,43 @@
|
|
4
4
|
|
5
5
|
...
|
6
6
|
|
7
|
+
## 3.1.1
|
8
|
+
|
9
|
+
### Bug fixes
|
10
|
+
|
11
|
+
* Allow the use of unsafe YAML parsing features when using psych >= 4 ([#306](https://github.com/railsconfig/config/issues/306))
|
12
|
+
|
13
|
+
## 3.1.0
|
14
|
+
|
15
|
+
### New features
|
16
|
+
|
17
|
+
* Evaluating ERB in YAML files can now be disabled with `Config.evaluate_erb_in_yaml = false`. The default value for this option is `true` for backwards-compatibility. ([#303](https://github.com/rubyconfig/config/pull/303))
|
18
|
+
|
19
|
+
## 3.0.0
|
20
|
+
|
21
|
+
### BREAKING CHANGES
|
22
|
+
|
23
|
+
* 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.
|
24
|
+
* `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.
|
25
|
+
|
26
|
+
### Bug fixes
|
27
|
+
|
28
|
+
* Added alias `to_h` for `to_hash` ([#277](https://github.com/railsconfig/config/issues/277))
|
29
|
+
|
30
|
+
### Changes
|
31
|
+
|
32
|
+
* Add `Config::Sources::EnvSource` for loading settings from flat `Hash`es with `String` keys and `String` values, such as from AWS SecretsManager ([#299](https://github.com/railsconfig/config/pull/299))
|
33
|
+
|
34
|
+
## 2.2.3
|
35
|
+
|
36
|
+
### Bug fixes
|
37
|
+
|
38
|
+
* Revert added alias to_h for to_hash ([#277](https://github.com/railsconfig/config/issues/277))
|
39
|
+
|
40
|
+
### Changes
|
41
|
+
|
42
|
+
* Raise explicit error on environment variable conflicts ([#293](https://github.com/railsconfig/config/issues/293))
|
43
|
+
|
7
44
|
## 2.2.2
|
8
45
|
|
9
46
|
### Bug fixes
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Config
|
2
2
|
|
3
|
-
[![
|
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
|
@@ -190,8 +190,9 @@ Settings.add_source!("#{Rails.root}/config/settings/local.yml")
|
|
190
190
|
Settings.reload!
|
191
191
|
```
|
192
192
|
|
193
|
-
> Note: this is an example usage, it is easier to just use the default local
|
194
|
-
settings
|
193
|
+
> Note: this is an example usage, it is easier to just use the default local
|
194
|
+
> files `settings.local.yml`, `settings/#{Rails.env}.local.yml` and
|
195
|
+
> `environments/#{Rails.env}.local.yml` for your developer specific settings.
|
195
196
|
|
196
197
|
You also have the option to add a raw hash as a source. One use case might be storing settings in the database or in environment variables that overwrite what is in the YML files.
|
197
198
|
|
@@ -204,7 +205,9 @@ You may pass a hash to `prepend_source!` as well.
|
|
204
205
|
|
205
206
|
## Embedded Ruby (ERB)
|
206
207
|
|
207
|
-
Embedded Ruby is allowed in the configuration files.
|
208
|
+
Embedded Ruby is allowed in the YAML configuration files. ERB will be evaluated at load time by default, and when the `evaluate_erb_in_yaml` configuration is set to `true`.
|
209
|
+
|
210
|
+
Consider the two following config files.
|
208
211
|
|
209
212
|
* ```#{Rails.root}/config/settings.yml```
|
210
213
|
|
@@ -265,6 +268,7 @@ After installing `Config` in Rails, you will find automatically generated file t
|
|
265
268
|
### General
|
266
269
|
|
267
270
|
* `const_name` - name of the object holing you settings. Default: `'Settings'`
|
271
|
+
* `evaluate_erb_in_yaml` - evaluate ERB in YAML config files. Set to false if the config file contains ERB that should not be evaluated at load time. Default: `true`
|
268
272
|
|
269
273
|
### Merge customization
|
270
274
|
|
@@ -419,6 +423,21 @@ ENV['Settings.section.server'] = 'google.com'
|
|
419
423
|
|
420
424
|
It won't work with arrays, though.
|
421
425
|
|
426
|
+
It is considered an error to use environment variables to simutaneously assign a "flat" value and a multi-level value to a key.
|
427
|
+
|
428
|
+
```ruby
|
429
|
+
# Raises an error when settings are loaded
|
430
|
+
ENV['BACKEND_DATABASE'] = 'development'
|
431
|
+
ENV['BACKEND_DATABASE_USER'] = 'postgres'
|
432
|
+
```
|
433
|
+
|
434
|
+
Instead, specify keys of equal depth in the environment variable names:
|
435
|
+
|
436
|
+
```ruby
|
437
|
+
ENV['BACKEND_DATABASE_NAME'] = 'development'
|
438
|
+
ENV['BACKEND_DATABASE_USER'] = 'postgres'
|
439
|
+
```
|
440
|
+
|
422
441
|
### Working with Heroku
|
423
442
|
|
424
443
|
Heroku uses ENV object to store sensitive settings. You cannot upload such files to Heroku because it's ephemeral filesystem gets recreated from the git sources on each instance refresh. To use config with Heroku just set the `use_env` var to `true` as mentioned above.
|
@@ -464,6 +483,50 @@ Settings.section.server # => 'google.com'
|
|
464
483
|
Settings.section.ssl_enabled # => false
|
465
484
|
```
|
466
485
|
|
486
|
+
### Working with AWS Secrets Manager
|
487
|
+
|
488
|
+
It is possible to parse variables stored in an AWS Secrets Manager Secret as if they were environment variables by using `Config::Sources::EnvSource`.
|
489
|
+
|
490
|
+
For example, the plaintext secret might look like this:
|
491
|
+
|
492
|
+
```json
|
493
|
+
{
|
494
|
+
"Settings.foo": "hello",
|
495
|
+
"Settings.bar": "world",
|
496
|
+
}
|
497
|
+
```
|
498
|
+
|
499
|
+
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.
|
500
|
+
|
501
|
+
```ruby
|
502
|
+
# fetch secrets from AWS
|
503
|
+
client = Aws::SecretsManager::Client.new
|
504
|
+
response = client.get_secret_value(secret_id: "#{ENV['ENVIRONMENT']}/my_application")
|
505
|
+
secrets = JSON.parse(response.secret_string)
|
506
|
+
|
507
|
+
# load secrets into config
|
508
|
+
secret_source = Config::Sources::EnvSource.new(secrets)
|
509
|
+
Settings.add_source!(secret_source)
|
510
|
+
Settings.reload!
|
511
|
+
```
|
512
|
+
|
513
|
+
In this case, the following settings will be available:
|
514
|
+
|
515
|
+
```ruby
|
516
|
+
Settings.foo # => "hello"
|
517
|
+
Settings.bar # => "world"
|
518
|
+
```
|
519
|
+
|
520
|
+
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.
|
521
|
+
|
522
|
+
```ruby
|
523
|
+
secret_source = Config::Sources::EnvSource.new(secrets,
|
524
|
+
prefix: 'MyConfig',
|
525
|
+
separator: '__',
|
526
|
+
converter: nil,
|
527
|
+
parse_values: false)
|
528
|
+
```
|
529
|
+
|
467
530
|
## Contributing
|
468
531
|
|
469
532
|
You are very warmly welcome to help. Please follow our [contribution guidelines](CONTRIBUTING.md)
|
data/lib/config/options.rb
CHANGED
@@ -31,42 +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
|
-
leaf[keys.last] = Config.env_parse_values ? __value(value) : value
|
63
|
-
end
|
64
|
-
|
65
|
-
merge!(hash)
|
66
|
-
end
|
67
|
-
|
68
|
-
alias :load_env! :reload_env!
|
69
|
-
|
70
34
|
# look through all our sources and rebuild the configuration
|
71
35
|
def reload!
|
72
36
|
conf = {}
|
@@ -91,7 +55,6 @@ module Config
|
|
91
55
|
# swap out the contents of the OStruct with a hash (need to recursively convert)
|
92
56
|
marshal_load(__convert(conf).marshal_dump)
|
93
57
|
|
94
|
-
reload_env! if Config.use_env
|
95
58
|
validate!
|
96
59
|
|
97
60
|
self
|
@@ -218,17 +181,5 @@ module Config
|
|
218
181
|
end
|
219
182
|
s
|
220
183
|
end
|
221
|
-
|
222
|
-
# Try to convert string to a correct type
|
223
|
-
def __value(v)
|
224
|
-
case v
|
225
|
-
when 'false'
|
226
|
-
false
|
227
|
-
when 'true'
|
228
|
-
true
|
229
|
-
else
|
230
|
-
Integer(v) rescue Float(v) rescue v
|
231
|
-
end
|
232
|
-
end
|
233
184
|
end
|
234
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
|
@@ -5,14 +5,20 @@ module Config
|
|
5
5
|
module Sources
|
6
6
|
class YAMLSource
|
7
7
|
attr_accessor :path
|
8
|
+
attr_reader :evaluate_erb
|
8
9
|
|
9
|
-
def initialize(path)
|
10
|
+
def initialize(path, evaluate_erb: Config.evaluate_erb_in_yaml)
|
10
11
|
@path = path.to_s
|
12
|
+
@evaluate_erb = !!evaluate_erb
|
11
13
|
end
|
12
14
|
|
13
15
|
# returns a config hash from the YML file
|
14
16
|
def load
|
15
|
-
|
17
|
+
if @path and File.exist?(@path)
|
18
|
+
file_contents = IO.read(@path)
|
19
|
+
file_contents = ERB.new(file_contents).result if evaluate_erb
|
20
|
+
result = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(file_contents) : YAML.load(file_contents)
|
21
|
+
end
|
16
22
|
|
17
23
|
result || {}
|
18
24
|
|
data/lib/config/version.rb
CHANGED
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
|
|
@@ -23,7 +24,8 @@ module Config
|
|
23
24
|
merge_nil_values: true,
|
24
25
|
overwrite_arrays: true,
|
25
26
|
merge_hash_arrays: false,
|
26
|
-
validation_contract: nil
|
27
|
+
validation_contract: nil,
|
28
|
+
evaluate_erb_in_yaml: true
|
27
29
|
)
|
28
30
|
|
29
31
|
def self.setup
|
@@ -41,6 +43,8 @@ module Config
|
|
41
43
|
config.add_source!(file.to_s)
|
42
44
|
end
|
43
45
|
|
46
|
+
config.add_source!(Sources::EnvSource.new(ENV)) if Config.use_env
|
47
|
+
|
44
48
|
config.load!
|
45
49
|
config
|
46
50
|
end
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: config
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Kuczynski
|
8
8
|
- Fred Wu
|
9
9
|
- Jacques Crocker
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2022-01-04 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: deep_merge
|
@@ -116,44 +116,58 @@ dependencies:
|
|
116
116
|
name: bootsnap
|
117
117
|
requirement: !ruby/object:Gem::Requirement
|
118
118
|
requirements:
|
119
|
-
- - "
|
119
|
+
- - ">="
|
120
120
|
- !ruby/object:Gem::Version
|
121
|
-
version:
|
121
|
+
version: 1.4.4
|
122
122
|
type: :development
|
123
123
|
prerelease: false
|
124
124
|
version_requirements: !ruby/object:Gem::Requirement
|
125
125
|
requirements:
|
126
|
-
- - "
|
126
|
+
- - ">="
|
127
127
|
- !ruby/object:Gem::Version
|
128
|
-
version:
|
128
|
+
version: 1.4.4
|
129
129
|
- !ruby/object:Gem::Dependency
|
130
130
|
name: rails
|
131
131
|
requirement: !ruby/object:Gem::Requirement
|
132
132
|
requirements:
|
133
133
|
- - '='
|
134
134
|
- !ruby/object:Gem::Version
|
135
|
-
version: 6.
|
135
|
+
version: 6.1.4
|
136
136
|
type: :development
|
137
137
|
prerelease: false
|
138
138
|
version_requirements: !ruby/object:Gem::Requirement
|
139
139
|
requirements:
|
140
140
|
- - '='
|
141
141
|
- !ruby/object:Gem::Version
|
142
|
-
version: 6.
|
142
|
+
version: 6.1.4
|
143
143
|
- !ruby/object:Gem::Dependency
|
144
144
|
name: rspec-rails
|
145
145
|
requirement: !ruby/object:Gem::Requirement
|
146
146
|
requirements:
|
147
147
|
- - "~>"
|
148
148
|
- !ruby/object:Gem::Version
|
149
|
-
version: '
|
149
|
+
version: '5.0'
|
150
150
|
type: :development
|
151
151
|
prerelease: false
|
152
152
|
version_requirements: !ruby/object:Gem::Requirement
|
153
153
|
requirements:
|
154
154
|
- - "~>"
|
155
155
|
- !ruby/object:Gem::Version
|
156
|
-
version: '
|
156
|
+
version: '5.0'
|
157
|
+
- !ruby/object:Gem::Dependency
|
158
|
+
name: psych
|
159
|
+
requirement: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '4'
|
164
|
+
type: :development
|
165
|
+
prerelease: false
|
166
|
+
version_requirements: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '4'
|
157
171
|
- !ruby/object:Gem::Dependency
|
158
172
|
name: mdl
|
159
173
|
requirement: !ruby/object:Gem::Requirement
|
@@ -215,6 +229,7 @@ files:
|
|
215
229
|
- lib/config/integrations/sinatra.rb
|
216
230
|
- lib/config/options.rb
|
217
231
|
- lib/config/rack/reloader.rb
|
232
|
+
- lib/config/sources/env_source.rb
|
218
233
|
- lib/config/sources/hash_source.rb
|
219
234
|
- lib/config/sources/yaml_source.rb
|
220
235
|
- lib/config/tasks/heroku.rake
|
@@ -250,8 +265,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
250
265
|
- !ruby/object:Gem::Version
|
251
266
|
version: '0'
|
252
267
|
requirements: []
|
253
|
-
rubygems_version: 3.1.
|
254
|
-
signing_key:
|
268
|
+
rubygems_version: 3.1.6
|
269
|
+
signing_key:
|
255
270
|
specification_version: 4
|
256
271
|
summary: Effortless multi-environment settings in Rails, Sinatra, Pandrino and others
|
257
272
|
test_files: []
|