mirror of
https://github.com/spf13/viper
synced 2024-12-22 19:47:01 +00:00
Support rewriting env keys
This commit is contained in:
parent
ededa04e0b
commit
03fb74b5d7
3 changed files with 44 additions and 3 deletions
|
@ -98,12 +98,13 @@ Aliases permit a single value to be referenced by multiple keys
|
||||||
### 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 three methods that exist to aid
|
applications out of the box. There are four methods that exist to aid
|
||||||
with working with ENV:
|
with working with ENV:
|
||||||
|
|
||||||
* AutomaticEnv()
|
* AutomaticEnv()
|
||||||
* BindEnv(string...) : error
|
* BindEnv(string...) : error
|
||||||
* SetEnvPrefix(string)
|
* SetEnvPrefix(string)
|
||||||
|
* SetEnvReplacer(string...) *strings.Replacer
|
||||||
|
|
||||||
_When working with ENV variables it’s important to recognize that Viper
|
_When working with ENV variables it’s important to recognize that Viper
|
||||||
treats ENV variables as case sensitive._
|
treats ENV variables as case sensitive._
|
||||||
|
@ -131,6 +132,11 @@ 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
|
It will check for a environment variable with a name matching the key
|
||||||
uppercased and prefixed with the EnvPrefix if set.
|
uppercased and prefixed with the EnvPrefix if set.
|
||||||
|
|
||||||
|
SetEnvReplacer allows you to use a `strings.Replacer` object to rewrite Env 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 example
|
||||||
|
of using it can be found in `viper_test.go`
|
||||||
|
|
||||||
#### Env example
|
#### Env example
|
||||||
|
|
||||||
SetEnvPrefix("spf") // will be uppercased automatically
|
SetEnvPrefix("spf") // will be uppercased automatically
|
||||||
|
|
25
viper.go
25
viper.go
|
@ -77,6 +77,7 @@ type viper struct {
|
||||||
envPrefix string
|
envPrefix string
|
||||||
|
|
||||||
automaticEnvApplied bool
|
automaticEnvApplied bool
|
||||||
|
envKeyReplacer *strings.Replacer
|
||||||
|
|
||||||
config map[string]interface{}
|
config map[string]interface{}
|
||||||
override map[string]interface{}
|
override map[string]interface{}
|
||||||
|
@ -153,6 +154,20 @@ func (v *viper) mergeWithEnvPrefix(in string) string {
|
||||||
return strings.ToUpper(in)
|
return strings.ToUpper(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: should getEnv logic be moved into find(). Can generalize the use of
|
||||||
|
// rewriting keys many things, Ex: Get('someKey') -> some_key
|
||||||
|
// (cammel case to snake case for JSON keys perhaps)
|
||||||
|
|
||||||
|
// getEnv s a wrapper around os.Getenv which replaces characters in the original
|
||||||
|
// key. This allows env vars which have different keys then the config object
|
||||||
|
// keys
|
||||||
|
func (v *viper) getEnv(key string) string {
|
||||||
|
if v.envKeyReplacer != nil {
|
||||||
|
key = v.envKeyReplacer.Replace(key)
|
||||||
|
}
|
||||||
|
return os.Getenv(key)
|
||||||
|
}
|
||||||
|
|
||||||
// Return the config file used
|
// Return the config file used
|
||||||
func ConfigFileUsed() string { return v.ConfigFileUsed() }
|
func ConfigFileUsed() string { return v.ConfigFileUsed() }
|
||||||
func (v *viper) ConfigFileUsed() string { return v.configFile }
|
func (v *viper) ConfigFileUsed() string { return v.configFile }
|
||||||
|
@ -427,7 +442,7 @@ func (v *viper) find(key string) interface{} {
|
||||||
if v.automaticEnvApplied {
|
if v.automaticEnvApplied {
|
||||||
// even if it hasn't been registered, if automaticEnv is used,
|
// even if it hasn't been registered, if automaticEnv is used,
|
||||||
// check any Get request
|
// check any Get request
|
||||||
if val = os.Getenv(v.mergeWithEnvPrefix(key)); val != "" {
|
if val = v.getEnv(v.mergeWithEnvPrefix(key)); val != "" {
|
||||||
jww.TRACE.Println(key, "found in environment with val:", val)
|
jww.TRACE.Println(key, "found in environment with val:", val)
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
@ -436,7 +451,7 @@ func (v *viper) find(key string) interface{} {
|
||||||
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)
|
||||||
if val = os.Getenv(envkey); val != "" {
|
if val = v.getEnv(envkey); val != "" {
|
||||||
jww.TRACE.Println(envkey, "found in environment with val:", val)
|
jww.TRACE.Println(envkey, "found in environment with val:", val)
|
||||||
return val
|
return val
|
||||||
} else {
|
} else {
|
||||||
|
@ -479,6 +494,12 @@ func (v *viper) AutomaticEnv() {
|
||||||
v.automaticEnvApplied = true
|
v.automaticEnvApplied = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetEnvKeyReplacer sets the strings.Replacer on the viper object
|
||||||
|
func SetEnvKeyReplacer(r *strings.Replacer) { v.SetEnvKeyReplacer(r) }
|
||||||
|
func (v *viper) SetEnvKeyReplacer(r *strings.Replacer) {
|
||||||
|
v.envKeyReplacer = r
|
||||||
|
}
|
||||||
|
|
||||||
// Aliases provide another accessor for the same key.
|
// Aliases provide another accessor for the same key.
|
||||||
// This enables one to change a name without breaking the application
|
// This enables one to change a name without breaking the application
|
||||||
func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) }
|
func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) }
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -221,6 +222,7 @@ func TestEnv(t *testing.T) {
|
||||||
AutomaticEnv()
|
AutomaticEnv()
|
||||||
|
|
||||||
assert.Equal(t, "crunk", Get("name"))
|
assert.Equal(t, "crunk", Get("name"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnvPrefix(t *testing.T) {
|
func TestEnvPrefix(t *testing.T) {
|
||||||
|
@ -260,6 +262,18 @@ func TestAutoEnvWithPrefix(t *testing.T) {
|
||||||
assert.Equal(t, "13", Get("bar"))
|
assert.Equal(t, "13", Get("bar"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetEnvReplacer(t *testing.T) {
|
||||||
|
Reset()
|
||||||
|
|
||||||
|
AutomaticEnv()
|
||||||
|
os.Setenv("REFRESH_INTERVAL", "30s")
|
||||||
|
|
||||||
|
replacer := strings.NewReplacer("-", "_")
|
||||||
|
SetEnvKeyReplacer(replacer)
|
||||||
|
|
||||||
|
assert.Equal(t, "30s", Get("refresh-interval"))
|
||||||
|
}
|
||||||
|
|
||||||
func TestAllKeys(t *testing.T) {
|
func TestAllKeys(t *testing.T) {
|
||||||
initConfigs()
|
initConfigs()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue