Skip to content

Commit 2cc5b86

Browse files
authored
Raise explicit error on env var conflicts (#293)
1 parent aa627cf commit 2cc5b86

4 files changed

Lines changed: 47 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22

33
## Unreleased
44

5+
### Bug fixes
6+
57
...
68

9+
### Changes
10+
11+
* Raise explicit error on environment variable conflicts ([#293](https://github.com/railsconfig/config/issues/293))
12+
713
## 2.2.2
814

915
### Bug fixes

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,9 @@ Settings.add_source!("#{Rails.root}/config/settings/local.yml")
190190
Settings.reload!
191191
```
192192

193-
> Note: this is an example usage, it is easier to just use the default local files `settings.local.yml,
194-
settings/#{Rails.env}.local.yml and environments/#{Rails.env}.local.yml` for your developer specific 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.
195196
196197
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.
197198

@@ -419,6 +420,21 @@ ENV['Settings.section.server'] = 'google.com'
419420

420421
It won't work with arrays, though.
421422

423+
It is considered an error to use environment variables to simutaneously assign a "flat" value and a multi-level value to a key.
424+
425+
```ruby
426+
# Raises an error when settings are loaded
427+
ENV['BACKEND_DATABASE'] = 'development'
428+
ENV['BACKEND_DATABASE_USER'] = 'postgres'
429+
```
430+
431+
Instead, specify keys of equal depth in the environment variable names:
432+
433+
```ruby
434+
ENV['BACKEND_DATABASE_NAME'] = 'development'
435+
ENV['BACKEND_DATABASE_USER'] = 'postgres'
436+
```
437+
422438
### Working with Heroku
423439

424440
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.

lib/config/options.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ def reload_env!
5959
h[key] ||= {}
6060
}
6161

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+
6267
leaf[keys.last] = Config.env_parse_values ? __value(value) : value
6368
end
6469

spec/config_env_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,5 +213,23 @@
213213
expect(config.new_var).to eq('value')
214214
end
215215

216+
context 'and env variable names conflict with new namespaces' do
217+
it 'should throw a descriptive error message' do
218+
ENV['Settings.backend_database'] = 'development'
219+
ENV['Settings.backend_database.user'] = 'postgres'
220+
221+
expected_message = 'Environment variable Settings.backend_database.user '\
222+
'conflicts with variable Settings.backend_database'
223+
expect { config }.to raise_error(RuntimeError, expected_message)
224+
end
225+
end
226+
227+
context 'and env variable names conflict with existing namespaces' do
228+
it 'should allow overriding the namespace' do
229+
ENV['Settings.databases'] = 'new databases'
230+
231+
expect(config.databases).to eq('new databases')
232+
end
233+
end
216234
end
217235
end

0 commit comments

Comments
 (0)