From e0a1ccb64a637673195804513902cba6b1d4e97c Mon Sep 17 00:00:00 2001 From: Niall Sheridan Date: Mon, 31 Oct 2016 16:36:17 +0000 Subject: Update dependencies --- vendor/github.com/spf13/viper/README.md | 10 +-- vendor/github.com/spf13/viper/util.go | 51 +++++++++-- vendor/github.com/spf13/viper/viper.go | 147 ++++++++++++++++++-------------- 3 files changed, 136 insertions(+), 72 deletions(-) (limited to 'vendor/github.com/spf13/viper') diff --git a/vendor/github.com/spf13/viper/README.md b/vendor/github.com/spf13/viper/README.md index f4e72f8..25181df 100644 --- a/vendor/github.com/spf13/viper/README.md +++ b/vendor/github.com/spf13/viper/README.md @@ -12,7 +12,7 @@ Many Go projects are built using Viper including: * [BloomApi](https://www.bloomapi.com/) * [doctl](https://github.com/digitalocean/doctl) - [![Build Status](https://travis-ci.org/spf13/viper.svg)](https://travis-ci.org/spf13/viper) [![Join the chat at https://gitter.im/spf13/viper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Build Status](https://travis-ci.org/spf13/viper.svg)](https://travis-ci.org/spf13/viper) [![Join the chat at https://gitter.im/spf13/viper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![GoDoc](https://godoc.org/github.com/spf13/viper?status.svg)](https://godoc.org/github.com/spf13/viper) ## What is Viper? @@ -277,10 +277,10 @@ Viper provides two Go interfaces to bind other flag systems if you don't use `Pf ```go type myFlag struct {} -func (f myFlag) IsChanged() { return false } -func (f myFlag) Name() { return "my-flag-name" } -func (f myFlag) ValueString() { return "my-flag-value" } -func (f myFlag) ValueType() { return "string" } +func (f myFlag) HasChanged() bool { return false } +func (f myFlag) Name() string { return "my-flag-name" } +func (f myFlag) ValueString() string { return "my-flag-value" } +func (f myFlag) ValueType() string { return "string" } ``` Once your flag implements this interface, you can simply tell Viper to bind it: diff --git a/vendor/github.com/spf13/viper/util.go b/vendor/github.com/spf13/viper/util.go index b0903fb..3ebada9 100644 --- a/vendor/github.com/spf13/viper/util.go +++ b/vendor/github.com/spf13/viper/util.go @@ -39,17 +39,58 @@ func (pe ConfigParseError) Error() string { return fmt.Sprintf("While parsing config: %s", pe.err.Error()) } +// toCaseInsensitiveValue checks if the value is a map; +// if so, create a copy and lower-case the keys recursively. +func toCaseInsensitiveValue(value interface{}) interface{} { + switch v := value.(type) { + case map[interface{}]interface{}: + value = copyAndInsensitiviseMap(cast.ToStringMap(v)) + case map[string]interface{}: + value = copyAndInsensitiviseMap(v) + } + + return value +} + +// copyAndInsensitiviseMap behaves like insensitiviseMap, but creates a copy of +// any map it makes case insensitive. +func copyAndInsensitiviseMap(m map[string]interface{}) map[string]interface{} { + nm := make(map[string]interface{}) + + for key, val := range m { + lkey := strings.ToLower(key) + switch v := val.(type) { + case map[interface{}]interface{}: + nm[lkey] = copyAndInsensitiviseMap(cast.ToStringMap(v)) + case map[string]interface{}: + nm[lkey] = copyAndInsensitiviseMap(v) + default: + nm[lkey] = v + } + } + + return nm +} + func insensitiviseMap(m map[string]interface{}) { for key, val := range m { + switch val.(type) { + case map[interface{}]interface{}: + // nested map: cast and recursively insensitivise + val = cast.ToStringMap(val) + insensitiviseMap(val.(map[string]interface{})) + case map[string]interface{}: + // nested map: recursively insensitivise + insensitiviseMap(val.(map[string]interface{})) + } + lower := strings.ToLower(key) if key != lower { + // remove old key (not lower-cased) delete(m, key) - m[lower] = val - if m2, ok := val.(map[string]interface{}); ok { - // nested map: recursively insensitivise - insensitiviseMap(m2) - } } + // update map + m[lower] = val } } diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go index 8f27849..4ed2d40 100644 --- a/vendor/github.com/spf13/viper/viper.go +++ b/vendor/github.com/spf13/viper/viper.go @@ -241,7 +241,13 @@ func (v *Viper) WatchConfig() { defer watcher.Close() // we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way - configFile := filepath.Clean(v.getConfigFile()) + filename, err := v.getConfigFile() + if err != nil { + log.Println("error:", err) + return + } + + configFile := filepath.Clean(filename) configDir, _ := filepath.Split(configFile) done := make(chan bool) @@ -401,22 +407,20 @@ func (v *Viper) providerPathExists(p *defaultRemoteProvider) bool { // searchMap recursively searches for a value for path in source map. // Returns nil if not found. +// Note: This assumes that the path entries and map keys are lower cased. func (v *Viper) searchMap(source map[string]interface{}, path []string) interface{} { if len(path) == 0 { return source } - var ok bool - var next interface{} - for k, v := range source { - if strings.ToLower(k) == strings.ToLower(path[0]) { - ok = true - next = v - break + next, ok := source[path[0]] + if ok { + // Fast path + if len(path) == 1 { + return next } - } - if ok { + // Nested case switch next.(type) { case map[interface{}]interface{}: return v.searchMap(cast.ToStringMap(next), path[1:]) @@ -425,9 +429,6 @@ func (v *Viper) searchMap(source map[string]interface{}, path []string) interfac // if the type of `next` is the same as the type being asserted return v.searchMap(next.(map[string]interface{}), path[1:]) default: - if len(path) == 1 { - return next - } // got a value but nested key expected, return "nil" for not found return nil } @@ -444,6 +445,8 @@ func (v *Viper) searchMap(source map[string]interface{}, path []string) interfac // // This should be useful only at config level (other maps may not contain dots // in their keys). +// +// Note: This assumes that the path entries and map keys are lower cased. func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path []string) interface{} { if len(path) == 0 { return source @@ -453,17 +456,14 @@ func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path [] for i := len(path); i > 0; i-- { prefixKey := strings.ToLower(strings.Join(path[0:i], v.keyDelim)) - var ok bool - var next interface{} - for k, v := range source { - if strings.ToLower(k) == prefixKey { - ok = true - next = v - break + next, ok := source[prefixKey] + if ok { + // Fast path + if i == len(path) { + return next } - } - if ok { + // Nested case var val interface{} switch next.(type) { case map[interface{}]interface{}: @@ -473,9 +473,6 @@ func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path [] // if the type of `next` is the same as the type being asserted val = v.searchMapWithPathPrefixes(next.(map[string]interface{}), path[i:]) default: - if len(path) == i { - val = next - } // got a value but nested key expected, do nothing and look for next prefix } if val != nil { @@ -579,6 +576,7 @@ func GetViper() *Viper { } // Get can retrieve any value given the key to use. +// Get is case-insensitive for a key. // Get has the behavior of returning the value associated with the first // place from where it is set. Viper will check in the following order: // override, flag, env, config file, key/value store, default @@ -594,6 +592,7 @@ func (v *Viper) Get(key string) interface{} { valType := val if v.typeByDefValue { + // TODO(bep) this branch isn't covered by a single test. path := strings.Split(lcaseKey, v.keyDelim) defVal := v.searchMap(v.defaults, path) if defVal != nil { @@ -621,6 +620,7 @@ func (v *Viper) Get(key string) interface{} { } // Sub returns new Viper instance representing a sub tree of this instance. +// Sub is case-insensitive for a key. func Sub(key string) *Viper { return v.Sub(key) } func (v *Viper) Sub(key string) *Viper { subv := New() @@ -841,32 +841,37 @@ func (v *Viper) BindEnv(input ...string) error { // Viper will check in the following order: // flag, env, config file, key/value store, default. // Viper will check to see if an alias exists first. -func (v *Viper) find(key string) interface{} { - var val interface{} - var exists bool +// Note: this assumes a lower-cased key given. +func (v *Viper) find(lcaseKey string) interface{} { + + var ( + val interface{} + exists bool + path = strings.Split(lcaseKey, v.keyDelim) + nested = len(path) > 1 + ) // compute the path through the nested maps to the nested value - path := strings.Split(key, v.keyDelim) - if shadow := v.isPathShadowedInDeepMap(path, castMapStringToMapInterface(v.aliases)); shadow != "" { + if nested && v.isPathShadowedInDeepMap(path, castMapStringToMapInterface(v.aliases)) != "" { return nil } // if the requested key is an alias, then return the proper key - key = v.realKey(key) - // re-compute the path - path = strings.Split(key, v.keyDelim) + lcaseKey = v.realKey(lcaseKey) + path = strings.Split(lcaseKey, v.keyDelim) + nested = len(path) > 1 // Set() override first val = v.searchMap(v.override, path) if val != nil { return val } - if shadow := v.isPathShadowedInDeepMap(path, v.override); shadow != "" { + if nested && v.isPathShadowedInDeepMap(path, v.override) != "" { return nil } // PFlag override next - flag, exists := v.pflags[key] + flag, exists := v.pflags[lcaseKey] if exists && flag.HasChanged() { switch flag.ValueType() { case "int", "int8", "int16", "int32", "int64": @@ -880,7 +885,7 @@ func (v *Viper) find(key string) interface{} { return flag.ValueString() } } - if shadow := v.isPathShadowedInFlatMap(path, v.pflags); shadow != "" { + if nested && v.isPathShadowedInFlatMap(path, v.pflags) != "" { return nil } @@ -888,20 +893,20 @@ 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 = v.getEnv(v.mergeWithEnvPrefix(key)); val != "" { + if val = v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); val != "" { return val } - if shadow := v.isPathShadowedInAutoEnv(path); shadow != "" { + if nested && v.isPathShadowedInAutoEnv(path) != "" { return nil } } - envkey, exists := v.env[key] + envkey, exists := v.env[lcaseKey] if exists { if val = v.getEnv(envkey); val != "" { return val } } - if shadow := v.isPathShadowedInFlatMap(path, v.env); shadow != "" { + if nested && v.isPathShadowedInFlatMap(path, v.env) != "" { return nil } @@ -910,7 +915,7 @@ func (v *Viper) find(key string) interface{} { if val != nil { return val } - if shadow := v.isPathShadowedInDeepMap(path, v.config); shadow != "" { + if nested && v.isPathShadowedInDeepMap(path, v.config) != "" { return nil } @@ -919,7 +924,7 @@ func (v *Viper) find(key string) interface{} { if val != nil { return val } - if shadow := v.isPathShadowedInDeepMap(path, v.kvstore); shadow != "" { + if nested && v.isPathShadowedInDeepMap(path, v.kvstore) != "" { return nil } @@ -928,13 +933,13 @@ func (v *Viper) find(key string) interface{} { if val != nil { return val } - if shadow := v.isPathShadowedInDeepMap(path, v.defaults); shadow != "" { + if nested && v.isPathShadowedInDeepMap(path, v.defaults) != "" { return nil } // last chance: if no other value is returned and a flag does exist for the value, // get the flag's value even if the flag's value has not changed - if flag, exists := v.pflags[key]; exists { + if flag, exists := v.pflags[lcaseKey]; exists { switch flag.ValueType() { case "int", "int8", "int16", "int32", "int64": return cast.ToInt(flag.ValueString()) @@ -953,6 +958,7 @@ func (v *Viper) find(key string) interface{} { } // IsSet checks to see if the key has been set in any of the data locations. +// IsSet is case-insensitive for a key. func IsSet(key string) bool { return v.IsSet(key) } func (v *Viper) IsSet(key string) bool { lcaseKey := strings.ToLower(key) @@ -1034,11 +1040,13 @@ func (v *Viper) InConfig(key string) bool { } // SetDefault sets the default value for this key. +// SetDefault is case-insensitive for a key. // Default only used when no value is provided by the user via flag, config or ENV. func SetDefault(key string, value interface{}) { v.SetDefault(key, value) } func (v *Viper) SetDefault(key string, value interface{}) { // If alias passed in, then set the proper default key = v.realKey(strings.ToLower(key)) + value = toCaseInsensitiveValue(value) path := strings.Split(key, v.keyDelim) lastKey := strings.ToLower(path[len(path)-1]) @@ -1049,12 +1057,14 @@ func (v *Viper) SetDefault(key string, value interface{}) { } // Set sets the value for the key in the override regiser. +// Set is case-insensitive for a key. // Will be used instead of values obtained via // flags, config file, ENV, default, or key/value store. func Set(key string, value interface{}) { v.Set(key, value) } func (v *Viper) Set(key string, value interface{}) { // If alias passed in, then set the proper override key = v.realKey(strings.ToLower(key)) + value = toCaseInsensitiveValue(value) path := strings.Split(key, v.keyDelim) lastKey := strings.ToLower(path[len(path)-1]) @@ -1069,11 +1079,16 @@ func (v *Viper) Set(key string, value interface{}) { func ReadInConfig() error { return v.ReadInConfig() } func (v *Viper) ReadInConfig() error { jww.INFO.Println("Attempting to read in config file") + filename, err := v.getConfigFile() + if err != nil { + return err + } + if !stringInSlice(v.getConfigType(), SupportedExts) { return UnsupportedConfigError(v.getConfigType()) } - file, err := afero.ReadFile(v.fs, v.getConfigFile()) + file, err := afero.ReadFile(v.fs, filename) if err != nil { return err } @@ -1091,7 +1106,12 @@ func (v *Viper) MergeInConfig() error { return UnsupportedConfigError(v.getConfigType()) } - file, err := afero.ReadFile(v.fs, v.getConfigFile()) + filename, err := v.getConfigFile() + if err != nil { + return err + } + + file, err := afero.ReadFile(v.fs, filename) if err != nil { return err } @@ -1149,6 +1169,14 @@ func castMapStringToMapInterface(src map[string]string) map[string]interface{} { return tgt } +func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} { + tgt := map[string]interface{}{} + for k, v := range src { + tgt[k] = v + } + return tgt +} + // mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's // insistence on parsing nested structures as `map[interface{}]interface{}` // instead of using a `string` as the key for nest structures beyond one level @@ -1294,8 +1322,8 @@ func (v *Viper) AllKeys() []string { // add all paths, by order of descending priority to ensure correct shadowing m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "") m = v.flattenAndMergeMap(m, v.override, "") - m = v.mergeFlatMap(m, v.pflags) - m = v.mergeFlatMap(m, v.env) + m = v.mergeFlatMap(m, castMapFlagToMapInterface(v.pflags)) + m = v.mergeFlatMap(m, castMapStringToMapInterface(v.env)) m = v.flattenAndMergeMap(m, v.config, "") m = v.flattenAndMergeMap(m, v.kvstore, "") m = v.flattenAndMergeMap(m, v.defaults, "") @@ -1347,16 +1375,7 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac // mergeFlatMap merges the given maps, excluding values of the second map // shadowed by values from the first map. -func (v *Viper) mergeFlatMap(shadow map[string]bool, mi interface{}) map[string]bool { - // unify input map - var m map[string]interface{} - switch mi.(type) { - case map[string]string, map[string]FlagValue: - m = cast.ToStringMap(mi) - default: - return shadow - } - +func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool { // scan keys outer: for k, _ := range m { @@ -1427,7 +1446,11 @@ func (v *Viper) getConfigType() string { return v.configType } - cf := v.getConfigFile() + cf, err := v.getConfigFile() + if err != nil { + return "" + } + ext := filepath.Ext(cf) if len(ext) > 1 { @@ -1437,15 +1460,15 @@ func (v *Viper) getConfigType() string { return "" } -func (v *Viper) getConfigFile() string { +func (v *Viper) getConfigFile() (string, error) { // if explicitly set, then use it if v.configFile != "" { - return v.configFile + return v.configFile, nil } cf, err := v.findConfigFile() if err != nil { - return "" + return "", err } v.configFile = cf -- cgit v1.2.3