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