More intelligent AutomaticEnv behavior and updated documentation.

This commit is contained in:
spf13 2014-12-22 22:47:25 -05:00
parent 54fed16054
commit d8f2aa78d4
2 changed files with 20 additions and 11 deletions

View File

@ -125,11 +125,11 @@ One important thing to recognize when working with ENV variables is that
the value will be read each time it is accessed. It does not fix the the value will be read each time it is accessed. It does not fix the
value when the BindEnv is called. value when the BindEnv is called.
AutomaticEnv is intended to be a convenience helper. It will look for all AutomaticEnv is a powerful helper especially when combined with
keys that have been set (via defaults, config file, flag, or remote key SetEnvPrefix. When called, Viper will check for an environment variable
value) and call BindEnv on that key. It does any time a viper.Get request is made. It will apply the following rules.
not simply import all ENV variables. Because of this behavior its It will check for a environment variable with a name matching the key
usually best to call it last. uppercased and prefixed with the EnvPrefix if set.
#### Env example #### Env example

View File

@ -76,6 +76,8 @@ type viper struct {
configType string configType string
envPrefix string envPrefix string
automaticEnvApplied bool
config map[string]interface{} config map[string]interface{}
override map[string]interface{} override map[string]interface{}
defaults map[string]interface{} defaults map[string]interface{}
@ -136,10 +138,10 @@ func (v *viper) SetEnvPrefix(in string) {
func (v *viper) mergeWithEnvPrefix(in string) string { func (v *viper) mergeWithEnvPrefix(in string) string {
if v.envPrefix != "" { if v.envPrefix != "" {
return v.envPrefix + "_" + in return strings.ToUpper(v.envPrefix + "_" + in)
} }
return in return strings.ToUpper(in)
} }
// Return the config file used // Return the config file used
@ -370,7 +372,7 @@ func (v *viper) BindEnv(input ...string) (err error) {
key = strings.ToLower(input[0]) key = strings.ToLower(input[0])
if len(input) == 1 { if len(input) == 1 {
envkey = strings.ToUpper(v.mergeWithEnvPrefix(key)) envkey = v.mergeWithEnvPrefix(key)
} else { } else {
envkey = input[1] envkey = input[1]
} }
@ -406,6 +408,15 @@ func (v *viper) find(key string) interface{} {
return val return val
} }
if v.automaticEnvApplied {
// even if it hasn't been registered, if automaticEnv is used,
// check any Get request
if val = os.Getenv(v.mergeWithEnvPrefix(key)); val != "" {
jww.TRACE.Println(key, "found in environment with val:", val)
return val
}
}
envkey, exists := v.env[key] envkey, exists := v.env[key]
if exists { if exists {
jww.TRACE.Println(key, "registered as env var", envkey) jww.TRACE.Println(key, "registered as env var", envkey)
@ -449,9 +460,7 @@ func (v *viper) IsSet(key string) bool {
// keys set in config, default & flags // keys set in config, default & flags
func AutomaticEnv() { v.AutomaticEnv() } func AutomaticEnv() { v.AutomaticEnv() }
func (v *viper) AutomaticEnv() { func (v *viper) AutomaticEnv() {
for _, x := range v.AllKeys() { v.automaticEnvApplied = true
v.BindEnv(x)
}
} }
// Aliases provide another accessor for the same key. // Aliases provide another accessor for the same key.