This commit is contained in:
laxmanvallandas 2018-04-08 04:44:33 +00:00 committed by GitHub
commit 97befb3142
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -29,6 +29,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"strconv"
"strings" "strings"
"time" "time"
@ -512,6 +513,56 @@ func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path []
return nil return nil
} }
func (v *Viper) searchMapWithArrayPrefix(source map[string]interface{}, path []string) interface{} {
if len(path) == 0 {
return source
}
next, ok := source[path[0]]
if ok {
// Immediate Key Value
if len(path) == 1 {
return next
}
// Value from Nested key
switch next.(type) {
case map[interface{}]interface{}:
return v.searchMapWithArrayPrefix(cast.ToStringMap(next), path[1:])
case map[string]interface{}:
// Type assertion is safe here since it is only reached
// if the type of `next` is the same as the type being asserted
return v.searchMapWithArrayPrefix(next.(map[string]interface{}), path[1:])
case []interface{}:
v1 := cast.ToSlice(next)
for k2, v2 := range v1 {
if reflect.TypeOf(v2).Kind() == reflect.Map {
if _, err := strconv.ParseInt(path[1], 10, 64); err == nil {
if strconv.Itoa(k2) == path[1] {
return v.searchMapWithArrayPrefix(cast.ToStringMap(v2), path[1:])
}
} else {
return v.searchMapWithArrayPrefix(cast.ToStringMap(v2), path[1:])
}
} else {
if _, err := strconv.ParseInt(path[1], 10, 64); err == nil {
if strconv.Itoa(k2) == path[1] {
return v2
}
}
}
}
default:
return nil
}
} else {
if _, err := strconv.ParseInt(path[0], 10, 64); err == nil {
return v.searchMapWithArrayPrefix(source, path[1:])
}
}
return nil
}
// isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere // isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere
// on its path in the map. // on its path in the map.
// e.g., if "foo.bar" has a value in the given map, it “shadows” // e.g., if "foo.bar" has a value in the given map, it “shadows”
@ -882,7 +933,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
@ -956,6 +1006,11 @@ func (v *Viper) find(lcaseKey string) interface{} {
if val != nil { if val != nil {
return val return val
} }
val = v.searchMapWithArrayPrefix(v.config, path)
if val != nil {
return val
}
if nested && v.isPathShadowedInDeepMap(path, v.config) != "" { if nested && v.isPathShadowedInDeepMap(path, v.config) != "" {
return nil return nil
} }