Add AllowEmptyEnv method to preserve backard compatibility

This commit is contained in:
Mark Sagi-Kazar 2018-11-06 20:20:07 +01:00
parent 5874d0cb08
commit 4f59047658
No known key found for this signature in database
GPG key ID: 34CC109EB5ED1C2A
3 changed files with 35 additions and 2 deletions

View file

@ -179,13 +179,14 @@ viper.GetBool("verbose") // true
### Working with Environment Variables ### Working with Environment Variables
Viper has full support for environment variables. This enables 12 factor Viper has full support for environment variables. This enables 12 factor
applications out of the box. There are four methods that exist to aid working applications out of the box. There are five methods that exist to aid working
with ENV: with ENV:
* `AutomaticEnv()` * `AutomaticEnv()`
* `BindEnv(string...) : error` * `BindEnv(string...) : error`
* `SetEnvPrefix(string)` * `SetEnvPrefix(string)`
* `SetEnvKeyReplacer(string...) *strings.Replacer` * `SetEnvKeyReplacer(string...) *strings.Replacer`
* `AllowEmptyEnvVar(bool)`
_When working with ENV variables, its important to recognize that Viper _When working with ENV variables, its important to recognize that Viper
treats ENV variables as case sensitive._ treats ENV variables as case sensitive._
@ -217,6 +218,10 @@ keys to an extent. This is useful if you want to use `-` or something in your
`Get()` calls, but want your environmental variables to use `_` delimiters. An `Get()` calls, but want your environmental variables to use `_` delimiters. An
example of using it can be found in `viper_test.go`. example of using it can be found in `viper_test.go`.
By default empty environment variables are considered unset and will fall back to
the next configuration source. To treat empty environment variables as set, use
the `AllowEmptyEnv` method.
#### Env example #### Env example
```go ```go

View file

@ -169,6 +169,7 @@ type Viper struct {
automaticEnvApplied bool automaticEnvApplied bool
envKeyReplacer *strings.Replacer envKeyReplacer *strings.Replacer
allowEmptyEnv bool
config map[string]interface{} config map[string]interface{}
override map[string]interface{} override map[string]interface{}
@ -330,6 +331,14 @@ func (v *Viper) mergeWithEnvPrefix(in string) string {
return strings.ToUpper(in) return strings.ToUpper(in)
} }
// AllowEmptyEnv tells Viper to consider set,
// but empty environment variables as valid values instead of falling back.
// For backward compatibility reasons this is false by default.
func AllowEmptyEnv(allowEmptyEnv bool) { v.AllowEmptyEnv(allowEmptyEnv) }
func (v *Viper) AllowEmptyEnv(allowEmptyEnv bool) {
v.allowEmptyEnv = allowEmptyEnv
}
// TODO: should getEnv logic be moved into find(). Can generalize the use of // TODO: should getEnv logic be moved into find(). Can generalize the use of
// rewriting keys many things, Ex: Get('someKey') -> some_key // rewriting keys many things, Ex: Get('someKey') -> some_key
// (camel case to snake case for JSON keys perhaps) // (camel case to snake case for JSON keys perhaps)
@ -341,7 +350,10 @@ func (v *Viper) getEnv(key string) (string, bool) {
if v.envKeyReplacer != nil { if v.envKeyReplacer != nil {
key = v.envKeyReplacer.Replace(key) key = v.envKeyReplacer.Replace(key)
} }
return os.LookupEnv(key)
val, ok := os.LookupEnv(key)
return val, ok && (v.allowEmptyEnv || val != "")
} }
// ConfigFileUsed returns the file used to populate the config registry. // ConfigFileUsed returns the file used to populate the config registry.

View file

@ -391,6 +391,22 @@ func TestEmptyEnv(t *testing.T) {
os.Setenv("TYPE", "") os.Setenv("TYPE", "")
assert.Equal(t, "donut", Get("type"))
assert.Equal(t, "Cake", Get("name"))
}
func TestEmptyEnv_Allowed(t *testing.T) {
initJSON()
AllowEmptyEnv(true)
BindEnv("type") // Empty environment variable
BindEnv("name") // Bound, but not set environment variable
os.Clearenv()
os.Setenv("TYPE", "")
assert.Equal(t, "", Get("type")) assert.Equal(t, "", Get("type"))
assert.Equal(t, "Cake", Get("name")) assert.Equal(t, "Cake", Get("name"))
} }