Creation of Sub now copies parent properties and sets envPrefix

This commit is contained in:
Roy Razon 2018-01-16 17:03:31 +02:00
parent aafc9e6bc7
commit daea2aaa5a
2 changed files with 33 additions and 2 deletions

View file

@ -204,6 +204,13 @@ func New() *Viper {
return v return v
} }
func newFrom(from *Viper) *Viper {
v := *new(Viper)
v = *from // shallow clone
return &v
}
// Intended for testing, will reset all to default settings. // Intended for testing, will reset all to default settings.
// In the public interface for the viper package so applications // In the public interface for the viper package so applications
// can use it in their testing as well. // can use it in their testing as well.
@ -647,11 +654,19 @@ func (v *Viper) Get(key string) interface{} {
return val return val
} }
func (v *Viper) prefixOfSub(key string) string {
if v.envPrefix == "" {
return key
} else {
return v.envPrefix + "." + key
}
}
// Sub returns new Viper instance representing a sub tree of this instance. // Sub returns new Viper instance representing a sub tree of this instance.
// Sub is case-insensitive for a key. // Sub is case-insensitive for a key.
func Sub(key string) *Viper { return v.Sub(key) } func Sub(key string) *Viper { return v.Sub(key) }
func (v *Viper) Sub(key string) *Viper { func (v *Viper) Sub(key string) *Viper {
subv := New() subv := newFrom(v)
data := v.Get(key) data := v.Get(key)
if data == nil { if data == nil {
return nil return nil
@ -659,6 +674,7 @@ func (v *Viper) Sub(key string) *Viper {
if reflect.TypeOf(data).Kind() == reflect.Map { if reflect.TypeOf(data).Kind() == reflect.Map {
subv.config = cast.ToStringMap(data) subv.config = cast.ToStringMap(data)
subv.envPrefix = v.prefixOfSub(key)
return subv return subv
} }
return nil return nil
@ -882,7 +898,6 @@ func (v *Viper) BindEnv(input ...string) error {
// Viper will check to see if an alias exists first. // Viper will check to see if an alias exists first.
// Note: this assumes a lower-cased key given. // Note: this assumes a lower-cased key given.
func (v *Viper) find(lcaseKey string) interface{} { func (v *Viper) find(lcaseKey string) interface{} {
var ( var (
val interface{} val interface{}
exists bool exists bool

View file

@ -848,6 +848,22 @@ func TestSub(t *testing.T) {
assert.Equal(t, (*Viper)(nil), subv) assert.Equal(t, (*Viper)(nil), subv)
} }
func TestSubEnv(t *testing.T) {
v := New()
v.SetConfigType("yaml")
v.ReadConfig(bytes.NewBuffer(yamlExample))
v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
assert.Equal(t, "leather", v.GetString("clothing.jacket"))
subv := v.Sub("clothing")
assert.Equal(t, "leather", subv.GetString("jacket"))
os.Setenv("CLOTHING_JACKET", "13")
assert.Equal(t, "13", v.GetString("clothing.jacket"))
assert.Equal(t, "13", subv.GetString("jacket"))
}
var hclWriteExpected = []byte(`"foos" = { var hclWriteExpected = []byte(`"foos" = {
"foo" = { "foo" = {
"key" = 1 "key" = 1