mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 18:42:26 -05:00 
			
		
		
		
	[chore] update viper version (#2539)
* update viper version * removes our last uses of the slice package * fix tests
This commit is contained in:
		
					parent
					
						
							
								c5eced5fd1
							
						
					
				
			
			
				commit
				
					
						906639ad7e
					
				
			
		
					 166 changed files with 11771 additions and 2782 deletions
				
			
		
							
								
								
									
										339
									
								
								vendor/github.com/spf13/viper/viper.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										339
									
								
								vendor/github.com/spf13/viper/viper.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -35,6 +35,7 @@ import ( | |||
| 
 | ||||
| 	"github.com/fsnotify/fsnotify" | ||||
| 	"github.com/mitchellh/mapstructure" | ||||
| 	slog "github.com/sagikazarmark/slog-shim" | ||||
| 	"github.com/spf13/afero" | ||||
| 	"github.com/spf13/cast" | ||||
| 	"github.com/spf13/pflag" | ||||
|  | @ -47,6 +48,7 @@ import ( | |||
| 	"github.com/spf13/viper/internal/encoding/json" | ||||
| 	"github.com/spf13/viper/internal/encoding/toml" | ||||
| 	"github.com/spf13/viper/internal/encoding/yaml" | ||||
| 	"github.com/spf13/viper/internal/features" | ||||
| ) | ||||
| 
 | ||||
| // ConfigMarshalError happens when failing to marshal the configuration. | ||||
|  | @ -76,7 +78,7 @@ type remoteConfigFactory interface { | |||
| 	WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool) | ||||
| } | ||||
| 
 | ||||
| // RemoteConfig is optional, see the remote package | ||||
| // RemoteConfig is optional, see the remote package. | ||||
| var RemoteConfig remoteConfigFactory | ||||
| 
 | ||||
| // UnsupportedConfigError denotes encountering an unsupported | ||||
|  | @ -101,7 +103,7 @@ func (str UnsupportedRemoteProviderError) Error() string { | |||
| // pull the configuration from the remote provider. | ||||
| type RemoteConfigError string | ||||
| 
 | ||||
| // Error returns the formatted remote provider error | ||||
| // Error returns the formatted remote provider error. | ||||
| func (rce RemoteConfigError) Error() string { | ||||
| 	return fmt.Sprintf("Remote Configurations Error: %s", string(rce)) | ||||
| } | ||||
|  | @ -125,7 +127,7 @@ func (faee ConfigFileAlreadyExistsError) Error() string { | |||
| } | ||||
| 
 | ||||
| // A DecoderConfigOption can be passed to viper.Unmarshal to configure | ||||
| // mapstructure.DecoderConfig options | ||||
| // mapstructure.DecoderConfig options. | ||||
| type DecoderConfigOption func(*mapstructure.DecoderConfig) | ||||
| 
 | ||||
| // DecodeHook returns a DecoderConfigOption which overrides the default | ||||
|  | @ -206,10 +208,10 @@ type Viper struct { | |||
| 	allowEmptyEnv       bool | ||||
| 
 | ||||
| 	parents        []string | ||||
| 	config         map[string]interface{} | ||||
| 	override       map[string]interface{} | ||||
| 	defaults       map[string]interface{} | ||||
| 	kvstore        map[string]interface{} | ||||
| 	config         map[string]any | ||||
| 	override       map[string]any | ||||
| 	defaults       map[string]any | ||||
| 	kvstore        map[string]any | ||||
| 	pflags         map[string]FlagValue | ||||
| 	env            map[string][]string | ||||
| 	aliases        map[string]string | ||||
|  | @ -217,7 +219,7 @@ type Viper struct { | |||
| 
 | ||||
| 	onConfigChange func(fsnotify.Event) | ||||
| 
 | ||||
| 	logger Logger | ||||
| 	logger *slog.Logger | ||||
| 
 | ||||
| 	// TODO: should probably be protected with a mutex | ||||
| 	encoderRegistry *encoding.EncoderRegistry | ||||
|  | @ -231,16 +233,16 @@ func New() *Viper { | |||
| 	v.configName = "config" | ||||
| 	v.configPermissions = os.FileMode(0o644) | ||||
| 	v.fs = afero.NewOsFs() | ||||
| 	v.config = make(map[string]interface{}) | ||||
| 	v.config = make(map[string]any) | ||||
| 	v.parents = []string{} | ||||
| 	v.override = make(map[string]interface{}) | ||||
| 	v.defaults = make(map[string]interface{}) | ||||
| 	v.kvstore = make(map[string]interface{}) | ||||
| 	v.override = make(map[string]any) | ||||
| 	v.defaults = make(map[string]any) | ||||
| 	v.kvstore = make(map[string]any) | ||||
| 	v.pflags = make(map[string]FlagValue) | ||||
| 	v.env = make(map[string][]string) | ||||
| 	v.aliases = make(map[string]string) | ||||
| 	v.typeByDefValue = false | ||||
| 	v.logger = jwwLogger{} | ||||
| 	v.logger = slog.New(&discardHandler{}) | ||||
| 
 | ||||
| 	v.resetEncoding() | ||||
| 
 | ||||
|  | @ -301,10 +303,10 @@ func NewWithOptions(opts ...Option) *Viper { | |||
| func Reset() { | ||||
| 	v = New() | ||||
| 	SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"} | ||||
| 	SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore"} | ||||
| 	SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore", "nats"} | ||||
| } | ||||
| 
 | ||||
| // TODO: make this lazy initialization instead | ||||
| // TODO: make this lazy initialization instead. | ||||
| func (v *Viper) resetEncoding() { | ||||
| 	encoderRegistry := encoding.NewEncoderRegistry() | ||||
| 	decoderRegistry := encoding.NewDecoderRegistry() | ||||
|  | @ -420,7 +422,7 @@ type RemoteProvider interface { | |||
| var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"} | ||||
| 
 | ||||
| // SupportedRemoteProviders are universally supported remote providers. | ||||
| var SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore"} | ||||
| var SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore", "nats"} | ||||
| 
 | ||||
| // OnConfigChange sets the event handler that is called when a config file changes. | ||||
| func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) } | ||||
|  | @ -438,7 +440,7 @@ func (v *Viper) WatchConfig() { | |||
| 	initWG := sync.WaitGroup{} | ||||
| 	initWG.Add(1) | ||||
| 	go func() { | ||||
| 		watcher, err := newWatcher() | ||||
| 		watcher, err := fsnotify.NewWatcher() | ||||
| 		if err != nil { | ||||
| 			v.logger.Error(fmt.Sprintf("failed to create watcher: %s", err)) | ||||
| 			os.Exit(1) | ||||
|  | @ -523,6 +525,12 @@ func (v *Viper) SetEnvPrefix(in string) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func GetEnvPrefix() string { return v.GetEnvPrefix() } | ||||
| 
 | ||||
| func (v *Viper) GetEnvPrefix() string { | ||||
| 	return v.envPrefix | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) mergeWithEnvPrefix(in string) string { | ||||
| 	if v.envPrefix != "" { | ||||
| 		return strings.ToUpper(v.envPrefix + "_" + in) | ||||
|  | @ -578,12 +586,12 @@ func (v *Viper) AddConfigPath(in string) { | |||
| 
 | ||||
| // AddRemoteProvider adds a remote configuration source. | ||||
| // Remote Providers are searched in the order they are added. | ||||
| // provider is a string value: "etcd", "etcd3", "consul" or "firestore" are currently supported. | ||||
| // endpoint is the url.  etcd requires http://ip:port  consul requires ip:port | ||||
| // provider is a string value: "etcd", "etcd3", "consul", "firestore" or "nats" are currently supported. | ||||
| // endpoint is the url.  etcd requires http://ip:port, consul requires ip:port, nats requires nats://ip:port | ||||
| // path is the path in the k/v store to retrieve configuration | ||||
| // To retrieve a config file called myapp.json from /configs/myapp.json | ||||
| // you should set path to /configs and set config name (SetConfigName()) to | ||||
| // "myapp" | ||||
| // "myapp". | ||||
| func AddRemoteProvider(provider, endpoint, path string) error { | ||||
| 	return v.AddRemoteProvider(provider, endpoint, path) | ||||
| } | ||||
|  | @ -609,14 +617,14 @@ func (v *Viper) AddRemoteProvider(provider, endpoint, path string) error { | |||
| 
 | ||||
| // AddSecureRemoteProvider adds a remote configuration source. | ||||
| // Secure Remote Providers are searched in the order they are added. | ||||
| // provider is a string value: "etcd", "etcd3", "consul" or "firestore" are currently supported. | ||||
| // provider is a string value: "etcd", "etcd3", "consul", "firestore" or "nats" are currently supported. | ||||
| // endpoint is the url.  etcd requires http://ip:port  consul requires ip:port | ||||
| // secretkeyring is the filepath to your openpgp secret keyring.  e.g. /etc/secrets/myring.gpg | ||||
| // path is the path in the k/v store to retrieve configuration | ||||
| // To retrieve a config file called myapp.json from /configs/myapp.json | ||||
| // you should set path to /configs and set config name (SetConfigName()) to | ||||
| // "myapp" | ||||
| // Secure Remote Providers are implemented with github.com/bketelsen/crypt | ||||
| // "myapp". | ||||
| // Secure Remote Providers are implemented with github.com/bketelsen/crypt. | ||||
| func AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error { | ||||
| 	return v.AddSecureRemoteProvider(provider, endpoint, path, secretkeyring) | ||||
| } | ||||
|  | @ -653,7 +661,7 @@ 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{} { | ||||
| func (v *Viper) searchMap(source map[string]any, path []string) any { | ||||
| 	if len(path) == 0 { | ||||
| 		return source | ||||
| 	} | ||||
|  | @ -666,13 +674,13 @@ func (v *Viper) searchMap(source map[string]interface{}, path []string) interfac | |||
| 		} | ||||
| 
 | ||||
| 		// Nested case | ||||
| 		switch next.(type) { | ||||
| 		case map[interface{}]interface{}: | ||||
| 		switch next := next.(type) { | ||||
| 		case map[any]any: | ||||
| 			return v.searchMap(cast.ToStringMap(next), path[1:]) | ||||
| 		case map[string]interface{}: | ||||
| 		case map[string]any: | ||||
| 			// 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.searchMap(next.(map[string]interface{}), path[1:]) | ||||
| 			return v.searchMap(next, path[1:]) | ||||
| 		default: | ||||
| 			// got a value but nested key expected, return "nil" for not found | ||||
| 			return nil | ||||
|  | @ -692,7 +700,7 @@ func (v *Viper) searchMap(source map[string]interface{}, path []string) interfac | |||
| // in their keys). | ||||
| // | ||||
| // Note: This assumes that the path entries and map keys are lower cased. | ||||
| func (v *Viper) searchIndexableWithPathPrefixes(source interface{}, path []string) interface{} { | ||||
| func (v *Viper) searchIndexableWithPathPrefixes(source any, path []string) any { | ||||
| 	if len(path) == 0 { | ||||
| 		return source | ||||
| 	} | ||||
|  | @ -701,11 +709,11 @@ func (v *Viper) searchIndexableWithPathPrefixes(source interface{}, path []strin | |||
| 	for i := len(path); i > 0; i-- { | ||||
| 		prefixKey := strings.ToLower(strings.Join(path[0:i], v.keyDelim)) | ||||
| 
 | ||||
| 		var val interface{} | ||||
| 		var val any | ||||
| 		switch sourceIndexable := source.(type) { | ||||
| 		case []interface{}: | ||||
| 		case []any: | ||||
| 			val = v.searchSliceWithPathPrefixes(sourceIndexable, prefixKey, i, path) | ||||
| 		case map[string]interface{}: | ||||
| 		case map[string]any: | ||||
| 			val = v.searchMapWithPathPrefixes(sourceIndexable, prefixKey, i, path) | ||||
| 		} | ||||
| 		if val != nil { | ||||
|  | @ -722,11 +730,11 @@ func (v *Viper) searchIndexableWithPathPrefixes(source interface{}, path []strin | |||
| // This function is part of the searchIndexableWithPathPrefixes recurring search and | ||||
| // should not be called directly from functions other than searchIndexableWithPathPrefixes. | ||||
| func (v *Viper) searchSliceWithPathPrefixes( | ||||
| 	sourceSlice []interface{}, | ||||
| 	sourceSlice []any, | ||||
| 	prefixKey string, | ||||
| 	pathIndex int, | ||||
| 	path []string, | ||||
| ) interface{} { | ||||
| ) any { | ||||
| 	// if the prefixKey is not a number or it is out of bounds of the slice | ||||
| 	index, err := strconv.Atoi(prefixKey) | ||||
| 	if err != nil || len(sourceSlice) <= index { | ||||
|  | @ -741,9 +749,9 @@ func (v *Viper) searchSliceWithPathPrefixes( | |||
| 	} | ||||
| 
 | ||||
| 	switch n := next.(type) { | ||||
| 	case map[interface{}]interface{}: | ||||
| 	case map[any]any: | ||||
| 		return v.searchIndexableWithPathPrefixes(cast.ToStringMap(n), path[pathIndex:]) | ||||
| 	case map[string]interface{}, []interface{}: | ||||
| 	case map[string]any, []any: | ||||
| 		return v.searchIndexableWithPathPrefixes(n, path[pathIndex:]) | ||||
| 	default: | ||||
| 		// got a value but nested key expected, do nothing and look for next prefix | ||||
|  | @ -758,11 +766,11 @@ func (v *Viper) searchSliceWithPathPrefixes( | |||
| // This function is part of the searchIndexableWithPathPrefixes recurring search and | ||||
| // should not be called directly from functions other than searchIndexableWithPathPrefixes. | ||||
| func (v *Viper) searchMapWithPathPrefixes( | ||||
| 	sourceMap map[string]interface{}, | ||||
| 	sourceMap map[string]any, | ||||
| 	prefixKey string, | ||||
| 	pathIndex int, | ||||
| 	path []string, | ||||
| ) interface{} { | ||||
| ) any { | ||||
| 	next, ok := sourceMap[prefixKey] | ||||
| 	if !ok { | ||||
| 		return nil | ||||
|  | @ -775,9 +783,9 @@ func (v *Viper) searchMapWithPathPrefixes( | |||
| 
 | ||||
| 	// Nested case | ||||
| 	switch n := next.(type) { | ||||
| 	case map[interface{}]interface{}: | ||||
| 	case map[any]any: | ||||
| 		return v.searchIndexableWithPathPrefixes(cast.ToStringMap(n), path[pathIndex:]) | ||||
| 	case map[string]interface{}, []interface{}: | ||||
| 	case map[string]any, []any: | ||||
| 		return v.searchIndexableWithPathPrefixes(n, path[pathIndex:]) | ||||
| 	default: | ||||
| 		// got a value but nested key expected, do nothing and look for next prefix | ||||
|  | @ -792,8 +800,8 @@ func (v *Viper) searchMapWithPathPrefixes( | |||
| // e.g., if "foo.bar" has a value in the given map, it “shadows” | ||||
| // | ||||
| //	"foo.bar.baz" in a lower-priority map | ||||
| func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string { | ||||
| 	var parentVal interface{} | ||||
| func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]any) string { | ||||
| 	var parentVal any | ||||
| 	for i := 1; i < len(path); i++ { | ||||
| 		parentVal = v.searchMap(m, path[0:i]) | ||||
| 		if parentVal == nil { | ||||
|  | @ -801,9 +809,9 @@ func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) | |||
| 			return "" | ||||
| 		} | ||||
| 		switch parentVal.(type) { | ||||
| 		case map[interface{}]interface{}: | ||||
| 		case map[any]any: | ||||
| 			continue | ||||
| 		case map[string]interface{}: | ||||
| 		case map[string]any: | ||||
| 			continue | ||||
| 		default: | ||||
| 			// parentVal is a regular value which shadows "path" | ||||
|  | @ -818,12 +826,14 @@ func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) | |||
| // e.g., if "foo.bar" has a value in the given map, it “shadows” | ||||
| // | ||||
| //	"foo.bar.baz" in a lower-priority map | ||||
| func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string { | ||||
| func (v *Viper) isPathShadowedInFlatMap(path []string, mi any) string { | ||||
| 	// unify input map | ||||
| 	var m map[string]interface{} | ||||
| 	switch mi.(type) { | ||||
| 	case map[string]string, map[string]FlagValue: | ||||
| 		m = cast.ToStringMap(mi) | ||||
| 	switch miv := mi.(type) { | ||||
| 	case map[string]string: | ||||
| 		m = castMapStringToMapInterface(miv) | ||||
| 	case map[string]FlagValue: | ||||
| 		m = castMapFlagToMapInterface(miv) | ||||
| 	default: | ||||
| 		return "" | ||||
| 	} | ||||
|  | @ -887,9 +897,9 @@ func GetViper() *Viper { | |||
| // override, flag, env, config file, key/value store, default | ||||
| // | ||||
| // Get returns an interface. For a specific value use one of the Get____ methods. | ||||
| func Get(key string) interface{} { return v.Get(key) } | ||||
| func Get(key string) any { return v.Get(key) } | ||||
| 
 | ||||
| func (v *Viper) Get(key string) interface{} { | ||||
| func (v *Viper) Get(key string) any { | ||||
| 	lcaseKey := strings.ToLower(key) | ||||
| 	val := v.find(lcaseKey, true) | ||||
| 	if val == nil { | ||||
|  | @ -950,7 +960,8 @@ func (v *Viper) Sub(key string) *Viper { | |||
| 	} | ||||
| 
 | ||||
| 	if reflect.TypeOf(data).Kind() == reflect.Map { | ||||
| 		subv.parents = append(v.parents, strings.ToLower(key)) | ||||
| 		subv.parents = append([]string(nil), v.parents...) | ||||
| 		subv.parents = append(subv.parents, strings.ToLower(key)) | ||||
| 		subv.automaticEnvApplied = v.automaticEnvApplied | ||||
| 		subv.envPrefix = v.envPrefix | ||||
| 		subv.envKeyReplacer = v.envKeyReplacer | ||||
|  | @ -1059,9 +1070,9 @@ func (v *Viper) GetStringSlice(key string) []string { | |||
| } | ||||
| 
 | ||||
| // GetStringMap returns the value associated with the key as a map of interfaces. | ||||
| func GetStringMap(key string) map[string]interface{} { return v.GetStringMap(key) } | ||||
| func GetStringMap(key string) map[string]any { return v.GetStringMap(key) } | ||||
| 
 | ||||
| func (v *Viper) GetStringMap(key string) map[string]interface{} { | ||||
| func (v *Viper) GetStringMap(key string) map[string]any { | ||||
| 	return cast.ToStringMap(v.Get(key)) | ||||
| } | ||||
| 
 | ||||
|  | @ -1089,27 +1100,58 @@ func (v *Viper) GetSizeInBytes(key string) uint { | |||
| } | ||||
| 
 | ||||
| // UnmarshalKey takes a single key and unmarshals it into a Struct. | ||||
| func UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error { | ||||
| func UnmarshalKey(key string, rawVal any, opts ...DecoderConfigOption) error { | ||||
| 	return v.UnmarshalKey(key, rawVal, opts...) | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error { | ||||
| func (v *Viper) UnmarshalKey(key string, rawVal any, opts ...DecoderConfigOption) error { | ||||
| 	return decode(v.Get(key), defaultDecoderConfig(rawVal, opts...)) | ||||
| } | ||||
| 
 | ||||
| // Unmarshal unmarshals the config into a Struct. Make sure that the tags | ||||
| // on the fields of the structure are properly set. | ||||
| func Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error { | ||||
| func Unmarshal(rawVal any, opts ...DecoderConfigOption) error { | ||||
| 	return v.Unmarshal(rawVal, opts...) | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error { | ||||
| 	return decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...)) | ||||
| func (v *Viper) Unmarshal(rawVal any, opts ...DecoderConfigOption) error { | ||||
| 	keys := v.AllKeys() | ||||
| 
 | ||||
| 	if features.BindStruct { | ||||
| 		// TODO: make this optional? | ||||
| 		structKeys, err := v.decodeStructKeys(rawVal, opts...) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		keys = append(keys, structKeys...) | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: struct keys should be enough? | ||||
| 	return decode(v.getSettings(keys), defaultDecoderConfig(rawVal, opts...)) | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) decodeStructKeys(input any, opts ...DecoderConfigOption) ([]string, error) { | ||||
| 	var structKeyMap map[string]any | ||||
| 
 | ||||
| 	err := decode(input, defaultDecoderConfig(&structKeyMap, opts...)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	flattenedStructKeyMap := v.flattenAndMergeMap(map[string]bool{}, structKeyMap, "") | ||||
| 
 | ||||
| 	r := make([]string, 0, len(flattenedStructKeyMap)) | ||||
| 	for v := range flattenedStructKeyMap { | ||||
| 		r = append(r, v) | ||||
| 	} | ||||
| 
 | ||||
| 	return r, nil | ||||
| } | ||||
| 
 | ||||
| // defaultDecoderConfig returns default mapstructure.DecoderConfig with support | ||||
| // of time.Duration values & string slices | ||||
| func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *mapstructure.DecoderConfig { | ||||
| // of time.Duration values & string slices. | ||||
| func defaultDecoderConfig(output any, opts ...DecoderConfigOption) *mapstructure.DecoderConfig { | ||||
| 	c := &mapstructure.DecoderConfig{ | ||||
| 		Metadata:         nil, | ||||
| 		Result:           output, | ||||
|  | @ -1125,8 +1167,8 @@ func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *maps | |||
| 	return c | ||||
| } | ||||
| 
 | ||||
| // A wrapper around mapstructure.Decode that mimics the WeakDecode functionality | ||||
| func decode(input interface{}, config *mapstructure.DecoderConfig) error { | ||||
| // decode is a wrapper around mapstructure.Decode that mimics the WeakDecode functionality. | ||||
| func decode(input any, config *mapstructure.DecoderConfig) error { | ||||
| 	decoder, err := mapstructure.NewDecoder(config) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|  | @ -1136,15 +1178,28 @@ func decode(input interface{}, config *mapstructure.DecoderConfig) error { | |||
| 
 | ||||
| // UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent | ||||
| // in the destination struct. | ||||
| func UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error { | ||||
| func UnmarshalExact(rawVal any, opts ...DecoderConfigOption) error { | ||||
| 	return v.UnmarshalExact(rawVal, opts...) | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error { | ||||
| func (v *Viper) UnmarshalExact(rawVal any, opts ...DecoderConfigOption) error { | ||||
| 	config := defaultDecoderConfig(rawVal, opts...) | ||||
| 	config.ErrorUnused = true | ||||
| 
 | ||||
| 	return decode(v.AllSettings(), config) | ||||
| 	keys := v.AllKeys() | ||||
| 
 | ||||
| 	if features.BindStruct { | ||||
| 		// TODO: make this optional? | ||||
| 		structKeys, err := v.decodeStructKeys(rawVal, opts...) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		keys = append(keys, structKeys...) | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: struct keys should be enough? | ||||
| 	return decode(v.getSettings(keys), config) | ||||
| } | ||||
| 
 | ||||
| // BindPFlags binds a full flag set to the configuration, using each flag's long | ||||
|  | @ -1237,9 +1292,9 @@ func (v *Viper) MustBindEnv(input ...string) { | |||
| // corresponds to a flag, the flag's default value is returned. | ||||
| // | ||||
| // Note: this assumes a lower-cased key given. | ||||
| func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} { | ||||
| func (v *Viper) find(lcaseKey string, flagDefault bool) any { | ||||
| 	var ( | ||||
| 		val    interface{} | ||||
| 		val    any | ||||
| 		exists bool | ||||
| 		path   = strings.Split(lcaseKey, v.keyDelim) | ||||
| 		nested = len(path) > 1 | ||||
|  | @ -1398,46 +1453,46 @@ func readAsCSV(val string) ([]string, error) { | |||
| } | ||||
| 
 | ||||
| // mostly copied from pflag's implementation of this operation here https://github.com/spf13/pflag/blob/master/string_to_string.go#L79 | ||||
| // alterations are: errors are swallowed, map[string]interface{} is returned in order to enable cast.ToStringMap | ||||
| func stringToStringConv(val string) interface{} { | ||||
| // alterations are: errors are swallowed, map[string]any is returned in order to enable cast.ToStringMap. | ||||
| func stringToStringConv(val string) any { | ||||
| 	val = strings.Trim(val, "[]") | ||||
| 	// An empty string would cause an empty map | ||||
| 	if len(val) == 0 { | ||||
| 		return map[string]interface{}{} | ||||
| 	if val == "" { | ||||
| 		return map[string]any{} | ||||
| 	} | ||||
| 	r := csv.NewReader(strings.NewReader(val)) | ||||
| 	ss, err := r.Read() | ||||
| 	if err != nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	out := make(map[string]interface{}, len(ss)) | ||||
| 	out := make(map[string]any, len(ss)) | ||||
| 	for _, pair := range ss { | ||||
| 		kv := strings.SplitN(pair, "=", 2) | ||||
| 		if len(kv) != 2 { | ||||
| 		k, vv, found := strings.Cut(pair, "=") | ||||
| 		if !found { | ||||
| 			return nil | ||||
| 		} | ||||
| 		out[kv[0]] = kv[1] | ||||
| 		out[k] = vv | ||||
| 	} | ||||
| 	return out | ||||
| } | ||||
| 
 | ||||
| // mostly copied from pflag's implementation of this operation here https://github.com/spf13/pflag/blob/d5e0c0615acee7028e1e2740a11102313be88de1/string_to_int.go#L68 | ||||
| // alterations are: errors are swallowed, map[string]interface{} is returned in order to enable cast.ToStringMap | ||||
| func stringToIntConv(val string) interface{} { | ||||
| // alterations are: errors are swallowed, map[string]any is returned in order to enable cast.ToStringMap. | ||||
| func stringToIntConv(val string) any { | ||||
| 	val = strings.Trim(val, "[]") | ||||
| 	// An empty string would cause an empty map | ||||
| 	if len(val) == 0 { | ||||
| 		return map[string]interface{}{} | ||||
| 	if val == "" { | ||||
| 		return map[string]any{} | ||||
| 	} | ||||
| 	ss := strings.Split(val, ",") | ||||
| 	out := make(map[string]interface{}, len(ss)) | ||||
| 	out := make(map[string]any, len(ss)) | ||||
| 	for _, pair := range ss { | ||||
| 		kv := strings.SplitN(pair, "=", 2) | ||||
| 		if len(kv) != 2 { | ||||
| 		k, vv, found := strings.Cut(pair, "=") | ||||
| 		if !found { | ||||
| 			return nil | ||||
| 		} | ||||
| 		var err error | ||||
| 		out[kv[0]], err = strconv.Atoi(kv[1]) | ||||
| 		out[k], err = strconv.Atoi(vv) | ||||
| 		if err != nil { | ||||
| 			return nil | ||||
| 		} | ||||
|  | @ -1474,13 +1529,13 @@ func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) { | |||
| 
 | ||||
| // RegisterAlias creates an alias that provides 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) } | ||||
| func RegisterAlias(alias, key string) { v.RegisterAlias(alias, key) } | ||||
| 
 | ||||
| func (v *Viper) RegisterAlias(alias string, key string) { | ||||
| func (v *Viper) RegisterAlias(alias, key string) { | ||||
| 	v.registerAlias(alias, strings.ToLower(key)) | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) registerAlias(alias string, key string) { | ||||
| func (v *Viper) registerAlias(alias, key string) { | ||||
| 	alias = strings.ToLower(alias) | ||||
| 	if alias != key && alias != v.realKey(key) { | ||||
| 		_, exists := v.aliases[alias] | ||||
|  | @ -1538,9 +1593,9 @@ 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 SetDefault(key string, value any) { v.SetDefault(key, value) } | ||||
| 
 | ||||
| func (v *Viper) SetDefault(key string, value interface{}) { | ||||
| func (v *Viper) SetDefault(key string, value any) { | ||||
| 	// If alias passed in, then set the proper default | ||||
| 	key = v.realKey(strings.ToLower(key)) | ||||
| 	value = toCaseInsensitiveValue(value) | ||||
|  | @ -1557,9 +1612,9 @@ func (v *Viper) SetDefault(key string, value interface{}) { | |||
| // 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 Set(key string, value any) { v.Set(key, value) } | ||||
| 
 | ||||
| func (v *Viper) Set(key string, value interface{}) { | ||||
| func (v *Viper) Set(key string, value any) { | ||||
| 	// If alias passed in, then set the proper override | ||||
| 	key = v.realKey(strings.ToLower(key)) | ||||
| 	value = toCaseInsensitiveValue(value) | ||||
|  | @ -1593,7 +1648,7 @@ func (v *Viper) ReadInConfig() error { | |||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	config := make(map[string]interface{}) | ||||
| 	config := make(map[string]any) | ||||
| 
 | ||||
| 	err = v.unmarshalReader(bytes.NewReader(file), config) | ||||
| 	if err != nil { | ||||
|  | @ -1631,7 +1686,7 @@ func (v *Viper) MergeInConfig() error { | |||
| func ReadConfig(in io.Reader) error { return v.ReadConfig(in) } | ||||
| 
 | ||||
| func (v *Viper) ReadConfig(in io.Reader) error { | ||||
| 	v.config = make(map[string]interface{}) | ||||
| 	v.config = make(map[string]any) | ||||
| 	return v.unmarshalReader(in, v.config) | ||||
| } | ||||
| 
 | ||||
|  | @ -1639,7 +1694,7 @@ func (v *Viper) ReadConfig(in io.Reader) error { | |||
| func MergeConfig(in io.Reader) error { return v.MergeConfig(in) } | ||||
| 
 | ||||
| func (v *Viper) MergeConfig(in io.Reader) error { | ||||
| 	cfg := make(map[string]interface{}) | ||||
| 	cfg := make(map[string]any) | ||||
| 	if err := v.unmarshalReader(in, cfg); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | @ -1648,11 +1703,11 @@ func (v *Viper) MergeConfig(in io.Reader) error { | |||
| 
 | ||||
| // MergeConfigMap merges the configuration from the map given with an existing config. | ||||
| // Note that the map given may be modified. | ||||
| func MergeConfigMap(cfg map[string]interface{}) error { return v.MergeConfigMap(cfg) } | ||||
| func MergeConfigMap(cfg map[string]any) error { return v.MergeConfigMap(cfg) } | ||||
| 
 | ||||
| func (v *Viper) MergeConfigMap(cfg map[string]interface{}) error { | ||||
| func (v *Viper) MergeConfigMap(cfg map[string]any) error { | ||||
| 	if v.config == nil { | ||||
| 		v.config = make(map[string]interface{}) | ||||
| 		v.config = make(map[string]any) | ||||
| 	} | ||||
| 	insensitiviseMap(cfg) | ||||
| 	mergeMaps(cfg, v.config, nil) | ||||
|  | @ -1717,7 +1772,7 @@ func (v *Viper) writeConfig(filename string, force bool) error { | |||
| 		return UnsupportedConfigError(configType) | ||||
| 	} | ||||
| 	if v.config == nil { | ||||
| 		v.config = make(map[string]interface{}) | ||||
| 		v.config = make(map[string]any) | ||||
| 	} | ||||
| 	flags := os.O_CREATE | os.O_TRUNC | os.O_WRONLY | ||||
| 	if !force { | ||||
|  | @ -1738,11 +1793,11 @@ func (v *Viper) writeConfig(filename string, force bool) error { | |||
| 
 | ||||
| // Unmarshal a Reader into a map. | ||||
| // Should probably be an unexported function. | ||||
| func unmarshalReader(in io.Reader, c map[string]interface{}) error { | ||||
| func unmarshalReader(in io.Reader, c map[string]any) error { | ||||
| 	return v.unmarshalReader(in, c) | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error { | ||||
| func (v *Viper) unmarshalReader(in io.Reader, c map[string]any) error { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	buf.ReadFrom(in) | ||||
| 
 | ||||
|  | @ -1776,7 +1831,7 @@ func (v *Viper) marshalWriter(f afero.File, configType string) error { | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func keyExists(k string, m map[string]interface{}) string { | ||||
| func keyExists(k string, m map[string]any) string { | ||||
| 	lk := strings.ToLower(k) | ||||
| 	for mk := range m { | ||||
| 		lmk := strings.ToLower(mk) | ||||
|  | @ -1788,33 +1843,33 @@ func keyExists(k string, m map[string]interface{}) string { | |||
| } | ||||
| 
 | ||||
| func castToMapStringInterface( | ||||
| 	src map[interface{}]interface{}, | ||||
| ) map[string]interface{} { | ||||
| 	tgt := map[string]interface{}{} | ||||
| 	src map[any]any, | ||||
| ) map[string]any { | ||||
| 	tgt := map[string]any{} | ||||
| 	for k, v := range src { | ||||
| 		tgt[fmt.Sprintf("%v", k)] = v | ||||
| 	} | ||||
| 	return tgt | ||||
| } | ||||
| 
 | ||||
| func castMapStringSliceToMapInterface(src map[string][]string) map[string]interface{} { | ||||
| 	tgt := map[string]interface{}{} | ||||
| func castMapStringSliceToMapInterface(src map[string][]string) map[string]any { | ||||
| 	tgt := map[string]any{} | ||||
| 	for k, v := range src { | ||||
| 		tgt[k] = v | ||||
| 	} | ||||
| 	return tgt | ||||
| } | ||||
| 
 | ||||
| func castMapStringToMapInterface(src map[string]string) map[string]interface{} { | ||||
| 	tgt := map[string]interface{}{} | ||||
| func castMapStringToMapInterface(src map[string]string) map[string]any { | ||||
| 	tgt := map[string]any{} | ||||
| 	for k, v := range src { | ||||
| 		tgt[k] = v | ||||
| 	} | ||||
| 	return tgt | ||||
| } | ||||
| 
 | ||||
| func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} { | ||||
| 	tgt := map[string]interface{}{} | ||||
| func castMapFlagToMapInterface(src map[string]FlagValue) map[string]any { | ||||
| 	tgt := map[string]any{} | ||||
| 	for k, v := range src { | ||||
| 		tgt[k] = v | ||||
| 	} | ||||
|  | @ -1822,17 +1877,15 @@ func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} | |||
| } | ||||
| 
 | ||||
| // mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's | ||||
| // insistence on parsing nested structures as `map[interface{}]interface{}` | ||||
| // insistence on parsing nested structures as `map[any]any` | ||||
| // instead of using a `string` as the key for nest structures beyond one level | ||||
| // deep. Both map types are supported as there is a go-yaml fork that uses | ||||
| // `map[string]interface{}` instead. | ||||
| func mergeMaps( | ||||
| 	src, tgt map[string]interface{}, itgt map[interface{}]interface{}, | ||||
| ) { | ||||
| // `map[string]any` instead. | ||||
| func mergeMaps(src, tgt map[string]any, itgt map[any]any) { | ||||
| 	for sk, sv := range src { | ||||
| 		tk := keyExists(sk, tgt) | ||||
| 		if tk == "" { | ||||
| 			v.logger.Trace("", "tk", "\"\"", fmt.Sprintf("tgt[%s]", sk), sv) | ||||
| 			v.logger.Debug("", "tk", "\"\"", fmt.Sprintf("tgt[%s]", sk), sv) | ||||
| 			tgt[sk] = sv | ||||
| 			if itgt != nil { | ||||
| 				itgt[sk] = sv | ||||
|  | @ -1842,7 +1895,7 @@ func mergeMaps( | |||
| 
 | ||||
| 		tv, ok := tgt[tk] | ||||
| 		if !ok { | ||||
| 			v.logger.Trace("", fmt.Sprintf("ok[%s]", tk), false, fmt.Sprintf("tgt[%s]", sk), sv) | ||||
| 			v.logger.Debug("", fmt.Sprintf("ok[%s]", tk), false, fmt.Sprintf("tgt[%s]", sk), sv) | ||||
| 			tgt[sk] = sv | ||||
| 			if itgt != nil { | ||||
| 				itgt[sk] = sv | ||||
|  | @ -1853,7 +1906,7 @@ func mergeMaps( | |||
| 		svType := reflect.TypeOf(sv) | ||||
| 		tvType := reflect.TypeOf(tv) | ||||
| 
 | ||||
| 		v.logger.Trace( | ||||
| 		v.logger.Debug( | ||||
| 			"processing", | ||||
| 			"key", sk, | ||||
| 			"st", svType, | ||||
|  | @ -1863,12 +1916,12 @@ func mergeMaps( | |||
| 		) | ||||
| 
 | ||||
| 		switch ttv := tv.(type) { | ||||
| 		case map[interface{}]interface{}: | ||||
| 			v.logger.Trace("merging maps (must convert)") | ||||
| 			tsv, ok := sv.(map[interface{}]interface{}) | ||||
| 		case map[any]any: | ||||
| 			v.logger.Debug("merging maps (must convert)") | ||||
| 			tsv, ok := sv.(map[any]any) | ||||
| 			if !ok { | ||||
| 				v.logger.Error( | ||||
| 					"Could not cast sv to map[interface{}]interface{}", | ||||
| 					"Could not cast sv to map[any]any", | ||||
| 					"key", sk, | ||||
| 					"st", svType, | ||||
| 					"tt", tvType, | ||||
|  | @ -1881,12 +1934,12 @@ func mergeMaps( | |||
| 			ssv := castToMapStringInterface(tsv) | ||||
| 			stv := castToMapStringInterface(ttv) | ||||
| 			mergeMaps(ssv, stv, ttv) | ||||
| 		case map[string]interface{}: | ||||
| 			v.logger.Trace("merging maps") | ||||
| 			tsv, ok := sv.(map[string]interface{}) | ||||
| 		case map[string]any: | ||||
| 			v.logger.Debug("merging maps") | ||||
| 			tsv, ok := sv.(map[string]any) | ||||
| 			if !ok { | ||||
| 				v.logger.Error( | ||||
| 					"Could not cast sv to map[string]interface{}", | ||||
| 					"Could not cast sv to map[string]any", | ||||
| 					"key", sk, | ||||
| 					"st", svType, | ||||
| 					"tt", tvType, | ||||
|  | @ -1897,7 +1950,7 @@ func mergeMaps( | |||
| 			} | ||||
| 			mergeMaps(tsv, ttv, nil) | ||||
| 		default: | ||||
| 			v.logger.Trace("setting value") | ||||
| 			v.logger.Debug("setting value") | ||||
| 			tgt[tk] = sv | ||||
| 			if itgt != nil { | ||||
| 				itgt[tk] = sv | ||||
|  | @ -1948,7 +2001,7 @@ func (v *Viper) getKeyValueConfig() error { | |||
| 	return RemoteConfigError("No Files Found") | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) { | ||||
| func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]any, error) { | ||||
| 	reader, err := RemoteConfig.Get(provider) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
|  | @ -1997,7 +2050,7 @@ func (v *Viper) watchKeyValueConfig() error { | |||
| 	return RemoteConfigError("No Files Found") | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) { | ||||
| func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]any, error) { | ||||
| 	reader, err := RemoteConfig.Watch(provider) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
|  | @ -2007,7 +2060,7 @@ func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface | |||
| } | ||||
| 
 | ||||
| // AllKeys returns all keys holding a value, regardless of where they are set. | ||||
| // Nested keys are returned with a v.keyDelim separator | ||||
| // Nested keys are returned with a v.keyDelim separator. | ||||
| func AllKeys() []string { return v.AllKeys() } | ||||
| 
 | ||||
| func (v *Viper) AllKeys() []string { | ||||
|  | @ -2036,7 +2089,7 @@ func (v *Viper) AllKeys() []string { | |||
| //     it is skipped. | ||||
| // | ||||
| // The resulting set of paths is merged to the given shadow set at the same time. | ||||
| func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool { | ||||
| func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]any, prefix string) map[string]bool { | ||||
| 	if shadow != nil && prefix != "" && shadow[prefix] { | ||||
| 		// prefix is shadowed => nothing more to flatten | ||||
| 		return shadow | ||||
|  | @ -2045,16 +2098,16 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac | |||
| 		shadow = make(map[string]bool) | ||||
| 	} | ||||
| 
 | ||||
| 	var m2 map[string]interface{} | ||||
| 	var m2 map[string]any | ||||
| 	if prefix != "" { | ||||
| 		prefix += v.keyDelim | ||||
| 	} | ||||
| 	for k, val := range m { | ||||
| 		fullKey := prefix + k | ||||
| 		switch val.(type) { | ||||
| 		case map[string]interface{}: | ||||
| 			m2 = val.(map[string]interface{}) | ||||
| 		case map[interface{}]interface{}: | ||||
| 		switch val := val.(type) { | ||||
| 		case map[string]any: | ||||
| 			m2 = val | ||||
| 		case map[any]any: | ||||
| 			m2 = cast.ToStringMap(val) | ||||
| 		default: | ||||
| 			// immediate value | ||||
|  | @ -2069,7 +2122,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, m map[string]interface{}) map[string]bool { | ||||
| func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]any) map[string]bool { | ||||
| 	// scan keys | ||||
| outer: | ||||
| 	for k := range m { | ||||
|  | @ -2089,13 +2142,17 @@ outer: | |||
| 	return shadow | ||||
| } | ||||
| 
 | ||||
| // AllSettings merges all settings and returns them as a map[string]interface{}. | ||||
| func AllSettings() map[string]interface{} { return v.AllSettings() } | ||||
| // AllSettings merges all settings and returns them as a map[string]any. | ||||
| func AllSettings() map[string]any { return v.AllSettings() } | ||||
| 
 | ||||
| func (v *Viper) AllSettings() map[string]interface{} { | ||||
| 	m := map[string]interface{}{} | ||||
| func (v *Viper) AllSettings() map[string]any { | ||||
| 	return v.getSettings(v.AllKeys()) | ||||
| } | ||||
| 
 | ||||
| func (v *Viper) getSettings(keys []string) map[string]any { | ||||
| 	m := map[string]any{} | ||||
| 	// start from the list of keys, and construct the map one value at a time | ||||
| 	for _, k := range v.AllKeys() { | ||||
| 	for _, k := range keys { | ||||
| 		value := v.Get(k) | ||||
| 		if value == nil { | ||||
| 			// should not happen, since AllKeys() returns only keys holding a value, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue