mirror of
https://github.com/sinatra/sinatra
synced 2023-03-27 23:18:01 -04:00
Load current environment settings regardless of support for other environments in settings file.
This commit is contained in:
parent
5074c1e342
commit
dac516088e
3 changed files with 66 additions and 30 deletions
|
@ -8,7 +8,7 @@ module Sinatra
|
||||||
#
|
#
|
||||||
# <tt>Sinatra::ConfigFile</tt> is an extension that allows you to load the
|
# <tt>Sinatra::ConfigFile</tt> is an extension that allows you to load the
|
||||||
# application's configuration from YAML files. It automatically detects if
|
# application's configuration from YAML files. It automatically detects if
|
||||||
# the files contains specific environment settings and it will use the
|
# the files contain specific environment settings and it will use those
|
||||||
# corresponding to the current one.
|
# corresponding to the current one.
|
||||||
#
|
#
|
||||||
# You can access those options through +settings+ within the application. If
|
# You can access those options through +settings+ within the application. If
|
||||||
|
@ -94,18 +94,11 @@ module Sinatra
|
||||||
# In either case, <tt>settings.foo</tt> will return the environment name, and
|
# In either case, <tt>settings.foo</tt> will return the environment name, and
|
||||||
# <tt>settings.bar</tt> will return <tt>"bar"</tt>.
|
# <tt>settings.bar</tt> will return <tt>"bar"</tt>.
|
||||||
#
|
#
|
||||||
# Be aware that if you have a different environment, besides development,
|
# If you wish to provide defaults that may be shared among all the
|
||||||
# test and production, you will also need to adjust the +environments+
|
# environments, this can be done by using a YAML alias, and then overwriting
|
||||||
# setting, otherwise the settings will not load. For instance, when
|
# values in environments where appropriate:
|
||||||
# you also have a staging environment:
|
|
||||||
#
|
#
|
||||||
# set :environments, %w{development test production staging}
|
# default: &common_settings
|
||||||
#
|
|
||||||
# If you wish to provide defaults that may be shared among all the environments,
|
|
||||||
# this can be done by using one of the existing environments as the default using
|
|
||||||
# the YAML alias, and then overwriting values in the other environments:
|
|
||||||
#
|
|
||||||
# development: &common_settings
|
|
||||||
# foo: 'foo'
|
# foo: 'foo'
|
||||||
# bar: 'bar'
|
# bar: 'bar'
|
||||||
#
|
#
|
||||||
|
@ -131,11 +124,9 @@ module Sinatra
|
||||||
raise UnsupportedConfigType unless ['.yml', '.erb'].include?(File.extname(file))
|
raise UnsupportedConfigType unless ['.yml', '.erb'].include?(File.extname(file))
|
||||||
logger.info "loading config file '#{file}'" if logging? && respond_to?(:logger)
|
logger.info "loading config file '#{file}'" if logging? && respond_to?(:logger)
|
||||||
document = ERB.new(IO.read(file)).result
|
document = ERB.new(IO.read(file)).result
|
||||||
yaml = config_for_env(YAML.load(document)) || {}
|
yaml = YAML.load(document)
|
||||||
yaml.each_pair do |key, value|
|
config = config_for_env(yaml)
|
||||||
for_env = config_for_env(value)
|
config.each_pair { |key, value| set(key, value) }
|
||||||
set key, for_env unless value and for_env.nil? and respond_to? key
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -149,22 +140,31 @@ module Sinatra
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Given a +hash+ with some application configuration it returns the
|
# Given a +hash+ containing application configuration it returns
|
||||||
# settings applicable to the current environment. Note that this can only
|
# settings applicable to the current environment. Note: It gives
|
||||||
# be done when all the keys of +hash+ are environment names included in the
|
# precedence to environment settings defined at the root-level.
|
||||||
# +environments+ setting (which is an Array of Strings). Also, the
|
|
||||||
# returned config is a indifferently accessible Hash, which means that you
|
|
||||||
# can get its values using Strings or Symbols as keys.
|
|
||||||
def config_for_env(hash)
|
def config_for_env(hash)
|
||||||
if hash.respond_to?(:keys) && hash.keys.all? { |k| environments.include?(k.to_s) }
|
return from_environment_key(hash) if environment_keys?(hash)
|
||||||
hash = hash[environment.to_s] || hash[environment.to_sym]
|
|
||||||
|
hash.each_with_object(IndifferentHash[]) do |(k, v), acc|
|
||||||
|
if environment_keys?(v)
|
||||||
|
acc.merge!(k => v[environment.to_s]) if v.key?(environment.to_s)
|
||||||
|
else
|
||||||
|
acc.merge!(k => v)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if hash.respond_to?(:to_hash)
|
# Given a +hash+ returns the settings corresponding to the current
|
||||||
IndifferentHash[hash.to_hash]
|
# environment.
|
||||||
else
|
def from_environment_key(hash)
|
||||||
hash
|
hash[environment.to_s] || hash[environment.to_sym] || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns true if supplied with a hash that has any recognized
|
||||||
|
# +environments+ in its root keys.
|
||||||
|
def environment_keys?(hash)
|
||||||
|
hash.is_a?(Hash) && hash.any? { |k, _| environments.include?(k.to_s) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
16
sinatra-contrib/spec/config_file/with_env_defaults.yml
Normal file
16
sinatra-contrib/spec/config_file/with_env_defaults.yml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
default: &default
|
||||||
|
foo: default
|
||||||
|
bar: baz
|
||||||
|
|
||||||
|
development:
|
||||||
|
<<: *default
|
||||||
|
foo: development
|
||||||
|
|
||||||
|
production:
|
||||||
|
<<: *default
|
||||||
|
foo: production
|
||||||
|
|
||||||
|
test:
|
||||||
|
<<: *default
|
||||||
|
foo: test
|
|
@ -73,4 +73,24 @@ describe Sinatra::ConfigFile do
|
||||||
config_file 'key_value_override.yml'
|
config_file 'key_value_override.yml'
|
||||||
expect(settings.foo).to eq('foo')
|
expect(settings.foo).to eq('foo')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when file contains superfluous environments' do
|
||||||
|
before { config_file 'with_env_defaults.yml' }
|
||||||
|
|
||||||
|
it 'loads settings for the current environment anyway' do
|
||||||
|
expect { settings.foo }.not_to raise_error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when file contains defaults' do
|
||||||
|
before { config_file 'with_env_defaults.yml' }
|
||||||
|
|
||||||
|
it 'uses the overridden value' do
|
||||||
|
expect(settings.foo).to eq('test')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'uses the default value' do
|
||||||
|
expect(settings.bar).to eq('baz')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue