-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added a setting to make viper case sensitive #592
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,3 +27,4 @@ _testmain.go | |
|
||
# exclude dependencies in the `/vendor` folder | ||
vendor | ||
.idea/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -203,6 +203,7 @@ type Viper struct { | |
properties *properties.Properties | ||
|
||
onConfigChange func(fsnotify.Event) | ||
caseSensitive bool | ||
} | ||
|
||
// New returns an initialized Viper instance. | ||
|
@@ -219,6 +220,7 @@ func New() *Viper { | |
v.env = make(map[string]string) | ||
v.aliases = make(map[string]string) | ||
v.typeByDefValue = false | ||
v.caseSensitive = false | ||
|
||
return v | ||
} | ||
|
@@ -277,6 +279,13 @@ func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) { | |
v.onConfigChange = run | ||
} | ||
|
||
func SetCaseSensitive(flag bool) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add some comments here that will appear in godoc. |
||
v.SetCaseSensitive(flag) | ||
} | ||
func (v *Viper) SetCaseSensitive(flag bool) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add some comments here that will appear in godoc. |
||
v.caseSensitive = flag | ||
} | ||
|
||
func WatchConfig() { v.WatchConfig() } | ||
|
||
func (v *Viper) WatchConfig() { | ||
|
@@ -536,7 +545,7 @@ func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path [] | |
|
||
// search for path prefixes, starting from the longest one | ||
for i := len(path); i > 0; i-- { | ||
prefixKey := strings.ToLower(strings.Join(path[0:i], v.keyDelim)) | ||
prefixKey := v.properCase(strings.Join(path[0:i], v.keyDelim)) | ||
|
||
next, ok := source[prefixKey] | ||
if ok { | ||
|
@@ -665,7 +674,7 @@ func GetViper() *Viper { | |
// Get returns an interface. For a specific value use one of the Get____ methods. | ||
func Get(key string) interface{} { return v.Get(key) } | ||
func (v *Viper) Get(key string) interface{} { | ||
lcaseKey := strings.ToLower(key) | ||
lcaseKey := v.properCase(key) | ||
val := v.find(lcaseKey) | ||
if val == nil { | ||
return nil | ||
|
@@ -918,7 +927,7 @@ func (v *Viper) BindFlagValue(key string, flag FlagValue) error { | |
if flag == nil { | ||
return fmt.Errorf("flag for %q is nil", key) | ||
} | ||
v.pflags[strings.ToLower(key)] = flag | ||
v.pflags[v.properCase(key)] = flag | ||
return nil | ||
} | ||
|
||
|
@@ -933,7 +942,7 @@ func (v *Viper) BindEnv(input ...string) error { | |
return fmt.Errorf("BindEnv missing key to bind to") | ||
} | ||
|
||
key = strings.ToLower(input[0]) | ||
key = v.properCase(input[0]) | ||
|
||
if len(input) == 1 { | ||
envkey = v.mergeWithEnvPrefix(key) | ||
|
@@ -1083,7 +1092,7 @@ func readAsCSV(val string) ([]string, error) { | |
// 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) | ||
lcaseKey := v.properCase(key) | ||
val := v.find(lcaseKey) | ||
return val != nil | ||
} | ||
|
@@ -1107,11 +1116,11 @@ func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) { | |
// This enables one to change a name without breaking the application | ||
func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) } | ||
func (v *Viper) RegisterAlias(alias string, key string) { | ||
v.registerAlias(alias, strings.ToLower(key)) | ||
v.registerAlias(alias, v.properCase(key)) | ||
} | ||
|
||
func (v *Viper) registerAlias(alias string, key string) { | ||
alias = strings.ToLower(alias) | ||
alias = v.properCase(alias) | ||
if alias != key && alias != v.realKey(key) { | ||
_, exists := v.aliases[alias] | ||
|
||
|
@@ -1167,11 +1176,14 @@ func (v *Viper) InConfig(key string) bool { | |
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) | ||
key = v.realKey(v.properCase(key)) | ||
|
||
if !v.caseSensitive { | ||
value = toCaseInsensitiveValue(value) | ||
} | ||
|
||
path := strings.Split(key, v.keyDelim) | ||
lastKey := strings.ToLower(path[len(path)-1]) | ||
lastKey := v.properCase(path[len(path)-1]) | ||
deepestMap := deepSearch(v.defaults, path[0:len(path)-1]) | ||
|
||
// set innermost value | ||
|
@@ -1185,11 +1197,14 @@ func (v *Viper) SetDefault(key string, value interface{}) { | |
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) | ||
key = v.realKey(v.properCase(key)) | ||
|
||
if !v.caseSensitive { | ||
value = toCaseInsensitiveValue(value) | ||
} | ||
|
||
path := strings.Split(key, v.keyDelim) | ||
lastKey := strings.ToLower(path[len(path)-1]) | ||
lastKey := v.properCase(path[len(path)-1]) | ||
deepestMap := deepSearch(v.override, path[0:len(path)-1]) | ||
|
||
// set innermost value | ||
|
@@ -1342,7 +1357,7 @@ func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error { | |
buf := new(bytes.Buffer) | ||
buf.ReadFrom(in) | ||
|
||
switch strings.ToLower(v.getConfigType()) { | ||
switch v.properCase(v.getConfigType()) { | ||
case "yaml", "yml": | ||
if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil { | ||
return ConfigParseError{err} | ||
|
@@ -1382,13 +1397,17 @@ func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error { | |
value, _ := v.properties.Get(key) | ||
// recursively build nested maps | ||
path := strings.Split(key, ".") | ||
lastKey := strings.ToLower(path[len(path)-1]) | ||
lastKey := v.properCase(path[len(path)-1]) | ||
deepestMap := deepSearch(c, path[0:len(path)-1]) | ||
// set innermost value | ||
deepestMap[lastKey] = value | ||
} | ||
} | ||
|
||
if v.caseSensitive { | ||
return nil | ||
} | ||
|
||
insensitiviseMap(c) | ||
return nil | ||
} | ||
|
@@ -1460,9 +1479,9 @@ func (v *Viper) marshalWriter(f afero.File, configType string) error { | |
} | ||
|
||
func keyExists(k string, m map[string]interface{}) string { | ||
lk := strings.ToLower(k) | ||
lk := v.properCase(k) | ||
for mk := range m { | ||
lmk := strings.ToLower(mk) | ||
lmk := v.properCase(mk) | ||
if lmk == lk { | ||
return mk | ||
} | ||
|
@@ -1572,6 +1591,10 @@ func (v *Viper) WatchRemoteConfigOnChannel() error { | |
} | ||
|
||
func (v *Viper) insensitiviseMaps() { | ||
if v.caseSensitive { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks unnecessary, at least I think you will never reach this check, since you do it before calling this method: https://github.com/spf13/viper/pull/592/files#diff-38f1012180f40493dcf780c312a40ec3R1407 I think it would be better to do these checks outside of the |
||
return | ||
} | ||
|
||
insensitiviseMap(v.config) | ||
insensitiviseMap(v.defaults) | ||
insensitiviseMap(v.override) | ||
|
@@ -1693,7 +1716,7 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac | |
m2 = cast.ToStringMap(val) | ||
default: | ||
// immediate value | ||
shadow[strings.ToLower(fullKey)] = true | ||
shadow[v.properCase(fullKey)] = true | ||
continue | ||
} | ||
// recursively merge to shadow map | ||
|
@@ -1719,7 +1742,7 @@ outer: | |
} | ||
} | ||
// add key | ||
shadow[strings.ToLower(k)] = true | ||
shadow[v.properCase(k)] = true | ||
} | ||
return shadow | ||
} | ||
|
@@ -1737,7 +1760,7 @@ func (v *Viper) AllSettings() map[string]interface{} { | |
continue | ||
} | ||
path := strings.Split(k, v.keyDelim) | ||
lastKey := strings.ToLower(path[len(path)-1]) | ||
lastKey := v.properCase(path[len(path)-1]) | ||
deepestMap := deepSearch(m, path[0:len(path)-1]) | ||
// set innermost value | ||
deepestMap[lastKey] = value | ||
|
@@ -1827,6 +1850,14 @@ func (v *Viper) findConfigFile() (string, error) { | |
return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)} | ||
} | ||
|
||
func (v *Viper) properCase(s string) string { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe call this |
||
if !v.caseSensitive { | ||
s = strings.ToLower(s) | ||
} | ||
|
||
return s | ||
} | ||
|
||
// Debug prints all configuration registries for debugging | ||
// purposes. | ||
func Debug() { v.Debug() } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be false by default, no need to set it here IMHO.