gitee.com/evanscat/viper@v1.7.2/viper.go (about)

     1  // Copyright © 2014 Steve Francia <spf@spf13.com>.
     2  //
     3  // Use of this source code is governed by an MIT-style
     4  // license that can be found in the LICENSE file.
     5  
     6  // Viper is an application configuration system.
     7  // It believes that applications can be configured a variety of ways
     8  // via flags, ENVIRONMENT variables, configuration files retrieved
     9  // from the file system, or a remote key/value store.
    10  
    11  // Each item takes precedence over the item below it:
    12  
    13  // overrides
    14  // flag
    15  // env
    16  // config
    17  // key/value store
    18  // default
    19  
    20  package viper
    21  
    22  import (
    23  	"bytes"
    24  	"encoding/csv"
    25  	"encoding/json"
    26  	"errors"
    27  	"fmt"
    28  	"io"
    29  	"log"
    30  	"os"
    31  	"path/filepath"
    32  	"reflect"
    33  	"strconv"
    34  	"strings"
    35  	"sync"
    36  	"time"
    37  
    38  	"github.com/fsnotify/fsnotify"
    39  	"github.com/hashicorp/hcl"
    40  	"github.com/hashicorp/hcl/hcl/printer"
    41  	"github.com/magiconair/properties"
    42  	"github.com/mitchellh/mapstructure"
    43  	"github.com/pelletier/go-toml"
    44  	"github.com/spf13/afero"
    45  	"github.com/spf13/cast"
    46  	jww "github.com/spf13/jwalterweatherman"
    47  	"github.com/spf13/pflag"
    48  	"github.com/subosito/gotenv"
    49  	"gopkg.in/ini.v1"
    50  	"gopkg.in/yaml.v2"
    51  )
    52  
    53  // ConfigMarshalError happens when failing to marshal the configuration.
    54  type ConfigMarshalError struct {
    55  	err error
    56  }
    57  
    58  // Error returns the formatted configuration error.
    59  func (e ConfigMarshalError) Error() string {
    60  	return fmt.Sprintf("While marshaling config: %s", e.err.Error())
    61  }
    62  
    63  var v *Viper
    64  
    65  type RemoteResponse struct {
    66  	Value []byte
    67  	Error error
    68  }
    69  
    70  func init() {
    71  	v = New()
    72  }
    73  
    74  type remoteConfigFactory interface {
    75  	Get(rp RemoteProvider) (io.Reader, error)
    76  	Watch(rp RemoteProvider) (io.Reader, error)
    77  	WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool)
    78  }
    79  
    80  // RemoteConfig is optional, see the remote package
    81  var RemoteConfig remoteConfigFactory
    82  
    83  // UnsupportedConfigError denotes encountering an unsupported
    84  // configuration filetype.
    85  type UnsupportedConfigError string
    86  
    87  // Error returns the formatted configuration error.
    88  func (str UnsupportedConfigError) Error() string {
    89  	return fmt.Sprintf("Unsupported Config Type %q", string(str))
    90  }
    91  
    92  // UnsupportedRemoteProviderError denotes encountering an unsupported remote
    93  // provider. Currently only etcd and Consul are supported.
    94  type UnsupportedRemoteProviderError string
    95  
    96  // Error returns the formatted remote provider error.
    97  func (str UnsupportedRemoteProviderError) Error() string {
    98  	return fmt.Sprintf("Unsupported Remote Provider Type %q", string(str))
    99  }
   100  
   101  // RemoteConfigError denotes encountering an error while trying to
   102  // pull the configuration from the remote provider.
   103  type RemoteConfigError string
   104  
   105  // Error returns the formatted remote provider error
   106  func (rce RemoteConfigError) Error() string {
   107  	return fmt.Sprintf("Remote Configurations Error: %s", string(rce))
   108  }
   109  
   110  // ConfigFileNotFoundError denotes failing to find configuration file.
   111  type ConfigFileNotFoundError struct {
   112  	name, locations string
   113  }
   114  
   115  // Error returns the formatted configuration error.
   116  func (fnfe ConfigFileNotFoundError) Error() string {
   117  	return fmt.Sprintf("Config File %q Not Found in %q", fnfe.name, fnfe.locations)
   118  }
   119  
   120  // ConfigFileAlreadyExistsError denotes failure to write new configuration file.
   121  type ConfigFileAlreadyExistsError string
   122  
   123  // Error returns the formatted error when configuration already exists.
   124  func (faee ConfigFileAlreadyExistsError) Error() string {
   125  	return fmt.Sprintf("Config File %q Already Exists", string(faee))
   126  }
   127  
   128  // A DecoderConfigOption can be passed to viper.Unmarshal to configure
   129  // mapstructure.DecoderConfig options
   130  type DecoderConfigOption func(*mapstructure.DecoderConfig)
   131  
   132  // DecodeHook returns a DecoderConfigOption which overrides the default
   133  // DecoderConfig.DecodeHook value, the default is:
   134  //
   135  //  mapstructure.ComposeDecodeHookFunc(
   136  //		mapstructure.StringToTimeDurationHookFunc(),
   137  //		mapstructure.StringToSliceHookFunc(","),
   138  //	)
   139  func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption {
   140  	return func(c *mapstructure.DecoderConfig) {
   141  		c.DecodeHook = hook
   142  	}
   143  }
   144  
   145  // Viper is a prioritized configuration registry. It
   146  // maintains a set of configuration sources, fetches
   147  // values to populate those, and provides them according
   148  // to the source's priority.
   149  // The priority of the sources is the following:
   150  // 1. overrides
   151  // 2. flags
   152  // 3. env. variables
   153  // 4. config file
   154  // 5. key/value store
   155  // 6. defaults
   156  //
   157  // For example, if values from the following sources were loaded:
   158  //
   159  //  Defaults : {
   160  //  	"secret": "",
   161  //  	"user": "default",
   162  //  	"endpoint": "https://localhost"
   163  //  }
   164  //  Config : {
   165  //  	"user": "root"
   166  //  	"secret": "defaultsecret"
   167  //  }
   168  //  Env : {
   169  //  	"secret": "somesecretkey"
   170  //  }
   171  //
   172  // The resulting config will have the following values:
   173  //
   174  //	{
   175  //		"secret": "somesecretkey",
   176  //		"user": "root",
   177  //		"endpoint": "https://localhost"
   178  //	}
   179  type Viper struct {
   180  	// Delimiter that separates a list of keys
   181  	// used to access a nested value in one go
   182  	keyDelim string
   183  
   184  	// A set of paths to look for the config file in
   185  	configPaths []string
   186  
   187  	// The filesystem to read config from.
   188  	fs afero.Fs
   189  
   190  	// A set of remote providers to search for the configuration
   191  	remoteProviders []*defaultRemoteProvider
   192  
   193  	// Name of file to look for inside the path
   194  	configName        string
   195  	configFile        string
   196  	configType        string
   197  	configPermissions os.FileMode
   198  	envPrefix         string
   199  
   200  	automaticEnvApplied bool
   201  	envKeyReplacer      StringReplacer
   202  	allowEmptyEnv       bool
   203  
   204  	config         map[string]interface{}
   205  	override       map[string]interface{}
   206  	defaults       map[string]interface{}
   207  	kvstore        map[string]interface{}
   208  	pflags         map[string]FlagValue
   209  	env            map[string][]string
   210  	aliases        map[string]string
   211  	typeByDefValue bool
   212  
   213  	// Store read properties on the object so that we can write back in order with comments.
   214  	// This will only be used if the configuration read is a properties file.
   215  	properties *properties.Properties
   216  
   217  	onConfigChange func(fsnotify.Event)
   218  }
   219  
   220  // New returns an initialized Viper instance.
   221  func New() *Viper {
   222  	v := new(Viper)
   223  	v.keyDelim = "."
   224  	v.configName = "config"
   225  	v.configPermissions = os.FileMode(0644)
   226  	v.fs = afero.NewOsFs()
   227  	v.config = make(map[string]interface{})
   228  	v.override = make(map[string]interface{})
   229  	v.defaults = make(map[string]interface{})
   230  	v.kvstore = make(map[string]interface{})
   231  	v.pflags = make(map[string]FlagValue)
   232  	v.env = make(map[string][]string)
   233  	v.aliases = make(map[string]string)
   234  	v.typeByDefValue = false
   235  
   236  	return v
   237  }
   238  
   239  // Option configures Viper using the functional options paradigm popularized by Rob Pike and Dave Cheney.
   240  // If you're unfamiliar with this style,
   241  // see https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html and
   242  // https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis.
   243  type Option interface {
   244  	apply(v *Viper)
   245  }
   246  
   247  type optionFunc func(v *Viper)
   248  
   249  func (fn optionFunc) apply(v *Viper) {
   250  	fn(v)
   251  }
   252  
   253  // KeyDelimiter sets the delimiter used for determining key parts.
   254  // By default it's value is ".".
   255  func KeyDelimiter(d string) Option {
   256  	return optionFunc(func(v *Viper) {
   257  		v.keyDelim = d
   258  	})
   259  }
   260  
   261  // StringReplacer applies a set of replacements to a string.
   262  type StringReplacer interface {
   263  	// Replace returns a copy of s with all replacements performed.
   264  	Replace(s string) string
   265  }
   266  
   267  // EnvKeyReplacer sets a replacer used for mapping environment variables to internal keys.
   268  func EnvKeyReplacer(r StringReplacer) Option {
   269  	return optionFunc(func(v *Viper) {
   270  		v.envKeyReplacer = r
   271  	})
   272  }
   273  
   274  // NewWithOptions creates a new Viper instance.
   275  func NewWithOptions(opts ...Option) *Viper {
   276  	v := New()
   277  
   278  	for _, opt := range opts {
   279  		opt.apply(v)
   280  	}
   281  
   282  	return v
   283  }
   284  
   285  // Reset is intended for testing, will reset all to default settings.
   286  // In the public interface for the viper package so applications
   287  // can use it in their testing as well.
   288  func Reset() {
   289  	v = New()
   290  	SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"}
   291  	SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
   292  }
   293  
   294  type defaultRemoteProvider struct {
   295  	provider      string
   296  	endpoint      string
   297  	path          string
   298  	secretKeyring string
   299  }
   300  
   301  func (rp defaultRemoteProvider) Provider() string {
   302  	return rp.provider
   303  }
   304  
   305  func (rp defaultRemoteProvider) Endpoint() string {
   306  	return rp.endpoint
   307  }
   308  
   309  func (rp defaultRemoteProvider) Path() string {
   310  	return rp.path
   311  }
   312  
   313  func (rp defaultRemoteProvider) SecretKeyring() string {
   314  	return rp.secretKeyring
   315  }
   316  
   317  // RemoteProvider stores the configuration necessary
   318  // to connect to a remote key/value store.
   319  // Optional secretKeyring to unencrypt encrypted values
   320  // can be provided.
   321  type RemoteProvider interface {
   322  	Provider() string
   323  	Endpoint() string
   324  	Path() string
   325  	SecretKeyring() string
   326  }
   327  
   328  // SupportedExts are universally supported extensions.
   329  var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"}
   330  
   331  // SupportedRemoteProviders are universally supported remote providers.
   332  var SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
   333  
   334  func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
   335  func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) {
   336  	v.onConfigChange = run
   337  }
   338  
   339  func WatchConfig() { v.WatchConfig() }
   340  
   341  func (v *Viper) WatchConfig() {
   342  	initWG := sync.WaitGroup{}
   343  	initWG.Add(1)
   344  	go func() {
   345  		watcher, err := fsnotify.NewWatcher()
   346  		if err != nil {
   347  			log.Fatal(err)
   348  		}
   349  		defer watcher.Close()
   350  		// we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way
   351  		filename, err := v.getConfigFile()
   352  		if err != nil {
   353  			log.Printf("error: %v\n", err)
   354  			initWG.Done()
   355  			return
   356  		}
   357  
   358  		configFile := filepath.Clean(filename)
   359  		configDir, _ := filepath.Split(configFile)
   360  		realConfigFile, _ := filepath.EvalSymlinks(filename)
   361  
   362  		eventsWG := sync.WaitGroup{}
   363  		eventsWG.Add(1)
   364  		go func() {
   365  			for {
   366  				select {
   367  				case event, ok := <-watcher.Events:
   368  					if !ok { // 'Events' channel is closed
   369  						eventsWG.Done()
   370  						return
   371  					}
   372  					currentConfigFile, _ := filepath.EvalSymlinks(filename)
   373  					// we only care about the config file with the following cases:
   374  					// 1 - if the config file was modified or created
   375  					// 2 - if the real path to the config file changed (eg: k8s ConfigMap replacement)
   376  					const writeOrCreateMask = fsnotify.Write | fsnotify.Create
   377  					if (filepath.Clean(event.Name) == configFile &&
   378  						event.Op&writeOrCreateMask != 0) ||
   379  						(currentConfigFile != "" && currentConfigFile != realConfigFile) {
   380  						realConfigFile = currentConfigFile
   381  						err := v.ReadInConfig()
   382  						if err != nil {
   383  							log.Printf("error reading config file: %v\n", err)
   384  						}
   385  						if v.onConfigChange != nil {
   386  							v.onConfigChange(event)
   387  						}
   388  					} else if filepath.Clean(event.Name) == configFile &&
   389  						event.Op&fsnotify.Remove&fsnotify.Remove != 0 {
   390  						eventsWG.Done()
   391  						return
   392  					}
   393  
   394  				case err, ok := <-watcher.Errors:
   395  					if ok { // 'Errors' channel is not closed
   396  						log.Printf("watcher error: %v\n", err)
   397  					}
   398  					eventsWG.Done()
   399  					return
   400  				}
   401  			}
   402  		}()
   403  		watcher.Add(configDir)
   404  		initWG.Done()   // done initializing the watch in this go routine, so the parent routine can move on...
   405  		eventsWG.Wait() // now, wait for event loop to end in this go-routine...
   406  	}()
   407  	initWG.Wait() // make sure that the go routine above fully ended before returning
   408  }
   409  
   410  // SetConfigFile explicitly defines the path, name and extension of the config file.
   411  // Viper will use this and not check any of the config paths.
   412  func SetConfigFile(in string) { v.SetConfigFile(in) }
   413  
   414  func (v *Viper) SetConfigFile(in string) {
   415  	if in != "" {
   416  		v.configFile = in
   417  	}
   418  }
   419  
   420  // SetEnvPrefix defines a prefix that ENVIRONMENT variables will use.
   421  // E.g. if your prefix is "spf", the env registry will look for env
   422  // variables that start with "SPF_".
   423  func SetEnvPrefix(in string) { v.SetEnvPrefix(in) }
   424  
   425  func (v *Viper) SetEnvPrefix(in string) {
   426  	if in != "" {
   427  		v.envPrefix = in
   428  	}
   429  }
   430  
   431  func (v *Viper) mergeWithEnvPrefix(in string) string {
   432  	if v.envPrefix != "" {
   433  		return strings.ToUpper(v.envPrefix + "_" + in)
   434  	}
   435  
   436  	return strings.ToUpper(in)
   437  }
   438  
   439  // AllowEmptyEnv tells Viper to consider set,
   440  // but empty environment variables as valid values instead of falling back.
   441  // For backward compatibility reasons this is false by default.
   442  func AllowEmptyEnv(allowEmptyEnv bool) { v.AllowEmptyEnv(allowEmptyEnv) }
   443  
   444  func (v *Viper) AllowEmptyEnv(allowEmptyEnv bool) {
   445  	v.allowEmptyEnv = allowEmptyEnv
   446  }
   447  
   448  // TODO: should getEnv logic be moved into find(). Can generalize the use of
   449  // rewriting keys many things, Ex: Get('someKey') -> some_key
   450  // (camel case to snake case for JSON keys perhaps)
   451  
   452  // getEnv is a wrapper around os.Getenv which replaces characters in the original
   453  // key. This allows env vars which have different keys than the config object
   454  // keys.
   455  func (v *Viper) getEnv(key string) (string, bool) {
   456  	if v.envKeyReplacer != nil {
   457  		key = v.envKeyReplacer.Replace(key)
   458  	}
   459  
   460  	val, ok := os.LookupEnv(key)
   461  
   462  	return val, ok && (v.allowEmptyEnv || val != "")
   463  }
   464  
   465  // ConfigFileUsed returns the file used to populate the config registry.
   466  func ConfigFileUsed() string            { return v.ConfigFileUsed() }
   467  func (v *Viper) ConfigFileUsed() string { return v.configFile }
   468  
   469  // AddConfigPath adds a path for Viper to search for the config file in.
   470  // Can be called multiple times to define multiple search paths.
   471  func AddConfigPath(in string) { v.AddConfigPath(in) }
   472  
   473  func (v *Viper) AddConfigPath(in string) {
   474  	if in != "" {
   475  		absin := absPathify(in)
   476  		jww.INFO.Println("adding", absin, "to paths to search")
   477  		if !stringInSlice(absin, v.configPaths) {
   478  			v.configPaths = append(v.configPaths, absin)
   479  		}
   480  	}
   481  }
   482  
   483  // AddRemoteProvider adds a remote configuration source.
   484  // Remote Providers are searched in the order they are added.
   485  // provider is a string value: "etcd", "consul" or "firestore" are currently supported.
   486  // endpoint is the url.  etcd requires http://ip:port  consul requires ip:port
   487  // path is the path in the k/v store to retrieve configuration
   488  // To retrieve a config file called myapp.json from /configs/myapp.json
   489  // you should set path to /configs and set config name (SetConfigName()) to
   490  // "myapp"
   491  func AddRemoteProvider(provider, endpoint, path string) error {
   492  	return v.AddRemoteProvider(provider, endpoint, path)
   493  }
   494  
   495  func (v *Viper) AddRemoteProvider(provider, endpoint, path string) error {
   496  	if !stringInSlice(provider, SupportedRemoteProviders) {
   497  		return UnsupportedRemoteProviderError(provider)
   498  	}
   499  	if provider != "" && endpoint != "" {
   500  		jww.INFO.Printf("adding %s:%s to remote provider list", provider, endpoint)
   501  		rp := &defaultRemoteProvider{
   502  			endpoint: endpoint,
   503  			provider: provider,
   504  			path:     path,
   505  		}
   506  		if !v.providerPathExists(rp) {
   507  			v.remoteProviders = append(v.remoteProviders, rp)
   508  		}
   509  	}
   510  	return nil
   511  }
   512  
   513  // AddSecureRemoteProvider adds a remote configuration source.
   514  // Secure Remote Providers are searched in the order they are added.
   515  // provider is a string value: "etcd", "consul" or "firestore" are currently supported.
   516  // endpoint is the url.  etcd requires http://ip:port  consul requires ip:port
   517  // secretkeyring is the filepath to your openpgp secret keyring.  e.g. /etc/secrets/myring.gpg
   518  // path is the path in the k/v store to retrieve configuration
   519  // To retrieve a config file called myapp.json from /configs/myapp.json
   520  // you should set path to /configs and set config name (SetConfigName()) to
   521  // "myapp"
   522  // Secure Remote Providers are implemented with github.com/bketelsen/crypt
   523  func AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error {
   524  	return v.AddSecureRemoteProvider(provider, endpoint, path, secretkeyring)
   525  }
   526  
   527  func (v *Viper) AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error {
   528  	if !stringInSlice(provider, SupportedRemoteProviders) {
   529  		return UnsupportedRemoteProviderError(provider)
   530  	}
   531  	if provider != "" && endpoint != "" {
   532  		jww.INFO.Printf("adding %s:%s to remote provider list", provider, endpoint)
   533  		rp := &defaultRemoteProvider{
   534  			endpoint:      endpoint,
   535  			provider:      provider,
   536  			path:          path,
   537  			secretKeyring: secretkeyring,
   538  		}
   539  		if !v.providerPathExists(rp) {
   540  			v.remoteProviders = append(v.remoteProviders, rp)
   541  		}
   542  	}
   543  	return nil
   544  }
   545  
   546  func (v *Viper) providerPathExists(p *defaultRemoteProvider) bool {
   547  	for _, y := range v.remoteProviders {
   548  		if reflect.DeepEqual(y, p) {
   549  			return true
   550  		}
   551  	}
   552  	return false
   553  }
   554  
   555  // searchMap recursively searches for a value for path in source map.
   556  // Returns nil if not found.
   557  // Note: This assumes that the path entries and map keys are lower cased.
   558  func (v *Viper) searchMap(source map[string]interface{}, path []string) interface{} {
   559  	if len(path) == 0 {
   560  		return source
   561  	}
   562  
   563  	next, ok := source[path[0]]
   564  	if ok {
   565  		// Fast path
   566  		if len(path) == 1 {
   567  			return next
   568  		}
   569  
   570  		// Nested case
   571  		switch next.(type) {
   572  		case map[interface{}]interface{}:
   573  			return v.searchMap(cast.ToStringMap(next), path[1:])
   574  		case map[string]interface{}:
   575  			// Type assertion is safe here since it is only reached
   576  			// if the type of `next` is the same as the type being asserted
   577  			return v.searchMap(next.(map[string]interface{}), path[1:])
   578  		default:
   579  			// got a value but nested key expected, return "nil" for not found
   580  			return nil
   581  		}
   582  	}
   583  	return nil
   584  }
   585  
   586  // searchIndexableWithPathPrefixes recursively searches for a value for path in source map/slice.
   587  //
   588  // While searchMap() considers each path element as a single map key or slice index, this
   589  // function searches for, and prioritizes, merged path elements.
   590  // e.g., if in the source, "foo" is defined with a sub-key "bar", and "foo.bar"
   591  // is also defined, this latter value is returned for path ["foo", "bar"].
   592  //
   593  // This should be useful only at config level (other maps may not contain dots
   594  // in their keys).
   595  //
   596  // Note: This assumes that the path entries and map keys are lower cased.
   597  func (v *Viper) searchIndexableWithPathPrefixes(source interface{}, path []string) interface{} {
   598  	if len(path) == 0 {
   599  		return source
   600  	}
   601  
   602  	// search for path prefixes, starting from the longest one
   603  	for i := len(path); i > 0; i-- {
   604  		prefixKey := strings.ToLower(strings.Join(path[0:i], v.keyDelim))
   605  
   606  		var val interface{}
   607  		switch sourceIndexable := source.(type) {
   608  		case []interface{}:
   609  			val = v.searchSliceWithPathPrefixes(sourceIndexable, prefixKey, i, path)
   610  		case map[string]interface{}:
   611  			val = v.searchMapWithPathPrefixes(sourceIndexable, prefixKey, i, path)
   612  		}
   613  		if val != nil {
   614  			return val
   615  		}
   616  	}
   617  
   618  	// not found
   619  	return nil
   620  }
   621  
   622  // searchSliceWithPathPrefixes searches for a value for path in sourceSlice
   623  //
   624  // This function is part of the searchIndexableWithPathPrefixes recurring search and
   625  // should not be called directly from functions other than searchIndexableWithPathPrefixes.
   626  func (v *Viper) searchSliceWithPathPrefixes(
   627  	sourceSlice []interface{},
   628  	prefixKey string,
   629  	pathIndex int,
   630  	path []string,
   631  ) interface{} {
   632  	// if the prefixKey is not a number or it is out of bounds of the slice
   633  	index, err := strconv.Atoi(prefixKey)
   634  	if err != nil || len(sourceSlice) <= index {
   635  		return nil
   636  	}
   637  
   638  	next := sourceSlice[index]
   639  
   640  	// Fast path
   641  	if pathIndex == len(path) {
   642  		return next
   643  	}
   644  
   645  	switch n := next.(type) {
   646  	case map[interface{}]interface{}:
   647  		return v.searchIndexableWithPathPrefixes(cast.ToStringMap(n), path[pathIndex:])
   648  	case map[string]interface{}, []interface{}:
   649  		return v.searchIndexableWithPathPrefixes(n, path[pathIndex:])
   650  	default:
   651  		// got a value but nested key expected, do nothing and look for next prefix
   652  	}
   653  
   654  	// not found
   655  	return nil
   656  }
   657  
   658  // searchMapWithPathPrefixes searches for a value for path in sourceMap
   659  //
   660  // This function is part of the searchIndexableWithPathPrefixes recurring search and
   661  // should not be called directly from functions other than searchIndexableWithPathPrefixes.
   662  func (v *Viper) searchMapWithPathPrefixes(
   663  	sourceMap map[string]interface{},
   664  	prefixKey string,
   665  	pathIndex int,
   666  	path []string,
   667  ) interface{} {
   668  	next, ok := sourceMap[prefixKey]
   669  	if !ok {
   670  		return nil
   671  	}
   672  
   673  	// Fast path
   674  	if pathIndex == len(path) {
   675  		return next
   676  	}
   677  
   678  	// Nested case
   679  	switch n := next.(type) {
   680  	case map[interface{}]interface{}:
   681  		return v.searchIndexableWithPathPrefixes(cast.ToStringMap(n), path[pathIndex:])
   682  	case map[string]interface{}, []interface{}:
   683  		return v.searchIndexableWithPathPrefixes(n, path[pathIndex:])
   684  	default:
   685  		// got a value but nested key expected, do nothing and look for next prefix
   686  	}
   687  
   688  	// not found
   689  	return nil
   690  }
   691  
   692  // isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere
   693  // on its path in the map.
   694  // e.g., if "foo.bar" has a value in the given map, it “shadows”
   695  //       "foo.bar.baz" in a lower-priority map
   696  func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string {
   697  	var parentVal interface{}
   698  	for i := 1; i < len(path); i++ {
   699  		parentVal = v.searchMap(m, path[0:i])
   700  		if parentVal == nil {
   701  			// not found, no need to add more path elements
   702  			return ""
   703  		}
   704  		switch parentVal.(type) {
   705  		case map[interface{}]interface{}:
   706  			continue
   707  		case map[string]interface{}:
   708  			continue
   709  		default:
   710  			// parentVal is a regular value which shadows "path"
   711  			return strings.Join(path[0:i], v.keyDelim)
   712  		}
   713  	}
   714  	return ""
   715  }
   716  
   717  // isPathShadowedInFlatMap makes sure the given path is not shadowed somewhere
   718  // in a sub-path of the map.
   719  // e.g., if "foo.bar" has a value in the given map, it “shadows”
   720  //       "foo.bar.baz" in a lower-priority map
   721  func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
   722  	// unify input map
   723  	var m map[string]interface{}
   724  	switch mi.(type) {
   725  	case map[string]string, map[string]FlagValue:
   726  		m = cast.ToStringMap(mi)
   727  	default:
   728  		return ""
   729  	}
   730  
   731  	// scan paths
   732  	var parentKey string
   733  	for i := 1; i < len(path); i++ {
   734  		parentKey = strings.Join(path[0:i], v.keyDelim)
   735  		if _, ok := m[parentKey]; ok {
   736  			return parentKey
   737  		}
   738  	}
   739  	return ""
   740  }
   741  
   742  // isPathShadowedInAutoEnv makes sure the given path is not shadowed somewhere
   743  // in the environment, when automatic env is on.
   744  // e.g., if "foo.bar" has a value in the environment, it “shadows”
   745  //       "foo.bar.baz" in a lower-priority map
   746  func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
   747  	var parentKey string
   748  	for i := 1; i < len(path); i++ {
   749  		parentKey = strings.Join(path[0:i], v.keyDelim)
   750  		if _, ok := v.getEnv(v.mergeWithEnvPrefix(parentKey)); ok {
   751  			return parentKey
   752  		}
   753  	}
   754  	return ""
   755  }
   756  
   757  // SetTypeByDefaultValue enables or disables the inference of a key value's
   758  // type when the Get function is used based upon a key's default value as
   759  // opposed to the value returned based on the normal fetch logic.
   760  //
   761  // For example, if a key has a default value of []string{} and the same key
   762  // is set via an environment variable to "a b c", a call to the Get function
   763  // would return a string slice for the key if the key's type is inferred by
   764  // the default value and the Get function would return:
   765  //
   766  //   []string {"a", "b", "c"}
   767  //
   768  // Otherwise the Get function would return:
   769  //
   770  //   "a b c"
   771  func SetTypeByDefaultValue(enable bool) { v.SetTypeByDefaultValue(enable) }
   772  
   773  func (v *Viper) SetTypeByDefaultValue(enable bool) {
   774  	v.typeByDefValue = enable
   775  }
   776  
   777  // GetViper gets the global Viper instance.
   778  func GetViper() *Viper {
   779  	return v
   780  }
   781  
   782  // Get can retrieve any value given the key to use.
   783  // Get is case-insensitive for a key.
   784  // Get has the behavior of returning the value associated with the first
   785  // place from where it is set. Viper will check in the following order:
   786  // override, flag, env, config file, key/value store, default
   787  //
   788  // Get returns an interface. For a specific value use one of the Get____ methods.
   789  func Get(key string) interface{} { return v.Get(key) }
   790  
   791  func (v *Viper) Get(key string) interface{} {
   792  	lcaseKey := strings.ToLower(key)
   793  	val := v.find(lcaseKey, true)
   794  	if val == nil {
   795  		return nil
   796  	}
   797  
   798  	if v.typeByDefValue {
   799  		// TODO(bep) this branch isn't covered by a single test.
   800  		valType := val
   801  		path := strings.Split(lcaseKey, v.keyDelim)
   802  		defVal := v.searchMap(v.defaults, path)
   803  		if defVal != nil {
   804  			valType = defVal
   805  		}
   806  
   807  		switch valType.(type) {
   808  		case bool:
   809  			return cast.ToBool(val)
   810  		case string:
   811  			return cast.ToString(val)
   812  		case int32, int16, int8, int:
   813  			return cast.ToInt(val)
   814  		case uint:
   815  			return cast.ToUint(val)
   816  		case uint32:
   817  			return cast.ToUint32(val)
   818  		case uint64:
   819  			return cast.ToUint64(val)
   820  		case int64:
   821  			return cast.ToInt64(val)
   822  		case float64, float32:
   823  			return cast.ToFloat64(val)
   824  		case time.Time:
   825  			return cast.ToTime(val)
   826  		case time.Duration:
   827  			return cast.ToDuration(val)
   828  		case []string:
   829  			return cast.ToStringSlice(val)
   830  		case []int:
   831  			return cast.ToIntSlice(val)
   832  		}
   833  	}
   834  
   835  	return val
   836  }
   837  
   838  // Sub returns new Viper instance representing a sub tree of this instance.
   839  // Sub is case-insensitive for a key.
   840  func Sub(key string) *Viper { return v.Sub(key) }
   841  
   842  func (v *Viper) Sub(key string) *Viper {
   843  	subv := New()
   844  	data := v.Get(key)
   845  	if data == nil {
   846  		return nil
   847  	}
   848  
   849  	if reflect.TypeOf(data).Kind() == reflect.Map {
   850  		subv.config = cast.ToStringMap(data)
   851  		return subv
   852  	}
   853  	return nil
   854  }
   855  
   856  // GetString returns the value associated with the key as a string.
   857  func GetString(key string) string { return v.GetString(key) }
   858  
   859  func (v *Viper) GetString(key string) string {
   860  	return cast.ToString(v.Get(key))
   861  }
   862  
   863  // GetBool returns the value associated with the key as a boolean.
   864  func GetBool(key string) bool { return v.GetBool(key) }
   865  
   866  func (v *Viper) GetBool(key string) bool {
   867  	return cast.ToBool(v.Get(key))
   868  }
   869  
   870  // GetInt returns the value associated with the key as an integer.
   871  func GetInt(key string) int { return v.GetInt(key) }
   872  
   873  func (v *Viper) GetInt(key string) int {
   874  	return cast.ToInt(v.Get(key))
   875  }
   876  
   877  // GetInt32 returns the value associated with the key as an integer.
   878  func GetInt32(key string) int32 { return v.GetInt32(key) }
   879  
   880  func (v *Viper) GetInt32(key string) int32 {
   881  	return cast.ToInt32(v.Get(key))
   882  }
   883  
   884  // GetInt64 returns the value associated with the key as an integer.
   885  func GetInt64(key string) int64 { return v.GetInt64(key) }
   886  
   887  func (v *Viper) GetInt64(key string) int64 {
   888  	return cast.ToInt64(v.Get(key))
   889  }
   890  
   891  // GetUint returns the value associated with the key as an unsigned integer.
   892  func GetUint(key string) uint { return v.GetUint(key) }
   893  
   894  func (v *Viper) GetUint(key string) uint {
   895  	return cast.ToUint(v.Get(key))
   896  }
   897  
   898  // GetUint32 returns the value associated with the key as an unsigned integer.
   899  func GetUint32(key string) uint32 { return v.GetUint32(key) }
   900  
   901  func (v *Viper) GetUint32(key string) uint32 {
   902  	return cast.ToUint32(v.Get(key))
   903  }
   904  
   905  // GetUint64 returns the value associated with the key as an unsigned integer.
   906  func GetUint64(key string) uint64 { return v.GetUint64(key) }
   907  
   908  func (v *Viper) GetUint64(key string) uint64 {
   909  	return cast.ToUint64(v.Get(key))
   910  }
   911  
   912  // GetFloat64 returns the value associated with the key as a float64.
   913  func GetFloat64(key string) float64 { return v.GetFloat64(key) }
   914  
   915  func (v *Viper) GetFloat64(key string) float64 {
   916  	return cast.ToFloat64(v.Get(key))
   917  }
   918  
   919  // GetTime returns the value associated with the key as time.
   920  func GetTime(key string) time.Time { return v.GetTime(key) }
   921  
   922  func (v *Viper) GetTime(key string) time.Time {
   923  	return cast.ToTime(v.Get(key))
   924  }
   925  
   926  // GetDuration returns the value associated with the key as a duration.
   927  func GetDuration(key string) time.Duration { return v.GetDuration(key) }
   928  
   929  func (v *Viper) GetDuration(key string) time.Duration {
   930  	return cast.ToDuration(v.Get(key))
   931  }
   932  
   933  // GetIntSlice returns the value associated with the key as a slice of int values.
   934  func GetIntSlice(key string) []int { return v.GetIntSlice(key) }
   935  
   936  func (v *Viper) GetIntSlice(key string) []int {
   937  	return cast.ToIntSlice(v.Get(key))
   938  }
   939  
   940  // GetStringSlice returns the value associated with the key as a slice of strings.
   941  func GetStringSlice(key string) []string { return v.GetStringSlice(key) }
   942  
   943  func (v *Viper) GetStringSlice(key string) []string {
   944  	return cast.ToStringSlice(v.Get(key))
   945  }
   946  
   947  // GetStringMap returns the value associated with the key as a map of interfaces.
   948  func GetStringMap(key string) map[string]interface{} { return v.GetStringMap(key) }
   949  
   950  func (v *Viper) GetStringMap(key string) map[string]interface{} {
   951  	return cast.ToStringMap(v.Get(key))
   952  }
   953  
   954  // GetStringMapString returns the value associated with the key as a map of strings.
   955  func GetStringMapString(key string) map[string]string { return v.GetStringMapString(key) }
   956  
   957  func (v *Viper) GetStringMapString(key string) map[string]string {
   958  	return cast.ToStringMapString(v.Get(key))
   959  }
   960  
   961  // GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
   962  func GetStringMapStringSlice(key string) map[string][]string { return v.GetStringMapStringSlice(key) }
   963  
   964  func (v *Viper) GetStringMapStringSlice(key string) map[string][]string {
   965  	return cast.ToStringMapStringSlice(v.Get(key))
   966  }
   967  
   968  // GetSizeInBytes returns the size of the value associated with the given key
   969  // in bytes.
   970  func GetSizeInBytes(key string) uint { return v.GetSizeInBytes(key) }
   971  
   972  func (v *Viper) GetSizeInBytes(key string) uint {
   973  	sizeStr := cast.ToString(v.Get(key))
   974  	return parseSizeInBytes(sizeStr)
   975  }
   976  
   977  // UnmarshalKey takes a single key and unmarshals it into a Struct.
   978  func UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error {
   979  	return v.UnmarshalKey(key, rawVal, opts...)
   980  }
   981  
   982  func (v *Viper) UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error {
   983  	return decode(v.Get(key), defaultDecoderConfig(rawVal, opts...))
   984  }
   985  
   986  // Unmarshal unmarshals the config into a Struct. Make sure that the tags
   987  // on the fields of the structure are properly set.
   988  func Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error {
   989  	return v.Unmarshal(rawVal, opts...)
   990  }
   991  
   992  func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error {
   993  	return decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...))
   994  }
   995  
   996  // defaultDecoderConfig returns default mapsstructure.DecoderConfig with suppot
   997  // of time.Duration values & string slices
   998  func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *mapstructure.DecoderConfig {
   999  	c := &mapstructure.DecoderConfig{
  1000  		Metadata:         nil,
  1001  		Result:           output,
  1002  		WeaklyTypedInput: true,
  1003  		DecodeHook: mapstructure.ComposeDecodeHookFunc(
  1004  			mapstructure.StringToTimeDurationHookFunc(),
  1005  			mapstructure.StringToSliceHookFunc(","),
  1006  		),
  1007  	}
  1008  	for _, opt := range opts {
  1009  		opt(c)
  1010  	}
  1011  	return c
  1012  }
  1013  
  1014  // A wrapper around mapstructure.Decode that mimics the WeakDecode functionality
  1015  func decode(input interface{}, config *mapstructure.DecoderConfig) error {
  1016  	decoder, err := mapstructure.NewDecoder(config)
  1017  	if err != nil {
  1018  		return err
  1019  	}
  1020  	return decoder.Decode(input)
  1021  }
  1022  
  1023  // UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent
  1024  // in the destination struct.
  1025  func UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error {
  1026  	return v.UnmarshalExact(rawVal, opts...)
  1027  }
  1028  
  1029  func (v *Viper) UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error {
  1030  	config := defaultDecoderConfig(rawVal, opts...)
  1031  	config.ErrorUnused = true
  1032  
  1033  	return decode(v.AllSettings(), config)
  1034  }
  1035  
  1036  // BindPFlags binds a full flag set to the configuration, using each flag's long
  1037  // name as the config key.
  1038  func BindPFlags(flags *pflag.FlagSet) error { return v.BindPFlags(flags) }
  1039  
  1040  func (v *Viper) BindPFlags(flags *pflag.FlagSet) error {
  1041  	return v.BindFlagValues(pflagValueSet{flags})
  1042  }
  1043  
  1044  // BindPFlag binds a specific key to a pflag (as used by cobra).
  1045  // Example (where serverCmd is a Cobra instance):
  1046  //
  1047  //	 serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
  1048  //	 Viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
  1049  //
  1050  func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) }
  1051  
  1052  func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error {
  1053  	if flag == nil {
  1054  		return fmt.Errorf("flag for %q is nil", key)
  1055  	}
  1056  	return v.BindFlagValue(key, pflagValue{flag})
  1057  }
  1058  
  1059  // BindFlagValues binds a full FlagValue set to the configuration, using each flag's long
  1060  // name as the config key.
  1061  func BindFlagValues(flags FlagValueSet) error { return v.BindFlagValues(flags) }
  1062  
  1063  func (v *Viper) BindFlagValues(flags FlagValueSet) (err error) {
  1064  	flags.VisitAll(func(flag FlagValue) {
  1065  		if err = v.BindFlagValue(flag.Name(), flag); err != nil {
  1066  			return
  1067  		}
  1068  	})
  1069  	return nil
  1070  }
  1071  
  1072  // BindFlagValue binds a specific key to a FlagValue.
  1073  func BindFlagValue(key string, flag FlagValue) error { return v.BindFlagValue(key, flag) }
  1074  
  1075  func (v *Viper) BindFlagValue(key string, flag FlagValue) error {
  1076  	if flag == nil {
  1077  		return fmt.Errorf("flag for %q is nil", key)
  1078  	}
  1079  	v.pflags[strings.ToLower(key)] = flag
  1080  	return nil
  1081  }
  1082  
  1083  // BindEnv binds a Viper key to a ENV variable.
  1084  // ENV variables are case sensitive.
  1085  // If only a key is provided, it will use the env key matching the key, uppercased.
  1086  // If more arguments are provided, they will represent the env variable names that
  1087  // should bind to this key and will be taken in the specified order.
  1088  // EnvPrefix will be used when set when env name is not provided.
  1089  func BindEnv(input ...string) error { return v.BindEnv(input...) }
  1090  
  1091  func (v *Viper) BindEnv(input ...string) error {
  1092  	if len(input) == 0 {
  1093  		return fmt.Errorf("missing key to bind to")
  1094  	}
  1095  
  1096  	key := strings.ToLower(input[0])
  1097  
  1098  	if len(input) == 1 {
  1099  		v.env[key] = append(v.env[key], v.mergeWithEnvPrefix(key))
  1100  	} else {
  1101  		v.env[key] = append(v.env[key], input[1:]...)
  1102  	}
  1103  
  1104  	return nil
  1105  }
  1106  
  1107  // Given a key, find the value.
  1108  //
  1109  // Viper will check to see if an alias exists first.
  1110  // Viper will then check in the following order:
  1111  // flag, env, config file, key/value store.
  1112  // Lastly, if no value was found and flagDefault is true, and if the key
  1113  // corresponds to a flag, the flag's default value is returned.
  1114  //
  1115  // Note: this assumes a lower-cased key given.
  1116  func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} {
  1117  	var (
  1118  		val    interface{}
  1119  		exists bool
  1120  		path   = strings.Split(lcaseKey, v.keyDelim)
  1121  		nested = len(path) > 1
  1122  	)
  1123  
  1124  	// compute the path through the nested maps to the nested value
  1125  	if nested && v.isPathShadowedInDeepMap(path, castMapStringToMapInterface(v.aliases)) != "" {
  1126  		return nil
  1127  	}
  1128  
  1129  	// if the requested key is an alias, then return the proper key
  1130  	lcaseKey = v.realKey(lcaseKey)
  1131  	path = strings.Split(lcaseKey, v.keyDelim)
  1132  	nested = len(path) > 1
  1133  
  1134  	// Set() override first
  1135  	val = v.searchMap(v.override, path)
  1136  	if val != nil {
  1137  		return val
  1138  	}
  1139  	if nested && v.isPathShadowedInDeepMap(path, v.override) != "" {
  1140  		return nil
  1141  	}
  1142  
  1143  	// PFlag override next
  1144  	flag, exists := v.pflags[lcaseKey]
  1145  	if exists && flag.HasChanged() {
  1146  		switch flag.ValueType() {
  1147  		case "int", "int8", "int16", "int32", "int64":
  1148  			return cast.ToInt(flag.ValueString())
  1149  		case "bool":
  1150  			return cast.ToBool(flag.ValueString())
  1151  		case "stringSlice":
  1152  			s := strings.TrimPrefix(flag.ValueString(), "[")
  1153  			s = strings.TrimSuffix(s, "]")
  1154  			res, _ := readAsCSV(s)
  1155  			return res
  1156  		case "intSlice":
  1157  			s := strings.TrimPrefix(flag.ValueString(), "[")
  1158  			s = strings.TrimSuffix(s, "]")
  1159  			res, _ := readAsCSV(s)
  1160  			return cast.ToIntSlice(res)
  1161  		case "stringToString":
  1162  			return stringToStringConv(flag.ValueString())
  1163  		default:
  1164  			return flag.ValueString()
  1165  		}
  1166  	}
  1167  	if nested && v.isPathShadowedInFlatMap(path, v.pflags) != "" {
  1168  		return nil
  1169  	}
  1170  
  1171  	// Env override next
  1172  	if v.automaticEnvApplied {
  1173  		// even if it hasn't been registered, if automaticEnv is used,
  1174  		// check any Get request
  1175  		if val, ok := v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); ok {
  1176  			return val
  1177  		}
  1178  		if nested && v.isPathShadowedInAutoEnv(path) != "" {
  1179  			return nil
  1180  		}
  1181  	}
  1182  	envkeys, exists := v.env[lcaseKey]
  1183  	if exists {
  1184  		for _, envkey := range envkeys {
  1185  			if val, ok := v.getEnv(envkey); ok {
  1186  				return val
  1187  			}
  1188  		}
  1189  	}
  1190  	if nested && v.isPathShadowedInFlatMap(path, v.env) != "" {
  1191  		return nil
  1192  	}
  1193  
  1194  	// Config file next
  1195  	val = v.searchIndexableWithPathPrefixes(v.config, path)
  1196  	if val != nil {
  1197  		return val
  1198  	}
  1199  	if nested && v.isPathShadowedInDeepMap(path, v.config) != "" {
  1200  		return nil
  1201  	}
  1202  
  1203  	// K/V store next
  1204  	val = v.searchMap(v.kvstore, path)
  1205  	if val != nil {
  1206  		return val
  1207  	}
  1208  	if nested && v.isPathShadowedInDeepMap(path, v.kvstore) != "" {
  1209  		return nil
  1210  	}
  1211  
  1212  	// Default next
  1213  	val = v.searchMap(v.defaults, path)
  1214  	if val != nil {
  1215  		return val
  1216  	}
  1217  	if nested && v.isPathShadowedInDeepMap(path, v.defaults) != "" {
  1218  		return nil
  1219  	}
  1220  
  1221  	if flagDefault {
  1222  		// last chance: if no value is found and a flag does exist for the key,
  1223  		// get the flag's default value even if the flag's value has not been set.
  1224  		if flag, exists := v.pflags[lcaseKey]; exists {
  1225  			switch flag.ValueType() {
  1226  			case "int", "int8", "int16", "int32", "int64":
  1227  				return cast.ToInt(flag.ValueString())
  1228  			case "bool":
  1229  				return cast.ToBool(flag.ValueString())
  1230  			case "stringSlice":
  1231  				s := strings.TrimPrefix(flag.ValueString(), "[")
  1232  				s = strings.TrimSuffix(s, "]")
  1233  				res, _ := readAsCSV(s)
  1234  				return res
  1235  			case "intSlice":
  1236  				s := strings.TrimPrefix(flag.ValueString(), "[")
  1237  				s = strings.TrimSuffix(s, "]")
  1238  				res, _ := readAsCSV(s)
  1239  				return cast.ToIntSlice(res)
  1240  			case "stringToString":
  1241  				return stringToStringConv(flag.ValueString())
  1242  			default:
  1243  				return flag.ValueString()
  1244  			}
  1245  		}
  1246  		// last item, no need to check shadowing
  1247  	}
  1248  
  1249  	return nil
  1250  }
  1251  
  1252  func readAsCSV(val string) ([]string, error) {
  1253  	if val == "" {
  1254  		return []string{}, nil
  1255  	}
  1256  	stringReader := strings.NewReader(val)
  1257  	csvReader := csv.NewReader(stringReader)
  1258  	return csvReader.Read()
  1259  }
  1260  
  1261  // mostly copied from pflag's implementation of this operation here https://github.com/spf13/pflag/blob/master/string_to_string.go#L79
  1262  // alterations are: errors are swallowed, map[string]interface{} is returned in order to enable cast.ToStringMap
  1263  func stringToStringConv(val string) interface{} {
  1264  	val = strings.Trim(val, "[]")
  1265  	// An empty string would cause an empty map
  1266  	if len(val) == 0 {
  1267  		return map[string]interface{}{}
  1268  	}
  1269  	r := csv.NewReader(strings.NewReader(val))
  1270  	ss, err := r.Read()
  1271  	if err != nil {
  1272  		return nil
  1273  	}
  1274  	out := make(map[string]interface{}, len(ss))
  1275  	for _, pair := range ss {
  1276  		kv := strings.SplitN(pair, "=", 2)
  1277  		if len(kv) != 2 {
  1278  			return nil
  1279  		}
  1280  		out[kv[0]] = kv[1]
  1281  	}
  1282  	return out
  1283  }
  1284  
  1285  // IsSet checks to see if the key has been set in any of the data locations.
  1286  // IsSet is case-insensitive for a key.
  1287  func IsSet(key string) bool { return v.IsSet(key) }
  1288  
  1289  func (v *Viper) IsSet(key string) bool {
  1290  	lcaseKey := strings.ToLower(key)
  1291  	val := v.find(lcaseKey, false)
  1292  	return val != nil
  1293  }
  1294  
  1295  // AutomaticEnv makes Viper check if environment variables match any of the existing keys
  1296  // (config, default or flags). If matching env vars are found, they are loaded into Viper.
  1297  func AutomaticEnv() { v.AutomaticEnv() }
  1298  
  1299  func (v *Viper) AutomaticEnv() {
  1300  	v.automaticEnvApplied = true
  1301  }
  1302  
  1303  // SetEnvKeyReplacer sets the strings.Replacer on the viper object
  1304  // Useful for mapping an environmental variable to a key that does
  1305  // not match it.
  1306  func SetEnvKeyReplacer(r *strings.Replacer) { v.SetEnvKeyReplacer(r) }
  1307  
  1308  func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) {
  1309  	v.envKeyReplacer = r
  1310  }
  1311  
  1312  // RegisterAlias creates an alias that provides another accessor for the same key.
  1313  // This enables one to change a name without breaking the application.
  1314  func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) }
  1315  
  1316  func (v *Viper) RegisterAlias(alias string, key string) {
  1317  	v.registerAlias(alias, strings.ToLower(key))
  1318  }
  1319  
  1320  func (v *Viper) registerAlias(alias string, key string) {
  1321  	alias = strings.ToLower(alias)
  1322  	if alias != key && alias != v.realKey(key) {
  1323  		_, exists := v.aliases[alias]
  1324  
  1325  		if !exists {
  1326  			// if we alias something that exists in one of the maps to another
  1327  			// name, we'll never be able to get that value using the original
  1328  			// name, so move the config value to the new realkey.
  1329  			if val, ok := v.config[alias]; ok {
  1330  				delete(v.config, alias)
  1331  				v.config[key] = val
  1332  			}
  1333  			if val, ok := v.kvstore[alias]; ok {
  1334  				delete(v.kvstore, alias)
  1335  				v.kvstore[key] = val
  1336  			}
  1337  			if val, ok := v.defaults[alias]; ok {
  1338  				delete(v.defaults, alias)
  1339  				v.defaults[key] = val
  1340  			}
  1341  			if val, ok := v.override[alias]; ok {
  1342  				delete(v.override, alias)
  1343  				v.override[key] = val
  1344  			}
  1345  			v.aliases[alias] = key
  1346  		}
  1347  	} else {
  1348  		jww.WARN.Println("Creating circular reference alias", alias, key, v.realKey(key))
  1349  	}
  1350  }
  1351  
  1352  func (v *Viper) realKey(key string) string {
  1353  	newkey, exists := v.aliases[key]
  1354  	if exists {
  1355  		jww.DEBUG.Println("Alias", key, "to", newkey)
  1356  		return v.realKey(newkey)
  1357  	}
  1358  	return key
  1359  }
  1360  
  1361  // InConfig checks to see if the given key (or an alias) is in the config file.
  1362  func InConfig(key string) bool { return v.InConfig(key) }
  1363  
  1364  func (v *Viper) InConfig(key string) bool {
  1365  	// if the requested key is an alias, then return the proper key
  1366  	key = v.realKey(key)
  1367  
  1368  	_, exists := v.config[key]
  1369  	return exists
  1370  }
  1371  
  1372  // SetDefault sets the default value for this key.
  1373  // SetDefault is case-insensitive for a key.
  1374  // Default only used when no value is provided by the user via flag, config or ENV.
  1375  func SetDefault(key string, value interface{}) { v.SetDefault(key, value) }
  1376  
  1377  func (v *Viper) SetDefault(key string, value interface{}) {
  1378  	// If alias passed in, then set the proper default
  1379  	key = v.realKey(strings.ToLower(key))
  1380  	value = toCaseInsensitiveValue(value)
  1381  
  1382  	path := strings.Split(key, v.keyDelim)
  1383  	lastKey := strings.ToLower(path[len(path)-1])
  1384  	deepestMap := deepSearch(v.defaults, path[0:len(path)-1])
  1385  
  1386  	// set innermost value
  1387  	deepestMap[lastKey] = value
  1388  }
  1389  
  1390  // Set sets the value for the key in the override register.
  1391  // Set is case-insensitive for a key.
  1392  // Will be used instead of values obtained via
  1393  // flags, config file, ENV, default, or key/value store.
  1394  func Set(key string, value interface{}) { v.Set(key, value) }
  1395  
  1396  func (v *Viper) Set(key string, value interface{}) {
  1397  	// If alias passed in, then set the proper override
  1398  	key = v.realKey(strings.ToLower(key))
  1399  	value = toCaseInsensitiveValue(value)
  1400  
  1401  	path := strings.Split(key, v.keyDelim)
  1402  	lastKey := strings.ToLower(path[len(path)-1])
  1403  	deepestMap := deepSearch(v.override, path[0:len(path)-1])
  1404  
  1405  	// set innermost value
  1406  	deepestMap[lastKey] = value
  1407  }
  1408  
  1409  // ReadInConfig will discover and load the configuration file from disk
  1410  // and key/value stores, searching in one of the defined paths.
  1411  func ReadInConfig() error { return v.ReadInConfig() }
  1412  
  1413  func (v *Viper) ReadInConfig() error {
  1414  	jww.INFO.Println("Attempting to read in config file")
  1415  	filename, err := v.getConfigFile()
  1416  	if err != nil {
  1417  		return err
  1418  	}
  1419  
  1420  	if !stringInSlice(v.getConfigType(), SupportedExts) {
  1421  		return UnsupportedConfigError(v.getConfigType())
  1422  	}
  1423  
  1424  	jww.DEBUG.Println("Reading file: ", filename)
  1425  	file, err := afero.ReadFile(v.fs, filename)
  1426  	if err != nil {
  1427  		return err
  1428  	}
  1429  
  1430  	config := make(map[string]interface{})
  1431  
  1432  	err = v.unmarshalReader(bytes.NewReader(file), config)
  1433  	if err != nil {
  1434  		return err
  1435  	}
  1436  
  1437  	v.config = config
  1438  	return nil
  1439  }
  1440  
  1441  // MergeInConfig merges a new configuration with an existing config.
  1442  func MergeInConfig() error { return v.MergeInConfig() }
  1443  
  1444  func (v *Viper) MergeInConfig() error {
  1445  	jww.INFO.Println("Attempting to merge in config file")
  1446  	filename, err := v.getConfigFile()
  1447  	if err != nil {
  1448  		return err
  1449  	}
  1450  
  1451  	if !stringInSlice(v.getConfigType(), SupportedExts) {
  1452  		return UnsupportedConfigError(v.getConfigType())
  1453  	}
  1454  
  1455  	file, err := afero.ReadFile(v.fs, filename)
  1456  	if err != nil {
  1457  		return err
  1458  	}
  1459  
  1460  	return v.MergeConfig(bytes.NewReader(file))
  1461  }
  1462  
  1463  // ReadConfig will read a configuration file, setting existing keys to nil if the
  1464  // key does not exist in the file.
  1465  func ReadConfig(in io.Reader) error { return v.ReadConfig(in) }
  1466  
  1467  func (v *Viper) ReadConfig(in io.Reader) error {
  1468  	v.config = make(map[string]interface{})
  1469  	return v.unmarshalReader(in, v.config)
  1470  }
  1471  
  1472  // MergeConfig merges a new configuration with an existing config.
  1473  func MergeConfig(in io.Reader) error { return v.MergeConfig(in) }
  1474  
  1475  func (v *Viper) MergeConfig(in io.Reader) error {
  1476  	cfg := make(map[string]interface{})
  1477  	if err := v.unmarshalReader(in, cfg); err != nil {
  1478  		return err
  1479  	}
  1480  	return v.MergeConfigMap(cfg)
  1481  }
  1482  
  1483  // MergeConfigMap merges the configuration from the map given with an existing config.
  1484  // Note that the map given may be modified.
  1485  func MergeConfigMap(cfg map[string]interface{}) error { return v.MergeConfigMap(cfg) }
  1486  
  1487  func (v *Viper) MergeConfigMap(cfg map[string]interface{}) error {
  1488  	if v.config == nil {
  1489  		v.config = make(map[string]interface{})
  1490  	}
  1491  	insensitiviseMap(cfg)
  1492  	mergeMaps(cfg, v.config, nil)
  1493  	return nil
  1494  }
  1495  
  1496  // WriteConfig writes the current configuration to a file.
  1497  func WriteConfig() error { return v.WriteConfig() }
  1498  
  1499  func (v *Viper) WriteConfig() error {
  1500  	filename, err := v.getConfigFile()
  1501  	if err != nil {
  1502  		return err
  1503  	}
  1504  	return v.writeConfig(filename, true)
  1505  }
  1506  
  1507  // SafeWriteConfig writes current configuration to file only if the file does not exist.
  1508  func SafeWriteConfig() error { return v.SafeWriteConfig() }
  1509  
  1510  func (v *Viper) SafeWriteConfig() error {
  1511  	if len(v.configPaths) < 1 {
  1512  		return errors.New("missing configuration for 'configPath'")
  1513  	}
  1514  	return v.SafeWriteConfigAs(filepath.Join(v.configPaths[0], v.configName+"."+v.configType))
  1515  }
  1516  
  1517  // WriteConfigAs writes current configuration to a given filename.
  1518  func WriteConfigAs(filename string) error { return v.WriteConfigAs(filename) }
  1519  
  1520  func (v *Viper) WriteConfigAs(filename string) error {
  1521  	return v.writeConfig(filename, true)
  1522  }
  1523  
  1524  // SafeWriteConfigAs writes current configuration to a given filename if it does not exist.
  1525  func SafeWriteConfigAs(filename string) error { return v.SafeWriteConfigAs(filename) }
  1526  
  1527  func (v *Viper) SafeWriteConfigAs(filename string) error {
  1528  	alreadyExists, err := afero.Exists(v.fs, filename)
  1529  	if alreadyExists && err == nil {
  1530  		return ConfigFileAlreadyExistsError(filename)
  1531  	}
  1532  	return v.writeConfig(filename, false)
  1533  }
  1534  
  1535  func (v *Viper) writeConfig(filename string, force bool) error {
  1536  	jww.INFO.Println("Attempting to write configuration to file.")
  1537  	var configType string
  1538  
  1539  	ext := filepath.Ext(filename)
  1540  	if ext != "" {
  1541  		configType = ext[1:]
  1542  	} else {
  1543  		configType = v.configType
  1544  	}
  1545  	if configType == "" {
  1546  		return fmt.Errorf("config type could not be determined for %s", filename)
  1547  	}
  1548  
  1549  	if !stringInSlice(configType, SupportedExts) {
  1550  		return UnsupportedConfigError(configType)
  1551  	}
  1552  	if v.config == nil {
  1553  		v.config = make(map[string]interface{})
  1554  	}
  1555  	flags := os.O_CREATE | os.O_TRUNC | os.O_WRONLY
  1556  	if !force {
  1557  		flags |= os.O_EXCL
  1558  	}
  1559  	f, err := v.fs.OpenFile(filename, flags, v.configPermissions)
  1560  	if err != nil {
  1561  		return err
  1562  	}
  1563  	defer f.Close()
  1564  
  1565  	if err := v.marshalWriter(f, configType); err != nil {
  1566  		return err
  1567  	}
  1568  
  1569  	return f.Sync()
  1570  }
  1571  
  1572  // Unmarshal a Reader into a map.
  1573  // Should probably be an unexported function.
  1574  func unmarshalReader(in io.Reader, c map[string]interface{}) error {
  1575  	return v.unmarshalReader(in, c)
  1576  }
  1577  
  1578  func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error {
  1579  	buf := new(bytes.Buffer)
  1580  	buf.ReadFrom(in)
  1581  
  1582  	switch strings.ToLower(v.getConfigType()) {
  1583  	case "yaml", "yml":
  1584  		if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil {
  1585  			return ConfigParseError{err}
  1586  		}
  1587  
  1588  	case "json":
  1589  		if err := json.Unmarshal(buf.Bytes(), &c); err != nil {
  1590  			return ConfigParseError{err}
  1591  		}
  1592  
  1593  	case "hcl":
  1594  		obj, err := hcl.Parse(buf.String())
  1595  		if err != nil {
  1596  			return ConfigParseError{err}
  1597  		}
  1598  		if err = hcl.DecodeObject(&c, obj); err != nil {
  1599  			return ConfigParseError{err}
  1600  		}
  1601  
  1602  	case "toml":
  1603  		tree, err := toml.LoadReader(buf)
  1604  		if err != nil {
  1605  			return ConfigParseError{err}
  1606  		}
  1607  		tmap := tree.ToMap()
  1608  		for k, v := range tmap {
  1609  			c[k] = v
  1610  		}
  1611  
  1612  	case "dotenv", "env":
  1613  		env, err := gotenv.StrictParse(buf)
  1614  		if err != nil {
  1615  			return ConfigParseError{err}
  1616  		}
  1617  		for k, v := range env {
  1618  			c[k] = v
  1619  		}
  1620  
  1621  	case "properties", "props", "prop":
  1622  		v.properties = properties.NewProperties()
  1623  		var err error
  1624  		if v.properties, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil {
  1625  			return ConfigParseError{err}
  1626  		}
  1627  		for _, key := range v.properties.Keys() {
  1628  			value, _ := v.properties.Get(key)
  1629  			// recursively build nested maps
  1630  			path := strings.Split(key, ".")
  1631  			lastKey := strings.ToLower(path[len(path)-1])
  1632  			deepestMap := deepSearch(c, path[0:len(path)-1])
  1633  			// set innermost value
  1634  			deepestMap[lastKey] = value
  1635  		}
  1636  
  1637  	case "ini":
  1638  		cfg := ini.Empty()
  1639  		err := cfg.Append(buf.Bytes())
  1640  		if err != nil {
  1641  			return ConfigParseError{err}
  1642  		}
  1643  		sections := cfg.Sections()
  1644  		for i := 0; i < len(sections); i++ {
  1645  			section := sections[i]
  1646  			keys := section.Keys()
  1647  			for j := 0; j < len(keys); j++ {
  1648  				key := keys[j]
  1649  				value := cfg.Section(section.Name()).Key(key.Name()).String()
  1650  				c[section.Name()+"."+key.Name()] = value
  1651  			}
  1652  		}
  1653  	}
  1654  
  1655  	insensitiviseMap(c)
  1656  	return nil
  1657  }
  1658  
  1659  // Marshal a map into Writer.
  1660  func (v *Viper) marshalWriter(f afero.File, configType string) error {
  1661  	c := v.AllSettings()
  1662  	switch configType {
  1663  	case "json":
  1664  		b, err := json.MarshalIndent(c, "", "  ")
  1665  		if err != nil {
  1666  			return ConfigMarshalError{err}
  1667  		}
  1668  		_, err = f.WriteString(string(b))
  1669  		if err != nil {
  1670  			return ConfigMarshalError{err}
  1671  		}
  1672  
  1673  	case "hcl":
  1674  		b, err := json.Marshal(c)
  1675  		if err != nil {
  1676  			return ConfigMarshalError{err}
  1677  		}
  1678  		ast, err := hcl.Parse(string(b))
  1679  		if err != nil {
  1680  			return ConfigMarshalError{err}
  1681  		}
  1682  		err = printer.Fprint(f, ast.Node)
  1683  		if err != nil {
  1684  			return ConfigMarshalError{err}
  1685  		}
  1686  
  1687  	case "prop", "props", "properties":
  1688  		if v.properties == nil {
  1689  			v.properties = properties.NewProperties()
  1690  		}
  1691  		p := v.properties
  1692  		for _, key := range v.AllKeys() {
  1693  			_, _, err := p.Set(key, v.GetString(key))
  1694  			if err != nil {
  1695  				return ConfigMarshalError{err}
  1696  			}
  1697  		}
  1698  		_, err := p.WriteComment(f, "#", properties.UTF8)
  1699  		if err != nil {
  1700  			return ConfigMarshalError{err}
  1701  		}
  1702  
  1703  	case "dotenv", "env":
  1704  		lines := []string{}
  1705  		for _, key := range v.AllKeys() {
  1706  			envName := strings.ToUpper(strings.Replace(key, ".", "_", -1))
  1707  			val := v.Get(key)
  1708  			lines = append(lines, fmt.Sprintf("%v=%v", envName, val))
  1709  		}
  1710  		s := strings.Join(lines, "\n")
  1711  		if _, err := f.WriteString(s); err != nil {
  1712  			return ConfigMarshalError{err}
  1713  		}
  1714  
  1715  	case "toml":
  1716  		t, err := toml.TreeFromMap(c)
  1717  		if err != nil {
  1718  			return ConfigMarshalError{err}
  1719  		}
  1720  		s := t.String()
  1721  		if _, err := f.WriteString(s); err != nil {
  1722  			return ConfigMarshalError{err}
  1723  		}
  1724  
  1725  	case "yaml", "yml":
  1726  		b, err := yaml.Marshal(c)
  1727  		if err != nil {
  1728  			return ConfigMarshalError{err}
  1729  		}
  1730  		if _, err = f.WriteString(string(b)); err != nil {
  1731  			return ConfigMarshalError{err}
  1732  		}
  1733  
  1734  	case "ini":
  1735  		keys := v.AllKeys()
  1736  		cfg := ini.Empty()
  1737  		ini.PrettyFormat = false
  1738  		for i := 0; i < len(keys); i++ {
  1739  			key := keys[i]
  1740  			lastSep := strings.LastIndex(key, ".")
  1741  			sectionName := key[:(lastSep)]
  1742  			keyName := key[(lastSep + 1):]
  1743  			if sectionName == "default" {
  1744  				sectionName = ""
  1745  			}
  1746  			cfg.Section(sectionName).Key(keyName).SetValue(v.GetString(key))
  1747  		}
  1748  		cfg.WriteTo(f)
  1749  	}
  1750  	return nil
  1751  }
  1752  
  1753  func keyExists(k string, m map[string]interface{}) string {
  1754  	lk := strings.ToLower(k)
  1755  	for mk := range m {
  1756  		lmk := strings.ToLower(mk)
  1757  		if lmk == lk {
  1758  			return mk
  1759  		}
  1760  	}
  1761  	return ""
  1762  }
  1763  
  1764  func castToMapStringInterface(
  1765  	src map[interface{}]interface{}) map[string]interface{} {
  1766  	tgt := map[string]interface{}{}
  1767  	for k, v := range src {
  1768  		tgt[fmt.Sprintf("%v", k)] = v
  1769  	}
  1770  	return tgt
  1771  }
  1772  
  1773  func castMapStringSliceToMapInterface(src map[string][]string) map[string]interface{} {
  1774  	tgt := map[string]interface{}{}
  1775  	for k, v := range src {
  1776  		tgt[k] = v
  1777  	}
  1778  	return tgt
  1779  }
  1780  
  1781  func castMapStringToMapInterface(src map[string]string) map[string]interface{} {
  1782  	tgt := map[string]interface{}{}
  1783  	for k, v := range src {
  1784  		tgt[k] = v
  1785  	}
  1786  	return tgt
  1787  }
  1788  
  1789  func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} {
  1790  	tgt := map[string]interface{}{}
  1791  	for k, v := range src {
  1792  		tgt[k] = v
  1793  	}
  1794  	return tgt
  1795  }
  1796  
  1797  // mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's
  1798  // insistence on parsing nested structures as `map[interface{}]interface{}`
  1799  // instead of using a `string` as the key for nest structures beyond one level
  1800  // deep. Both map types are supported as there is a go-yaml fork that uses
  1801  // `map[string]interface{}` instead.
  1802  func mergeMaps(
  1803  	src, tgt map[string]interface{}, itgt map[interface{}]interface{}) {
  1804  	for sk, sv := range src {
  1805  		tk := keyExists(sk, tgt)
  1806  		if tk == "" {
  1807  			jww.TRACE.Printf("tk=\"\", tgt[%s]=%v", sk, sv)
  1808  			tgt[sk] = sv
  1809  			if itgt != nil {
  1810  				itgt[sk] = sv
  1811  			}
  1812  			continue
  1813  		}
  1814  
  1815  		tv, ok := tgt[tk]
  1816  		if !ok {
  1817  			jww.TRACE.Printf("tgt[%s] != ok, tgt[%s]=%v", tk, sk, sv)
  1818  			tgt[sk] = sv
  1819  			if itgt != nil {
  1820  				itgt[sk] = sv
  1821  			}
  1822  			continue
  1823  		}
  1824  
  1825  		svType := reflect.TypeOf(sv)
  1826  		tvType := reflect.TypeOf(tv)
  1827  		if svType != tvType {
  1828  			jww.ERROR.Printf(
  1829  				"svType != tvType; key=%s, st=%v, tt=%v, sv=%v, tv=%v",
  1830  				sk, svType, tvType, sv, tv)
  1831  			continue
  1832  		}
  1833  
  1834  		jww.TRACE.Printf("processing key=%s, st=%v, tt=%v, sv=%v, tv=%v",
  1835  			sk, svType, tvType, sv, tv)
  1836  
  1837  		switch ttv := tv.(type) {
  1838  		case map[interface{}]interface{}:
  1839  			jww.TRACE.Printf("merging maps (must convert)")
  1840  			tsv := sv.(map[interface{}]interface{})
  1841  			ssv := castToMapStringInterface(tsv)
  1842  			stv := castToMapStringInterface(ttv)
  1843  			mergeMaps(ssv, stv, ttv)
  1844  		case map[string]interface{}:
  1845  			jww.TRACE.Printf("merging maps")
  1846  			mergeMaps(sv.(map[string]interface{}), ttv, nil)
  1847  		default:
  1848  			jww.TRACE.Printf("setting value")
  1849  			tgt[tk] = sv
  1850  			if itgt != nil {
  1851  				itgt[tk] = sv
  1852  			}
  1853  		}
  1854  	}
  1855  }
  1856  
  1857  // ReadRemoteConfig attempts to get configuration from a remote source
  1858  // and read it in the remote configuration registry.
  1859  func ReadRemoteConfig() error { return v.ReadRemoteConfig() }
  1860  
  1861  func (v *Viper) ReadRemoteConfig() error {
  1862  	return v.getKeyValueConfig()
  1863  }
  1864  
  1865  func WatchRemoteConfig() error { return v.WatchRemoteConfig() }
  1866  func (v *Viper) WatchRemoteConfig() error {
  1867  	return v.watchKeyValueConfig()
  1868  }
  1869  
  1870  func (v *Viper) WatchRemoteConfigOnChannel() error {
  1871  	return v.watchKeyValueConfigOnChannel()
  1872  }
  1873  
  1874  // Retrieve the first found remote configuration.
  1875  func (v *Viper) getKeyValueConfig() error {
  1876  	if RemoteConfig == nil {
  1877  		return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ gitee.com/evanscat/viper/remote'")
  1878  	}
  1879  
  1880  	for _, rp := range v.remoteProviders {
  1881  		val, err := v.getRemoteConfig(rp)
  1882  		if err != nil {
  1883  			jww.ERROR.Printf("get remote config: %s", err)
  1884  
  1885  			continue
  1886  		}
  1887  
  1888  		v.kvstore = val
  1889  
  1890  		return nil
  1891  	}
  1892  	return RemoteConfigError("No Files Found")
  1893  }
  1894  
  1895  func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) {
  1896  	reader, err := RemoteConfig.Get(provider)
  1897  	if err != nil {
  1898  		return nil, err
  1899  	}
  1900  	err = v.unmarshalReader(reader, v.kvstore)
  1901  	return v.kvstore, err
  1902  }
  1903  
  1904  // Retrieve the first found remote configuration.
  1905  func (v *Viper) watchKeyValueConfigOnChannel() error {
  1906  	for _, rp := range v.remoteProviders {
  1907  		respc, _ := RemoteConfig.WatchChannel(rp)
  1908  		// Todo: Add quit channel
  1909  		go func(rc <-chan *RemoteResponse) {
  1910  			for {
  1911  				b := <-rc
  1912  				reader := bytes.NewReader(b.Value)
  1913  				v.unmarshalReader(reader, v.kvstore)
  1914  			}
  1915  		}(respc)
  1916  		return nil
  1917  	}
  1918  	return RemoteConfigError("No Files Found")
  1919  }
  1920  
  1921  // Retrieve the first found remote configuration.
  1922  func (v *Viper) watchKeyValueConfig() error {
  1923  	for _, rp := range v.remoteProviders {
  1924  		val, err := v.watchRemoteConfig(rp)
  1925  		if err != nil {
  1926  			continue
  1927  		}
  1928  		v.kvstore = val
  1929  		return nil
  1930  	}
  1931  	return RemoteConfigError("No Files Found")
  1932  }
  1933  
  1934  func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) {
  1935  	reader, err := RemoteConfig.Watch(provider)
  1936  	if err != nil {
  1937  		return nil, err
  1938  	}
  1939  	err = v.unmarshalReader(reader, v.kvstore)
  1940  	return v.kvstore, err
  1941  }
  1942  
  1943  // AllKeys returns all keys holding a value, regardless of where they are set.
  1944  // Nested keys are returned with a v.keyDelim separator
  1945  func AllKeys() []string { return v.AllKeys() }
  1946  
  1947  func (v *Viper) AllKeys() []string {
  1948  	m := map[string]bool{}
  1949  	// add all paths, by order of descending priority to ensure correct shadowing
  1950  	m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "")
  1951  	m = v.flattenAndMergeMap(m, v.override, "")
  1952  	m = v.mergeFlatMap(m, castMapFlagToMapInterface(v.pflags))
  1953  	m = v.mergeFlatMap(m, castMapStringSliceToMapInterface(v.env))
  1954  	m = v.flattenAndMergeMap(m, v.config, "")
  1955  	m = v.flattenAndMergeMap(m, v.kvstore, "")
  1956  	m = v.flattenAndMergeMap(m, v.defaults, "")
  1957  
  1958  	// convert set of paths to list
  1959  	a := make([]string, 0, len(m))
  1960  	for x := range m {
  1961  		a = append(a, x)
  1962  	}
  1963  	return a
  1964  }
  1965  
  1966  // flattenAndMergeMap recursively flattens the given map into a map[string]bool
  1967  // of key paths (used as a set, easier to manipulate than a []string):
  1968  // - each path is merged into a single key string, delimited with v.keyDelim
  1969  // - if a path is shadowed by an earlier value in the initial shadow map,
  1970  //   it is skipped.
  1971  // The resulting set of paths is merged to the given shadow set at the same time.
  1972  func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool {
  1973  	if shadow != nil && prefix != "" && shadow[prefix] {
  1974  		// prefix is shadowed => nothing more to flatten
  1975  		return shadow
  1976  	}
  1977  	if shadow == nil {
  1978  		shadow = make(map[string]bool)
  1979  	}
  1980  
  1981  	var m2 map[string]interface{}
  1982  	if prefix != "" {
  1983  		prefix += v.keyDelim
  1984  	}
  1985  	for k, val := range m {
  1986  		fullKey := prefix + k
  1987  		switch val.(type) {
  1988  		case map[string]interface{}:
  1989  			m2 = val.(map[string]interface{})
  1990  		case map[interface{}]interface{}:
  1991  			m2 = cast.ToStringMap(val)
  1992  		default:
  1993  			// immediate value
  1994  			shadow[strings.ToLower(fullKey)] = true
  1995  			continue
  1996  		}
  1997  		// recursively merge to shadow map
  1998  		shadow = v.flattenAndMergeMap(shadow, m2, fullKey)
  1999  	}
  2000  	return shadow
  2001  }
  2002  
  2003  // mergeFlatMap merges the given maps, excluding values of the second map
  2004  // shadowed by values from the first map.
  2005  func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool {
  2006  	// scan keys
  2007  outer:
  2008  	for k := range m {
  2009  		path := strings.Split(k, v.keyDelim)
  2010  		// scan intermediate paths
  2011  		var parentKey string
  2012  		for i := 1; i < len(path); i++ {
  2013  			parentKey = strings.Join(path[0:i], v.keyDelim)
  2014  			if shadow[parentKey] {
  2015  				// path is shadowed, continue
  2016  				continue outer
  2017  			}
  2018  		}
  2019  		// add key
  2020  		shadow[strings.ToLower(k)] = true
  2021  	}
  2022  	return shadow
  2023  }
  2024  
  2025  // AllSettings merges all settings and returns them as a map[string]interface{}.
  2026  func AllSettings() map[string]interface{} { return v.AllSettings() }
  2027  
  2028  func (v *Viper) AllSettings() map[string]interface{} {
  2029  	m := map[string]interface{}{}
  2030  	// start from the list of keys, and construct the map one value at a time
  2031  	for _, k := range v.AllKeys() {
  2032  		value := v.Get(k)
  2033  		if value == nil {
  2034  			// should not happen, since AllKeys() returns only keys holding a value,
  2035  			// check just in case anything changes
  2036  			continue
  2037  		}
  2038  		path := strings.Split(k, v.keyDelim)
  2039  		lastKey := strings.ToLower(path[len(path)-1])
  2040  		deepestMap := deepSearch(m, path[0:len(path)-1])
  2041  		// set innermost value
  2042  		deepestMap[lastKey] = value
  2043  	}
  2044  	return m
  2045  }
  2046  
  2047  // SetFs sets the filesystem to use to read configuration.
  2048  func SetFs(fs afero.Fs) { v.SetFs(fs) }
  2049  
  2050  func (v *Viper) SetFs(fs afero.Fs) {
  2051  	v.fs = fs
  2052  }
  2053  
  2054  // SetConfigName sets name for the config file.
  2055  // Does not include extension.
  2056  func SetConfigName(in string) { v.SetConfigName(in) }
  2057  
  2058  func (v *Viper) SetConfigName(in string) {
  2059  	if in != "" {
  2060  		v.configName = in
  2061  		v.configFile = ""
  2062  	}
  2063  }
  2064  
  2065  // SetConfigType sets the type of the configuration returned by the
  2066  // remote source, e.g. "json".
  2067  func SetConfigType(in string) { v.SetConfigType(in) }
  2068  
  2069  func (v *Viper) SetConfigType(in string) {
  2070  	if in != "" {
  2071  		v.configType = in
  2072  	}
  2073  }
  2074  
  2075  // SetConfigPermissions sets the permissions for the config file.
  2076  func SetConfigPermissions(perm os.FileMode) { v.SetConfigPermissions(perm) }
  2077  
  2078  func (v *Viper) SetConfigPermissions(perm os.FileMode) {
  2079  	v.configPermissions = perm.Perm()
  2080  }
  2081  
  2082  func (v *Viper) getConfigType() string {
  2083  	if v.configType != "" {
  2084  		return v.configType
  2085  	}
  2086  
  2087  	cf, err := v.getConfigFile()
  2088  	if err != nil {
  2089  		return ""
  2090  	}
  2091  
  2092  	ext := filepath.Ext(cf)
  2093  
  2094  	if len(ext) > 1 {
  2095  		return ext[1:]
  2096  	}
  2097  
  2098  	return ""
  2099  }
  2100  
  2101  func (v *Viper) getConfigFile() (string, error) {
  2102  	if v.configFile == "" {
  2103  		cf, err := v.findConfigFile()
  2104  		if err != nil {
  2105  			return "", err
  2106  		}
  2107  		v.configFile = cf
  2108  	}
  2109  	return v.configFile, nil
  2110  }
  2111  
  2112  func (v *Viper) searchInPath(in string) (filename string) {
  2113  	jww.DEBUG.Println("Searching for config in ", in)
  2114  	for _, ext := range SupportedExts {
  2115  		jww.DEBUG.Println("Checking for", filepath.Join(in, v.configName+"."+ext))
  2116  		if b, _ := exists(v.fs, filepath.Join(in, v.configName+"."+ext)); b {
  2117  			jww.DEBUG.Println("Found: ", filepath.Join(in, v.configName+"."+ext))
  2118  			return filepath.Join(in, v.configName+"."+ext)
  2119  		}
  2120  	}
  2121  
  2122  	if v.configType != "" {
  2123  		if b, _ := exists(v.fs, filepath.Join(in, v.configName)); b {
  2124  			return filepath.Join(in, v.configName)
  2125  		}
  2126  	}
  2127  
  2128  	return ""
  2129  }
  2130  
  2131  // Search all configPaths for any config file.
  2132  // Returns the first path that exists (and is a config file).
  2133  func (v *Viper) findConfigFile() (string, error) {
  2134  	jww.INFO.Println("Searching for config in ", v.configPaths)
  2135  
  2136  	for _, cp := range v.configPaths {
  2137  		file := v.searchInPath(cp)
  2138  		if file != "" {
  2139  			return file, nil
  2140  		}
  2141  	}
  2142  	return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)}
  2143  }
  2144  
  2145  // Debug prints all configuration registries for debugging
  2146  // purposes.
  2147  func Debug() { v.Debug() }
  2148  
  2149  func (v *Viper) Debug() {
  2150  	fmt.Printf("Aliases:\n%#v\n", v.aliases)
  2151  	fmt.Printf("Override:\n%#v\n", v.override)
  2152  	fmt.Printf("PFlags:\n%#v\n", v.pflags)
  2153  	fmt.Printf("Env:\n%#v\n", v.env)
  2154  	fmt.Printf("Key/Value Store:\n%#v\n", v.kvstore)
  2155  	fmt.Printf("Config:\n%#v\n", v.config)
  2156  	fmt.Printf("Defaults:\n%#v\n", v.defaults)
  2157  }