From d8f2aa78d42b618f51e668d0b7e05fe203f889de Mon Sep 17 00:00:00 2001 From: spf13 Date: Mon, 22 Dec 2014 22:47:25 -0500 Subject: [PATCH] More intelligent AutomaticEnv behavior and updated documentation. --- README.md | 10 +++++----- viper.go | 21 +++++++++++++++------ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8ef1ae9..a06bedb 100644 --- a/README.md +++ b/README.md @@ -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 value when the BindEnv is called. -AutomaticEnv is intended to be a convenience helper. It will look for all -keys that have been set (via defaults, config file, flag, or remote key -value) and call BindEnv on that key. It does -not simply import all ENV variables. Because of this behavior it’s -usually best to call it last. +AutomaticEnv is a powerful helper especially when combined with +SetEnvPrefix. When called, Viper will check for an environment variable +any time a viper.Get request is made. It will apply the following rules. +It will check for a environment variable with a name matching the key +uppercased and prefixed with the EnvPrefix if set. #### Env example diff --git a/viper.go b/viper.go index d075a95..89834b7 100644 --- a/viper.go +++ b/viper.go @@ -76,6 +76,8 @@ type viper struct { configType string envPrefix string + automaticEnvApplied bool + config map[string]interface{} override map[string]interface{} defaults map[string]interface{} @@ -136,10 +138,10 @@ func (v *viper) SetEnvPrefix(in string) { func (v *viper) mergeWithEnvPrefix(in string) string { if v.envPrefix != "" { - return v.envPrefix + "_" + in + return strings.ToUpper(v.envPrefix + "_" + in) } - return in + return strings.ToUpper(in) } // Return the config file used @@ -370,7 +372,7 @@ func (v *viper) BindEnv(input ...string) (err error) { key = strings.ToLower(input[0]) if len(input) == 1 { - envkey = strings.ToUpper(v.mergeWithEnvPrefix(key)) + envkey = v.mergeWithEnvPrefix(key) } else { envkey = input[1] } @@ -406,6 +408,15 @@ func (v *viper) find(key string) interface{} { 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] if exists { 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 func AutomaticEnv() { v.AutomaticEnv() } func (v *viper) AutomaticEnv() { - for _, x := range v.AllKeys() { - v.BindEnv(x) - } + v.automaticEnvApplied = true } // Aliases provide another accessor for the same key.