config 2.2.1 → 4.2.1

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: 554478f496c7582db5d4a3965d44499cde1b9d739002cf9e828eb0578de3b356
4
- data.tar.gz: d3d21afa1efa34e03d958e4ae347de44ff00f2e1f45ffdeceef8785bfcb41b61
3
+ metadata.gz: d8e3673269abb8919961385bf27374aac4125d46988f5f69114feb7b2d36ef30
4
+ data.tar.gz: 040fff3a658f33f09da8296079a0672b28fbce8e3e6333c8dfacdfb8a239e998
5
5
  SHA512:
6
- metadata.gz: bde322b8eb560783917d36ebcaea664d10b255ccdf915b86fa8330b3e7ed50aba4c3f66ba265f5b2bd896a679bd74ccc6add60e2f5d92a088fb8c1d61cafce75
7
- data.tar.gz: 81895a02cdda30016f6dc80d2f6a5d3e01669d884ee177ec5bbdc910938a4e3f5964749416694afa99b375316735ba98c1a375ee90430a847b6ee5cd68e64809
6
+ metadata.gz: 859eda030f5b0ac224a367359f4fc8c1af2a45eab726c74691db3da79fd3f2cb8fa6f85011036be6fef7c07600a0f5687e96db2f3a09bb1430755bfb7322cd86
7
+ data.tar.gz: 0d233e69e12d0f92d6edd3d588e727905b8bff7d57b93027ec40290131ea3883208e4509db3fff946a30a326a6b34fe6fae340dacb12ea196cb07cd1eb68c850
data/CHANGELOG.md CHANGED
@@ -1,8 +1,83 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 4.2.1
4
4
 
5
- ...
5
+ ### Bug fixes
6
+
7
+ * Address edge case with `table` config param ([#339](https://github.com/rubyconfig/config/pull/339))
8
+
9
+ ## 4.2.0
10
+
11
+ ### Bug fixes
12
+
13
+ * Remove use of method `File.exists?` to fix use in Ruby 3.0 ([#318](https://github.com/rubyconfig/config/pull/318))
14
+
15
+ ## 4.1.0
16
+
17
+ ### Bug fixes
18
+
19
+ * Only load `Railtie` integration if `Rails::Railtie` is defined ([#319](https://github.com/rubyconfig/config/pull/319))
20
+ * Fix indentation warning in Ruby 3.1 ([#322](https://github.com/rubyconfig/config/pull/322))
21
+
22
+ ## 4.0.0
23
+
24
+ ### BREAKING CHANGES
25
+
26
+ * Rails versions `< 5.2` are no longer supported ([#316](https://github.com/rubyconfig/config/pull/316))
27
+ * Ruby versions `< 2.6` are no longer supported ([#316](https://github.com/rubyconfig/config/pull/316))
28
+ * Support `HashSource` and `EnvSource` instances in `Config.load_files` and `Config.load_and_set_settings`. ([#315](https://github.com/rubyconfig/config/pull/315)). There are a few subtle breaking changes:
29
+ * Previously, `Config.load_files` (called from `Config.load_and_set_settings`) would call `.to_s` on each of its arguments. Now, this responsibility is defered to YAMLSource. In effect, if your application passes String or Pathname objects to `Config.load_files`, no changes are necessary, but if you were somehow relying on the `.to_s` call for some other type of object, you'll now need to call `.to_s` on that object before passing it to `Config`.
30
+ * Before this change, `Config.load_files` would call `uniq` on its argument array. This call has been removed, so duplicate file paths are not removed before further processing. In some cases, this can cause differences in behavior since later config files override the values in earlier ones. In most cases, it's best to ensure that duplicate paths are not passed to `Config.load_files`.
31
+
32
+ ## 3.1.1
33
+
34
+ ### Bug fixes
35
+
36
+ * Allow the use of unsafe YAML parsing features when using psych >= 4 ([#306](https://github.com/railsconfig/config/issues/306))
37
+
38
+ ## 3.1.0
39
+
40
+ ### New features
41
+
42
+ * 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))
43
+
44
+ ## 3.0.0
45
+
46
+ ### BREAKING CHANGES
47
+
48
+ * 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.
49
+ * `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.
50
+
51
+ ### Bug fixes
52
+
53
+ * Added alias `to_h` for `to_hash` ([#277](https://github.com/railsconfig/config/issues/277))
54
+
55
+ ### Changes
56
+
57
+ * 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))
58
+
59
+ ## 2.2.3
60
+
61
+ ### Bug fixes
62
+
63
+ * Revert added alias to_h for to_hash ([#277](https://github.com/railsconfig/config/issues/277))
64
+
65
+ ### Changes
66
+
67
+ * Raise explicit error on environment variable conflicts ([#293](https://github.com/railsconfig/config/issues/293))
68
+
69
+ ## 2.2.2
70
+
71
+ ### Bug fixes
72
+
73
+ * Added alias to_h for to_hash ([#277](https://github.com/railsconfig/config/issues/277))
74
+ * Prevent unnecessary doubled loading of environment variables ([#291](https://github.com/rubyconfig/config/pull/291))
75
+ * Return `Hash` from `Config::Options#as_json` instead of `Array` of pairs when using ActiveSupport Core Extensions ([#292](https://github.com/rubyconfig/config/pull/292))
76
+
77
+ ### Changes
78
+
79
+ * Add JRuby 9.2 to the test matrix ([#228](https://github.com/railsconfig/config/issues/228))
80
+ * Add exit! to reserved keywords ([#289](https://github.com/railsconfig/config/issues/289))
6
81
 
7
82
  ## 2.2.1
8
83
 
@@ -16,7 +91,7 @@
16
91
 
17
92
  * Fix missing new_ostruct_member in Ruby 2.7 ([#255](https://github.com/rubyconfig/config/pull/255))
18
93
  * Fix validation contract documentation ([#260](https://github.com/rubyconfig/config/pull/260))
19
- * Fix validation contract documentation ([#260](https://github.com/rubyconfig/config/pull/260))
94
+ * Excluded test application's *.md files from the gem build ([#267](https://github.com/rubyconfig/config/pull/267))
20
95
 
21
96
  ### Changes
22
97
 
data/README.md CHANGED
@@ -1,9 +1,8 @@
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)
4
5
  [![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
6
  [![Financial Contributors on Open Collective](https://opencollective.com/rubyconfig/all/badge.svg?label=backers)](https://opencollective.com/rubyconfig)
8
7
 
9
8
  ## Summary
@@ -21,16 +20,21 @@ Config helps you easily manage environment specific settings in an easy and usab
21
20
 
22
21
  ## Compatibility
23
22
 
23
+ Current version supports and is [tested](.github/workflows/tests.yml#L19) for the following interpreters and frameworks:
24
+
24
25
  * Interpreters
25
- * [Ruby](https://www.ruby-lang.org/en/) `>= 2.4`
26
- * [TruffleRuby](https://github.com/oracle/truffleruby) `>= 19.0.0`
26
+ * [Ruby](https://www.ruby-lang.org) `>= 2.6`
27
+ * [JRuby](https://www.jruby.org) `>= 9.2`
28
+ * [TruffleRuby](https://github.com/oracle/truffleruby) `>= 19.3`
27
29
  * Application frameworks
28
- * Rails `>= 4.2` and `5`
30
+ * Rails `>= 5.2`
29
31
  * Padrino
30
32
  * Sinatra
31
33
 
32
34
  For Ruby `2.0` to `2.3` or Rails `3` to `4.1` use version `1.x` of this gem. For older versions of Rails or Ruby use [AppConfig](http://github.com/fredwu/app_config).
33
35
 
36
+ For Ruby `2.4` or `2.5` or Rails `4.2`, `5.0`, or `5.1` use version `3.x` of this gem.
37
+
34
38
  ## Installing
35
39
 
36
40
  ### Installing on Rails
@@ -42,6 +46,7 @@ Add `gem 'config'` to your `Gemfile` and run `bundle install` to install it. The
42
46
  which will generate customizable config file `config/initializers/config.rb` and set of default settings files:
43
47
 
44
48
  config/settings.yml
49
+ config/settings.local.yml
45
50
  config/settings/development.yml
46
51
  config/settings/production.yml
47
52
  config/settings/test.yml
@@ -186,8 +191,9 @@ Settings.add_source!("#{Rails.root}/config/settings/local.yml")
186
191
  Settings.reload!
187
192
  ```
188
193
 
189
- > Note: this is an example usage, it is easier to just use the default local files `settings.local.yml,
190
- settings/#{Rails.env}.local.yml and environments/#{Rails.env}.local.yml` for your developer specific settings.
194
+ > Note: this is an example usage, it is easier to just use the default local
195
+ > files `settings.local.yml`, `settings/#{Rails.env}.local.yml` and
196
+ > `environments/#{Rails.env}.local.yml` for your developer specific settings.
191
197
 
192
198
  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.
193
199
 
@@ -200,7 +206,9 @@ You may pass a hash to `prepend_source!` as well.
200
206
 
201
207
  ## Embedded Ruby (ERB)
202
208
 
203
- Embedded Ruby is allowed in the configuration files. Consider the two following config files.
209
+ 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`.
210
+
211
+ Consider the two following config files.
204
212
 
205
213
  * ```#{Rails.root}/config/settings.yml```
206
214
 
@@ -261,6 +269,7 @@ After installing `Config` in Rails, you will find automatically generated file t
261
269
  ### General
262
270
 
263
271
  * `const_name` - name of the object holing you settings. Default: `'Settings'`
272
+ * `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`
264
273
 
265
274
  ### Merge customization
266
275
 
@@ -415,6 +424,21 @@ ENV['Settings.section.server'] = 'google.com'
415
424
 
416
425
  It won't work with arrays, though.
417
426
 
427
+ It is considered an error to use environment variables to simutaneously assign a "flat" value and a multi-level value to a key.
428
+
429
+ ```ruby
430
+ # Raises an error when settings are loaded
431
+ ENV['BACKEND_DATABASE'] = 'development'
432
+ ENV['BACKEND_DATABASE_USER'] = 'postgres'
433
+ ```
434
+
435
+ Instead, specify keys of equal depth in the environment variable names:
436
+
437
+ ```ruby
438
+ ENV['BACKEND_DATABASE_NAME'] = 'development'
439
+ ENV['BACKEND_DATABASE_USER'] = 'postgres'
440
+ ```
441
+
418
442
  ### Working with Heroku
419
443
 
420
444
  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.
@@ -460,12 +484,83 @@ Settings.section.server # => 'google.com'
460
484
  Settings.section.ssl_enabled # => false
461
485
  ```
462
486
 
487
+ ### Working with AWS Secrets Manager
488
+
489
+ It is possible to parse variables stored in an AWS Secrets Manager Secret as if they were environment variables by using `Config::Sources::EnvSource`.
490
+
491
+ For example, the plaintext secret might look like this:
492
+
493
+ ```json
494
+ {
495
+ "Settings.foo": "hello",
496
+ "Settings.bar": "world",
497
+ }
498
+ ```
499
+
500
+ 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.
501
+
502
+ ```ruby
503
+ # fetch secrets from AWS
504
+ client = Aws::SecretsManager::Client.new
505
+ response = client.get_secret_value(secret_id: "#{ENV['ENVIRONMENT']}/my_application")
506
+ secrets = JSON.parse(response.secret_string)
507
+
508
+ # load secrets into config
509
+ secret_source = Config::Sources::EnvSource.new(secrets)
510
+ Settings.add_source!(secret_source)
511
+ Settings.reload!
512
+ ```
513
+
514
+ In this case, the following settings will be available:
515
+
516
+ ```ruby
517
+ Settings.foo # => "hello"
518
+ Settings.bar # => "world"
519
+ ```
520
+
521
+ 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.
522
+
523
+ ```ruby
524
+ secret_source = Config::Sources::EnvSource.new(secrets,
525
+ prefix: 'MyConfig',
526
+ separator: '__',
527
+ converter: nil,
528
+ parse_values: false)
529
+ ```
530
+
463
531
  ## Contributing
464
532
 
465
533
  You are very warmly welcome to help. Please follow our [contribution guidelines](CONTRIBUTING.md)
466
534
 
467
535
  Any and all contributions offered in any form, past present or future are understood to be in complete agreement and acceptance with [MIT](LICENSE) license.
468
536
 
537
+ ### Running specs
538
+
539
+ Setup
540
+
541
+ ```sh
542
+ bundle install
543
+ bundle exec appraisal install
544
+ ```
545
+
546
+ List defined appraisals:
547
+
548
+ ```sh
549
+ bundle exec appraisal list
550
+ ```
551
+
552
+ Run specs for specific appraisal:
553
+
554
+ ```sh
555
+ bundle exec appraisal rails-6.1 rspec
556
+ ```
557
+
558
+ Run specs for all appraisals:
559
+
560
+ ```sh
561
+ bundle exec appraisal rspec
562
+ ```
563
+
469
564
  ## Authors
470
565
 
471
566
  * [Piotr Kuczynski](http://github.com/pkuczynski)
@@ -497,4 +592,4 @@ Support this project by becoming a [sponsor](https://opencollective.com/rubyconf
497
592
 
498
593
  ## License
499
594
 
500
- Copyright (C) Piotr Kuczynski. Released under the [MIT License](LICENSE).
595
+ Copyright (C) Piotr Kuczynski. Released under the [MIT License](LICENSE.md).
data/config.gemspec CHANGED
@@ -8,23 +8,23 @@ Gem::Specification.new do |s|
8
8
  s.date = Time.now.strftime '%F'
9
9
  s.authors = ['Piotr Kuczynski', 'Fred Wu', 'Jacques Crocker']
10
10
  s.email = %w[piotr.kuczynski@gmail.com ifredwu@gmail.com railsjedi@gmail.com]
11
- s.summary = 'Effortless multi-environment settings in Rails, Sinatra, Pandrino and others'
11
+ s.summary = 'Effortless multi-environment settings in Rails, Sinatra, Padrino and others'
12
12
  s.description = 'Easiest way to manage multi-environment settings in any ruby project or framework: ' +
13
- 'Rails, Sinatra, Pandrino and others'
13
+ 'Rails, Sinatra, Padrino and others'
14
14
  s.homepage = 'https://github.com/rubyconfig/config'
15
15
  s.license = 'MIT'
16
16
  s.extra_rdoc_files = %w[README.md CHANGELOG.md CONTRIBUTING.md LICENSE.md]
17
17
  s.rdoc_options = ['--charset=UTF-8']
18
- s.post_install_message = "\n\e[33mThanks for installing Config\e[0m 🙏
18
+ s.post_install_message = "\n\e[33mThanks for installing Config\e[0m
19
19
  Please consider donating to our open collective to help us maintain this project.
20
20
  \n
21
- 👉 Donate: \e[34mhttps://opencollective.com/rubyconfig/donate\e[0m\n"
21
+ Donate: \e[34mhttps://opencollective.com/rubyconfig/donate\e[0m\n"
22
22
 
23
23
  s.files = `git ls-files`.split($/)
24
24
  s.files.select! { |file| /(^lib\/|^\w+.md$|\.gemspec$)/ =~ file }
25
25
 
26
26
  s.require_paths = ['lib']
27
- s.required_ruby_version = '>= 2.4.0'
27
+ s.required_ruby_version = '>= 2.6.0'
28
28
 
29
29
  s.add_dependency 'deep_merge', '~> 1.2', '>= 1.2.1'
30
30
  s.add_dependency 'dry-validation', '~> 1.0', '>= 1.0.0'
@@ -32,22 +32,23 @@ Please consider donating to our open collective to help us maintain this project
32
32
  s.add_development_dependency 'rake', '~> 12.0', '>= 12.0.0'
33
33
 
34
34
  # Testing
35
- s.add_development_dependency 'appraisal', '~> 2.2', '>= 2.2.0'
36
- s.add_development_dependency 'rspec', '~> 3.7', '>= 3.7.0'
35
+ s.add_development_dependency 'appraisal', '~> 2.3', '>= 2.3.0'
36
+ s.add_development_dependency 'rspec', '~> 3.9', '>= 3.9.0'
37
37
 
38
38
  # Default RSpec run will test against latest Rails app
39
39
  unless ENV['APPRAISAL_INITIALIZED'] || ENV['GITHUB_ACTIONS']
40
- File.read(Dir['gemfiles/rails*.gemfile'].sort.last).scan(/gem "(.*?)", "(.*?)"/m) do |name, version|
40
+ gems_to_install = /gem "(.*?)", "(.*?)"(?!, platform: (?!\[:ruby\]))/
41
+ File.read(Dir['gemfiles/rails*.gemfile'].sort.last).scan(gems_to_install) do |name, version|
41
42
  s.add_development_dependency name, version
42
43
  end
43
44
  end
44
45
 
45
46
  if ENV['GITHUB_ACTIONS']
46
47
  # Code coverage is needed only in CI
47
- s.add_development_dependency 'simplecov', '~> 0.17.1' if RUBY_ENGINE == 'ruby'
48
+ s.add_development_dependency 'simplecov', '~> 0.18.5' if RUBY_ENGINE == 'ruby'
48
49
  else
49
50
  # Static code analysis to be used locally
50
- s.add_development_dependency 'mdl', '~> 0.8', '>= 0.8.0'
51
- s.add_development_dependency 'rubocop', '~> 0.78.0'
51
+ s.add_development_dependency 'mdl', '~> 0.9', '>= 0.9.0'
52
+ s.add_development_dependency 'rubocop', '~> 0.85.0'
52
53
  end
53
54
  end
@@ -16,7 +16,7 @@ module Config
16
16
 
17
17
  def add_source!(source)
18
18
  # handle yaml file paths
19
- source = (Sources::YAMLSource.new(source)) if source.is_a?(String)
19
+ source = (Sources::YAMLSource.new(source)) if source.is_a?(String) || source.is_a?(Pathname)
20
20
  source = (Sources::HashSource.new(source)) if source.is_a?(Hash)
21
21
 
22
22
  @config_sources ||= []
@@ -24,49 +24,13 @@ module Config
24
24
  end
25
25
 
26
26
  def prepend_source!(source)
27
- source = (Sources::YAMLSource.new(source)) if source.is_a?(String)
27
+ source = (Sources::YAMLSource.new(source)) if source.is_a?(String) || source.is_a?(Pathname)
28
28
  source = (Sources::HashSource.new(source)) if source.is_a?(Hash)
29
29
 
30
30
  @config_sources ||= []
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
@@ -118,6 +81,8 @@ module Config
118
81
  result
119
82
  end
120
83
 
84
+ alias :to_h :to_hash
85
+
121
86
  def each(*args, &block)
122
87
  marshal_dump.each(*args, &block)
123
88
  end
@@ -127,6 +92,10 @@ module Config
127
92
  to_hash.to_json(*args)
128
93
  end
129
94
 
95
+ def as_json(options = nil)
96
+ to_hash.as_json(options)
97
+ end
98
+
130
99
  def merge!(hash)
131
100
  current = to_hash
132
101
  DeepMerge.deep_merge!(
@@ -143,7 +112,7 @@ module Config
143
112
  end
144
113
 
145
114
  # Some keywords that don't play nicely with OpenStruct
146
- SETTINGS_RESERVED_NAMES = %w[select collect test count zip min max].freeze
115
+ SETTINGS_RESERVED_NAMES = %w[select collect test count zip min max exit! table].freeze
147
116
 
148
117
  # An alternative mechanism for property access.
149
118
  # This let's you do foo['bar'] along with foo.bar.
@@ -163,11 +132,11 @@ module Config
163
132
  end
164
133
 
165
134
  def key?(key)
166
- table.key?(key)
135
+ @table.key?(key)
167
136
  end
168
137
 
169
138
  def has_key?(key)
170
- table.has_key?(key)
139
+ @table.has_key?(key)
171
140
  end
172
141
 
173
142
  def method_missing(method_name, *args)
@@ -212,17 +181,5 @@ module Config
212
181
  end
213
182
  s
214
183
  end
215
-
216
- # Try to convert string to a correct type
217
- def __value(v)
218
- case v
219
- when 'false'
220
- false
221
- when 'true'
222
- true
223
- else
224
- Integer(v) rescue Float(v) rescue v
225
- end
226
- end
227
184
  end
228
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,21 +5,27 @@ 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
- result = YAML.load(ERB.new(IO.read(@path)).result) if @path and File.exist?(@path)
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
 
19
- rescue Psych::SyntaxError => e
20
- raise "YAML syntax error occurred while parsing #{@path}. " \
21
- "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
22
- "Error: #{e.message}"
25
+ rescue Psych::SyntaxError => e
26
+ raise "YAML syntax error occurred while parsing #{@path}. " \
27
+ "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
28
+ "Error: #{e.message}"
23
29
  end
24
30
  end
25
31
  end
@@ -1,3 +1,3 @@
1
1
  module Config
2
- VERSION = '2.2.1'.freeze
2
+ VERSION = '4.2.1'.freeze
3
3
  end
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
@@ -33,24 +35,25 @@ module Config
33
35
 
34
36
  # Create a populated Options instance from a settings file. If a second file is given, then the sections of that
35
37
  # file will overwrite existing sections of the first file.
36
- def self.load_files(*files)
38
+ def self.load_files(*sources)
37
39
  config = Options.new
38
40
 
39
41
  # add settings sources
40
- [files].flatten.compact.uniq.each do |file|
41
- config.add_source!(file.to_s)
42
+ [sources].flatten.compact.each do |source|
43
+ config.add_source!(source)
42
44
  end
43
45
 
46
+ config.add_source!(Sources::EnvSource.new(ENV)) if Config.use_env
47
+
44
48
  config.load!
45
- config.load_env! if use_env
46
49
  config
47
50
  end
48
51
 
49
52
  # Loads and sets the settings constant!
50
- def self.load_and_set_settings(*files)
53
+ def self.load_and_set_settings(*sources)
51
54
  name = Config.const_name
52
55
  Object.send(:remove_const, name) if Object.const_defined?(name)
53
- Object.const_set(name, Config.load_files(files))
56
+ Object.const_set(name, Config.load_files(sources))
54
57
  end
55
58
 
56
59
  def self.setting_files(config_root, env)
@@ -76,7 +79,7 @@ module Config
76
79
  end
77
80
 
78
81
  # Rails integration
79
- require('config/integrations/rails/railtie') if defined?(::Rails)
82
+ require('config/integrations/rails/railtie') if defined?(::Rails::Railtie)
80
83
 
81
84
  # Sinatra integration
82
85
  require('config/integrations/sinatra') if defined?(::Sinatra)
@@ -18,7 +18,7 @@ module Config
18
18
  end
19
19
 
20
20
  def modify_gitignore
21
- create_file '.gitignore' unless File.exists? '.gitignore'
21
+ create_file '.gitignore' unless File.exist? '.gitignore'
22
22
 
23
23
  append_to_file '.gitignore' do
24
24
  "\n" +
@@ -52,4 +52,7 @@ Config.setup do |config|
52
52
  # required(:email).filled(format?: EMAIL_REGEX)
53
53
  # end
54
54
 
55
+ # Evaluate ERB in YAML config files at load time.
56
+ #
57
+ # config.evaluate_erb_in_yaml = true
55
58
  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: 2.2.1
4
+ version: 4.2.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: 2020-01-08 00:00:00.000000000 Z
13
+ date: 2023-06-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: deep_merge
@@ -36,174 +36,174 @@ 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.0
42
39
  - - "~>"
43
40
  - !ruby/object:Gem::Version
44
41
  version: '1.0'
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 1.0.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.0
52
49
  - - "~>"
53
50
  - !ruby/object:Gem::Version
54
51
  version: '1.0'
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.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.0
62
59
  - - "~>"
63
60
  - !ruby/object:Gem::Version
64
61
  version: '12.0'
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 12.0.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.0
72
69
  - - "~>"
73
70
  - !ruby/object:Gem::Version
74
71
  version: '12.0'
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 12.0.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.2.0
82
79
  - - "~>"
83
80
  - !ruby/object:Gem::Version
84
- version: '2.2'
81
+ version: '2.3'
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 2.3.0
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.2.0
92
89
  - - "~>"
93
90
  - !ruby/object:Gem::Version
94
- version: '2.2'
91
+ version: '2.3'
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 2.3.0
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.7.0
102
99
  - - "~>"
103
100
  - !ruby/object:Gem::Version
104
- version: '3.7'
101
+ version: '3.9'
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 3.9.0
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.7.0
112
109
  - - "~>"
113
110
  - !ruby/object:Gem::Version
114
- version: '3.7'
111
+ version: '3.9'
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 3.9.0
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: bootsnap
117
117
  requirement: !ruby/object:Gem::Requirement
118
118
  requirements:
119
- - - "~>"
119
+ - - ">="
120
120
  - !ruby/object:Gem::Version
121
- version: '1.4'
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: '1.4'
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.0.2.1
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.0.2.1
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: '3.7'
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: '3.7'
156
+ version: '5.0'
157
157
  - !ruby/object:Gem::Dependency
158
- name: sqlite3
158
+ name: psych
159
159
  requirement: !ruby/object:Gem::Requirement
160
160
  requirements:
161
- - - "~>"
161
+ - - ">="
162
162
  - !ruby/object:Gem::Version
163
- version: 1.4.0
163
+ version: '4'
164
164
  type: :development
165
165
  prerelease: false
166
166
  version_requirements: !ruby/object:Gem::Requirement
167
167
  requirements:
168
- - - "~>"
168
+ - - ">="
169
169
  - !ruby/object:Gem::Version
170
- version: 1.4.0
170
+ version: '4'
171
171
  - !ruby/object:Gem::Dependency
172
172
  name: mdl
173
173
  requirement: !ruby/object:Gem::Requirement
174
174
  requirements:
175
- - - ">="
176
- - !ruby/object:Gem::Version
177
- version: 0.8.0
178
175
  - - "~>"
179
176
  - !ruby/object:Gem::Version
180
- version: '0.8'
177
+ version: '0.9'
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: 0.9.0
181
181
  type: :development
182
182
  prerelease: false
183
183
  version_requirements: !ruby/object:Gem::Requirement
184
184
  requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: 0.8.0
188
185
  - - "~>"
189
186
  - !ruby/object:Gem::Version
190
- version: '0.8'
187
+ version: '0.9'
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ version: 0.9.0
191
191
  - !ruby/object:Gem::Dependency
192
192
  name: rubocop
193
193
  requirement: !ruby/object:Gem::Requirement
194
194
  requirements:
195
195
  - - "~>"
196
196
  - !ruby/object:Gem::Version
197
- version: 0.78.0
197
+ version: 0.85.0
198
198
  type: :development
199
199
  prerelease: false
200
200
  version_requirements: !ruby/object:Gem::Requirement
201
201
  requirements:
202
202
  - - "~>"
203
203
  - !ruby/object:Gem::Version
204
- version: 0.78.0
204
+ version: 0.85.0
205
205
  description: 'Easiest way to manage multi-environment settings in any ruby project
206
- or framework: Rails, Sinatra, Pandrino and others'
206
+ or framework: Rails, Sinatra, Padrino and others'
207
207
  email:
208
208
  - piotr.kuczynski@gmail.com
209
209
  - ifredwu@gmail.com
@@ -229,6 +229,7 @@ files:
229
229
  - lib/config/integrations/sinatra.rb
230
230
  - lib/config/options.rb
231
231
  - lib/config/rack/reloader.rb
232
+ - lib/config/sources/env_source.rb
232
233
  - lib/config/sources/hash_source.rb
233
234
  - lib/config/sources/yaml_source.rb
234
235
  - lib/config/tasks/heroku.rake
@@ -247,9 +248,8 @@ homepage: https://github.com/rubyconfig/config
247
248
  licenses:
248
249
  - MIT
249
250
  metadata: {}
250
- post_install_message: "\n\e[33mThanks for installing Config\e[0m \U0001F64F\nPlease
251
- consider donating to our open collective to help us maintain this project.\n\n\n\U0001F449
252
- \ Donate: \e[34mhttps://opencollective.com/rubyconfig/donate\e[0m\n"
251
+ post_install_message: "\n\e[33mThanks for installing Config\e[0m\nPlease consider
252
+ donating to our open collective to help us maintain this project.\n\n\nDonate: \e[34mhttps://opencollective.com/rubyconfig/donate\e[0m\n"
253
253
  rdoc_options:
254
254
  - "--charset=UTF-8"
255
255
  require_paths:
@@ -258,15 +258,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
258
258
  requirements:
259
259
  - - ">="
260
260
  - !ruby/object:Gem::Version
261
- version: 2.4.0
261
+ version: 2.6.0
262
262
  required_rubygems_version: !ruby/object:Gem::Requirement
263
263
  requirements:
264
264
  - - ">="
265
265
  - !ruby/object:Gem::Version
266
266
  version: '0'
267
267
  requirements: []
268
- rubygems_version: 3.0.4
269
- signing_key:
268
+ rubygems_version: 3.4.13
269
+ signing_key:
270
270
  specification_version: 4
271
- summary: Effortless multi-environment settings in Rails, Sinatra, Pandrino and others
271
+ summary: Effortless multi-environment settings in Rails, Sinatra, Padrino and others
272
272
  test_files: []