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
|
||||
|
||||
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:
|
||||
|
||||
* AutomaticEnv()
|
||||
* BindEnv(string...) : error
|
||||
* SetEnvPrefix(string)
|
||||
* SetEnvReplacer(string...) *strings.Replacer
|
||||
|
||||
_When working with ENV variables it’s important to recognize that Viper
|
||||
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
|
||||
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
|
||||
|
||||
SetEnvPrefix("spf") // will be uppercased automatically
|
||||
|
|
25
viper.go
25
viper.go
|
@ -77,6 +77,7 @@ type viper struct {
|
|||
envPrefix string
|
||||
|
||||
automaticEnvApplied bool
|
||||
envKeyReplacer *strings.Replacer
|
||||
|
||||
config map[string]interface{}
|
||||
override map[string]interface{}
|
||||
|
@ -153,6 +154,20 @@ func (v *viper) mergeWithEnvPrefix(in string) string {
|
|||
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
|
||||
func ConfigFileUsed() string { return v.ConfigFileUsed() }
|
||||
func (v *viper) ConfigFileUsed() string { return v.configFile }
|
||||
|
@ -427,7 +442,7 @@ func (v *viper) find(key string) interface{} {
|
|||
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 != "" {
|
||||
if val = v.getEnv(v.mergeWithEnvPrefix(key)); val != "" {
|
||||
jww.TRACE.Println(key, "found in environment with val:", val)
|
||||
return val
|
||||
}
|
||||
|
@ -436,7 +451,7 @@ func (v *viper) find(key string) interface{} {
|
|||
envkey, exists := v.env[key]
|
||||
if exists {
|
||||
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)
|
||||
return val
|
||||
} else {
|
||||
|
@ -479,6 +494,12 @@ func (v *viper) AutomaticEnv() {
|
|||
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.
|
||||
// This enables one to change a name without breaking the application
|
||||
func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) }
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -221,6 +222,7 @@ func TestEnv(t *testing.T) {
|
|||
AutomaticEnv()
|
||||
|
||||
assert.Equal(t, "crunk", Get("name"))
|
||||
|
||||
}
|
||||
|
||||
func TestEnvPrefix(t *testing.T) {
|
||||
|
@ -260,6 +262,18 @@ func TestAutoEnvWithPrefix(t *testing.T) {
|
|||
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) {
|
||||
initConfigs()
|
||||
|
||||
|
|
Loading…
Reference in a new issue