gitlab.dev.zniis.ru/tools/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  	"strings"
    34  	"sync"
    35  	"time"
    36  
    37  	"github.com/fsnotify/fsnotify"
    38  	"github.com/hashicorp/hcl"
    39  	"github.com/hashicorp/hcl/hcl/printer"
    40  	"github.com/magiconair/properties"
    41  	"github.com/mitchellh/mapstructure"
    42  	"github.com/pelletier/go-toml"
    43  	"github.com/spf13/afero"
    44  	"github.com/spf13/cast"
    45  	jww "github.com/spf13/jwalterweatherman"
    46  	"github.com/spf13/pflag"
    47  	"github.com/subosito/gotenv"
    48  	"gopkg.in/ini.v1"
    49  	"gopkg.in/yaml.v2"
    50  )
    51  
    52  // ConfigMarshalError happens when failing to marshal the configuration.
    53  type ConfigMarshalError struct {
    54  	err error
    55  }
    56  
    57  // Error returns the formatted configuration error.
    58  func (e ConfigMarshalError) Error() string {
    59  	return fmt.Sprintf("While marshaling config: %s", e.err.Error())
    60  }
    61  
    62  var v *Viper
    63  
    64  type RemoteResponse struct {
    65  	Value []byte
    66  	Error error
    67  }
    68  
    69  func init() {
    70  	v = New()
    71  }
    72  
    73  type remoteConfigFactory interface {
    74  	Get(rp RemoteProvider) (io.Reader, error)
    75  	Watch(rp RemoteProvider) (io.Reader, error)
    76  	WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool)
    77  }
    78  
    79  // RemoteConfig is optional, see the remote package
    80  var RemoteConfig remoteConfigFactory
    81  
    82  // UnsupportedConfigError denotes encountering an unsupported
    83  // configuration filetype.
    84  type UnsupportedConfigError string
    85  
    86  // Error returns the formatted configuration error.
    87  func (str UnsupportedConfigError) Error() string {
    88  	return fmt.Sprintf("Unsupported Config Type %q", string(str))
    89  }
    90  
    91  // UnsupportedRemoteProviderError denotes encountering an unsupported remote
    92  // provider. Currently only etcd and Consul are supported.
    93  type UnsupportedRemoteProviderError string
    94  
    95  // Error returns the formatted remote provider error.
    96  func (str UnsupportedRemoteProviderError) Error() string {
    97  	return fmt.Sprintf("Unsupported Remote Provider Type %q", string(str))
    98  }
    99  
   100  // RemoteConfigError denotes encountering an error while trying to
   101  // pull the configuration from the remote provider.
   102  type RemoteConfigError string
   103  
   104  // Error returns the formatted remote provider error
   105  func (rce RemoteConfigError) Error() string {
   106  	return fmt.Sprintf("Remote Configurations Error: %s", string(rce))
   107  }
   108  
   109  // ConfigFileNotFoundError denotes failing to find configuration file.
   110  type ConfigFileNotFoundError struct {
   111  	name, locations string
   112  }
   113  
   114  // Error returns the formatted configuration error.
   115  func (fnfe ConfigFileNotFoundError) Error() string {
   116  	return fmt.Sprintf("Config File %q Not Found in %q", fnfe.name, fnfe.locations)
   117  }
   118  
   119  // ConfigFileAlreadyExistsError denotes failure to write new configuration file.
   120  type ConfigFileAlreadyExistsError string
   121  
   122  // Error returns the formatted error when configuration already exists.
   123  func (faee ConfigFileAlreadyExistsError) Error() string {
   124  	return fmt.Sprintf("Config File %q Already Exists", string(faee))
   125  }
   126  
   127  // A DecoderConfigOption can be passed to viper.Unmarshal to configure
   128  // mapstructure.DecoderConfig options
   129  type DecoderConfigOption func(*mapstructure.DecoderConfig)
   130  
   131  // DecodeHook returns a DecoderConfigOption which overrides the default
   132  // DecoderConfig.DecodeHook value, the default is:
   133  //
   134  //  mapstructure.ComposeDecodeHookFunc(
   135  //		mapstructure.StringToTimeDurationHookFunc(),
   136  //		mapstructure.StringToSliceHookFunc(","),
   137  //	)
   138  func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption {
   139  	return func(c *mapstructure.DecoderConfig) {
   140  		c.DecodeHook = hook
   141  	}
   142  }
   143  
   144  // Viper is a prioritized configuration registry. It
   145  // maintains a set of configuration sources, fetches
   146  // values to populate those, and provides them according
   147  // to the source's priority.
   148  // The priority of the sources is the following:
   149  // 1. overrides
   150  // 2. flags
   151  // 3. env. variables
   152  // 4. config file
   153  // 5. key/value store
   154  // 6. defaults
   155  //
   156  // For example, if values from the following sources were loaded:
   157  //
   158  //  Defaults : {
   159  //  	"secret": "",
   160  //  	"user": "default",
   161  //  	"endpoint": "https://localhost"
   162  //  }
   163  //  Config : {
   164  //  	"user": "root"
   165  //  	"secret": "defaultsecret"
   166  //  }
   167  //  Env : {
   168  //  	"secret": "somesecretkey"
   169  //  }
   170  //
   171  // The resulting config will have the following values:
   172  //
   173  //	{
   174  //		"secret": "somesecretkey",
   175  //		"user": "root",
   176  //		"endpoint": "https://localhost"
   177  //	}
   178  type Viper struct {
   179  	// Delimiter that separates a list of keys
   180  	// used to access a nested value in one go
   181  	keyDelim string
   182  
   183  	// A set of paths to look for the config file in
   184  	configPaths []string
   185  
   186  	// The filesystem to read config from.
   187  	fs afero.Fs
   188  
   189  	// A set of remote providers to search for the configuration
   190  	remoteProviders []*defaultRemoteProvider
   191  
   192  	// Name of file to look for inside the path
   193  	configName        string
   194  	configFile        string
   195  	configType        string
   196  	configPermissions os.FileMode
   197  	envPrefix         string
   198  
   199  	automaticEnvApplied bool
   200  	envKeyReplacer      StringReplacer
   201  	allowEmptyEnv       bool
   202  
   203  	config         map[string]interface{}
   204  	override       map[string]interface{}
   205  	defaults       map[string]interface{}
   206  	kvstore        map[string]interface{}
   207  	pflags         map[string]FlagValue
   208  	env            map[string]string
   209  	aliases        map[string]string
   210  	typeByDefValue bool
   211  
   212  	// Store read properties on the object so that we can write back in order with comments.
   213  	// This will only be used if the configuration read is a properties file.
   214  	properties *properties.Properties
   215  
   216  	onConfigChange func(fsnotify.Event)
   217  }
   218  
   219  // New returns an initialized Viper instance.
   220  func New() *Viper {
   221  	v := new(Viper)
   222  	v.keyDelim = "."
   223  	v.configName = "config"
   224  	v.configPermissions = os.FileMode(0644)
   225  	v.fs = afero.NewOsFs()
   226  	v.config = make(map[string]interface{})
   227  	v.override = make(map[string]interface{})
   228  	v.defaults = make(map[string]interface{})
   229  	v.kvstore = make(map[string]interface{})
   230  	v.pflags = make(map[string]FlagValue)
   231  	v.env = make(map[string]string)
   232  	v.aliases = make(map[string]string)
   233  	v.typeByDefValue = false
   234  
   235  	return v
   236  }
   237  
   238  // Option configures Viper using the functional options paradigm popularized by Rob Pike and Dave Cheney.
   239  // If you're unfamiliar with this style,
   240  // see https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html and
   241  // https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis.
   242  type Option interface {
   243  	apply(v *Viper)
   244  }
   245  
   246  type optionFunc func(v *Viper)
   247  
   248  func (fn optionFunc) apply(v *Viper) {
   249  	fn(v)
   250  }
   251  
   252  // KeyDelimiter sets the delimiter used for determining key parts.
   253  // By default it's value is ".".
   254  func KeyDelimiter(d string) Option {
   255  	return optionFunc(func(v *Viper) {
   256  		v.keyDelim = d
   257  	})
   258  }
   259  
   260  // StringReplacer applies a set of replacements to a string.
   261  type StringReplacer interface {
   262  	// Replace returns a copy of s with all replacements performed.
   263  	Replace(s string) string
   264  }
   265  
   266  // EnvKeyReplacer sets a replacer used for mapping environment variables to internal keys.
   267  func EnvKeyReplacer(r StringReplacer) Option {
   268  	return optionFunc(func(v *Viper) {
   269  		v.envKeyReplacer = r
   270  	})
   271  }
   272  
   273  // NewWithOptions creates a new Viper instance.
   274  func NewWithOptions(opts ...Option) *Viper {
   275  	v := New()
   276  
   277  	for _, opt := range opts {
   278  		opt.apply(v)
   279  	}
   280  
   281  	return v
   282  }
   283  
   284  // Reset is intended for testing, will reset all to default settings.
   285  // In the public interface for the viper package so applications
   286  // can use it in their testing as well.
   287  func Reset() {
   288  	v = New()
   289  	SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"}
   290  	SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
   291  }
   292  
   293  type defaultRemoteProvider struct {
   294  	provider      string
   295  	endpoint      string
   296  	path          string
   297  	secretKeyring string
   298  }
   299  
   300  func (rp defaultRemoteProvider) Provider() string {
   301  	return rp.provider
   302  }
   303  
   304  func (rp defaultRemoteProvider) Endpoint() string {
   305  	return rp.endpoint
   306  }
   307  
   308  func (rp defaultRemoteProvider) Path() string {
   309  	return rp.path
   310  }
   311  
   312  func (rp defaultRemoteProvider) SecretKeyring() string {
   313  	return rp.secretKeyring
   314  }
   315  
   316  // RemoteProvider stores the configuration necessary
   317  // to connect to a remote key/value store.
   318  // Optional secretKeyring to unencrypt encrypted values
   319  // can be provided.
   320  type RemoteProvider interface {
   321  	Provider() string
   322  	Endpoint() string
   323  	Path() string
   324  	SecretKeyring() string
   325  }
   326  
   327  // SupportedExts are universally supported extensions.
   328  var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"}
   329  
   330  // SupportedRemoteProviders are universally supported remote providers.
   331  var SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
   332  
   333  func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
   334  func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) {
   335  	v.onConfigChange = run
   336  }
   337  
   338  func WatchConfig() { v.WatchConfig() }
   339  
   340  func (v *Viper) WatchConfig() {
   341  	initWG := sync.WaitGroup{}
   342  	initWG.Add(1)
   343  	go func() {
   344  		watcher, err := fsnotify.NewWatcher()
   345  		if err != nil {
   346  			log.Fatal(err)
   347  		}
   348  		defer watcher.Close()
   349  		// we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way
   350  		filename, err := v.getConfigFile()
   351  		if err != nil {
   352  			log.Printf("error: %v\n", err)
   353  			initWG.Done()
   354  			return
   355  		}
   356  
   357  		configFile := filepath.Clean(filename)
   358  		configDir, _ := filepath.Split(configFile)
   359  		realConfigFile, _ := filepath.EvalSymlinks(filename)
   360  
   361  		eventsWG := sync.WaitGroup{}
   362  		eventsWG.Add(1)
   363  		go func() {
   364  			for {
   365  				select {
   366  				case event, ok := <-watcher.Events:
   367  					if !ok { // 'Events' channel is closed
   368  						eventsWG.Done()
   369  						return
   370  					}
   371  					currentConfigFile, _ := filepath.EvalSymlinks(filename)
   372  					// we only care about the config file with the following cases:
   373  					// 1 - if the config file was modified or created
   374  					// 2 - if the real path to the config file changed (eg: k8s ConfigMap replacement)
   375  					const writeOrCreateMask = fsnotify.Write | fsnotify.Create
   376  					if (filepath.Clean(event.Name) == configFile &&
   377  						event.Op&writeOrCreateMask != 0) ||
   378  						(currentConfigFile != "" && currentConfigFile != realConfigFile) {
   379  						realConfigFile = currentConfigFile
   380  						err := v.ReadInConfig()
   381  						if err != nil {
   382  							log.Printf("error reading config file: %v\n", err)
   383  						}
   384  						if v.onConfigChange != nil {
   385  							v.onConfigChange(event)
   386  						}
   387  					} else if filepath.Clean(event.Name) == configFile &&
   388  						event.Op&fsnotify.Remove&fsnotify.Remove != 0 {
   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 !stringInSlice(v.getConfigType(), SupportedExts) {
  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 !stringInSlice(v.getConfigType(), SupportedExts) {
  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 !stringInSlice(configType, SupportedExts) {
  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  	buf := new(bytes.Buffer)
  1468  	buf.ReadFrom(in)
  1469  
  1470  	switch strings.ToLower(v.getConfigType()) {
  1471  	case "yaml", "yml":
  1472  		if err := yaml.UnmarshalStrict(buf.Bytes(), &c); err != nil {
  1473  			return ConfigParseError{err}
  1474  		}
  1475  
  1476  	case "json":
  1477  		if err := json.Unmarshal(buf.Bytes(), &c); err != nil {
  1478  			return ConfigParseError{err}
  1479  		}
  1480  
  1481  	case "hcl":
  1482  		obj, err := hcl.Parse(buf.String())
  1483  		if err != nil {
  1484  			return ConfigParseError{err}
  1485  		}
  1486  		if err = hcl.DecodeObject(&c, obj); err != nil {
  1487  			return ConfigParseError{err}
  1488  		}
  1489  
  1490  	case "toml":
  1491  		tree, err := toml.LoadReader(buf)
  1492  		if err != nil {
  1493  			return ConfigParseError{err}
  1494  		}
  1495  		tmap := tree.ToMap()
  1496  		for k, v := range tmap {
  1497  			c[k] = v
  1498  		}
  1499  
  1500  	case "dotenv", "env":
  1501  		env, err := gotenv.StrictParse(buf)
  1502  		if err != nil {
  1503  			return ConfigParseError{err}
  1504  		}
  1505  		for k, v := range env {
  1506  			c[k] = v
  1507  		}
  1508  
  1509  	case "properties", "props", "prop":
  1510  		v.properties = properties.NewProperties()
  1511  		var err error
  1512  		if v.properties, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil {
  1513  			return ConfigParseError{err}
  1514  		}
  1515  		for _, key := range v.properties.Keys() {
  1516  			value, _ := v.properties.Get(key)
  1517  			// recursively build nested maps
  1518  			path := strings.Split(key, ".")
  1519  			lastKey := strings.ToLower(path[len(path)-1])
  1520  			deepestMap := deepSearch(c, path[0:len(path)-1])
  1521  			// set innermost value
  1522  			deepestMap[lastKey] = value
  1523  		}
  1524  
  1525  	case "ini":
  1526  		cfg := ini.Empty()
  1527  		err := cfg.Append(buf.Bytes())
  1528  		if err != nil {
  1529  			return ConfigParseError{err}
  1530  		}
  1531  		sections := cfg.Sections()
  1532  		for i := 0; i < len(sections); i++ {
  1533  			section := sections[i]
  1534  			keys := section.Keys()
  1535  			for j := 0; j < len(keys); j++ {
  1536  				key := keys[j]
  1537  				value := cfg.Section(section.Name()).Key(key.Name()).String()
  1538  				c[section.Name()+"."+key.Name()] = value
  1539  			}
  1540  		}
  1541  	}
  1542  
  1543  	insensitiviseMap(c)
  1544  	return nil
  1545  }
  1546  
  1547  // Marshal a map into Writer.
  1548  func (v *Viper) marshalWriter(f afero.File, configType string) error {
  1549  	c := v.AllSettings()
  1550  	switch configType {
  1551  	case "json":
  1552  		b, err := json.MarshalIndent(c, "", "  ")
  1553  		if err != nil {
  1554  			return ConfigMarshalError{err}
  1555  		}
  1556  		_, err = f.WriteString(string(b))
  1557  		if err != nil {
  1558  			return ConfigMarshalError{err}
  1559  		}
  1560  
  1561  	case "hcl":
  1562  		b, err := json.Marshal(c)
  1563  		if err != nil {
  1564  			return ConfigMarshalError{err}
  1565  		}
  1566  		ast, err := hcl.Parse(string(b))
  1567  		if err != nil {
  1568  			return ConfigMarshalError{err}
  1569  		}
  1570  		err = printer.Fprint(f, ast.Node)
  1571  		if err != nil {
  1572  			return ConfigMarshalError{err}
  1573  		}
  1574  
  1575  	case "prop", "props", "properties":
  1576  		if v.properties == nil {
  1577  			v.properties = properties.NewProperties()
  1578  		}
  1579  		p := v.properties
  1580  		for _, key := range v.AllKeys() {
  1581  			_, _, err := p.Set(key, v.GetString(key))
  1582  			if err != nil {
  1583  				return ConfigMarshalError{err}
  1584  			}
  1585  		}
  1586  		_, err := p.WriteComment(f, "#", properties.UTF8)
  1587  		if err != nil {
  1588  			return ConfigMarshalError{err}
  1589  		}
  1590  
  1591  	case "dotenv", "env":
  1592  		lines := []string{}
  1593  		for _, key := range v.AllKeys() {
  1594  			envName := strings.ToUpper(strings.Replace(key, ".", "_", -1))
  1595  			val := v.Get(key)
  1596  			lines = append(lines, fmt.Sprintf("%v=%v", envName, val))
  1597  		}
  1598  		s := strings.Join(lines, "\n")
  1599  		if _, err := f.WriteString(s); err != nil {
  1600  			return ConfigMarshalError{err}
  1601  		}
  1602  
  1603  	case "toml":
  1604  		t, err := toml.TreeFromMap(c)
  1605  		if err != nil {
  1606  			return ConfigMarshalError{err}
  1607  		}
  1608  		s := t.String()
  1609  		if _, err := f.WriteString(s); err != nil {
  1610  			return ConfigMarshalError{err}
  1611  		}
  1612  
  1613  	case "yaml", "yml":
  1614  		b, err := yaml.Marshal(c)
  1615  		if err != nil {
  1616  			return ConfigMarshalError{err}
  1617  		}
  1618  		if _, err = f.WriteString(string(b)); err != nil {
  1619  			return ConfigMarshalError{err}
  1620  		}
  1621  
  1622  	case "ini":
  1623  		keys := v.AllKeys()
  1624  		cfg := ini.Empty()
  1625  		ini.PrettyFormat = false
  1626  		for i := 0; i < len(keys); i++ {
  1627  			key := keys[i]
  1628  			lastSep := strings.LastIndex(key, ".")
  1629  			sectionName := key[:(lastSep)]
  1630  			keyName := key[(lastSep + 1):]
  1631  			if sectionName == "default" {
  1632  				sectionName = ""
  1633  			}
  1634  			cfg.Section(sectionName).Key(keyName).SetValue(v.Get(key).(string))
  1635  		}
  1636  		cfg.WriteTo(f)
  1637  	}
  1638  	return nil
  1639  }
  1640  
  1641  func keyExists(k string, m map[string]interface{}) string {
  1642  	lk := strings.ToLower(k)
  1643  	for mk := range m {
  1644  		lmk := strings.ToLower(mk)
  1645  		if lmk == lk {
  1646  			return mk
  1647  		}
  1648  	}
  1649  	return ""
  1650  }
  1651  
  1652  func castToMapStringInterface(
  1653  	src map[interface{}]interface{}) map[string]interface{} {
  1654  	tgt := map[string]interface{}{}
  1655  	for k, v := range src {
  1656  		tgt[fmt.Sprintf("%v", k)] = v
  1657  	}
  1658  	return tgt
  1659  }
  1660  
  1661  func castMapStringToMapInterface(src map[string]string) map[string]interface{} {
  1662  	tgt := map[string]interface{}{}
  1663  	for k, v := range src {
  1664  		tgt[k] = v
  1665  	}
  1666  	return tgt
  1667  }
  1668  
  1669  func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} {
  1670  	tgt := map[string]interface{}{}
  1671  	for k, v := range src {
  1672  		tgt[k] = v
  1673  	}
  1674  	return tgt
  1675  }
  1676  
  1677  // mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's
  1678  // insistence on parsing nested structures as `map[interface{}]interface{}`
  1679  // instead of using a `string` as the key for nest structures beyond one level
  1680  // deep. Both map types are supported as there is a go-yaml fork that uses
  1681  // `map[string]interface{}` instead.
  1682  func mergeMaps(
  1683  	src, tgt map[string]interface{}, itgt map[interface{}]interface{}) {
  1684  	for sk, sv := range src {
  1685  		tk := keyExists(sk, tgt)
  1686  		if tk == "" {
  1687  			jww.TRACE.Printf("tk=\"\", tgt[%s]=%v", sk, sv)
  1688  			tgt[sk] = sv
  1689  			if itgt != nil {
  1690  				itgt[sk] = sv
  1691  			}
  1692  			continue
  1693  		}
  1694  
  1695  		tv, ok := tgt[tk]
  1696  		if !ok {
  1697  			jww.TRACE.Printf("tgt[%s] != ok, tgt[%s]=%v", tk, sk, sv)
  1698  			tgt[sk] = sv
  1699  			if itgt != nil {
  1700  				itgt[sk] = sv
  1701  			}
  1702  			continue
  1703  		}
  1704  
  1705  		svType := reflect.TypeOf(sv)
  1706  		tvType := reflect.TypeOf(tv)
  1707  		if svType != tvType {
  1708  			jww.ERROR.Printf(
  1709  				"svType != tvType; key=%s, st=%v, tt=%v, sv=%v, tv=%v",
  1710  				sk, svType, tvType, sv, tv)
  1711  			continue
  1712  		}
  1713  
  1714  		jww.TRACE.Printf("processing key=%s, st=%v, tt=%v, sv=%v, tv=%v",
  1715  			sk, svType, tvType, sv, tv)
  1716  
  1717  		switch ttv := tv.(type) {
  1718  		case map[interface{}]interface{}:
  1719  			jww.TRACE.Printf("merging maps (must convert)")
  1720  			tsv := sv.(map[interface{}]interface{})
  1721  			ssv := castToMapStringInterface(tsv)
  1722  			stv := castToMapStringInterface(ttv)
  1723  			mergeMaps(ssv, stv, ttv)
  1724  		case map[string]interface{}:
  1725  			jww.TRACE.Printf("merging maps")
  1726  			mergeMaps(sv.(map[string]interface{}), ttv, nil)
  1727  		default:
  1728  			jww.TRACE.Printf("setting value")
  1729  			tgt[tk] = sv
  1730  			if itgt != nil {
  1731  				itgt[tk] = sv
  1732  			}
  1733  		}
  1734  	}
  1735  }
  1736  
  1737  // ReadRemoteConfig attempts to get configuration from a remote source
  1738  // and read it in the remote configuration registry.
  1739  func ReadRemoteConfig() error { return v.ReadRemoteConfig() }
  1740  func (v *Viper) ReadRemoteConfig() error {
  1741  	return v.getKeyValueConfig()
  1742  }
  1743  
  1744  func WatchRemoteConfig() error { return v.WatchRemoteConfig() }
  1745  func (v *Viper) WatchRemoteConfig() error {
  1746  	return v.watchKeyValueConfig()
  1747  }
  1748  
  1749  func (v *Viper) WatchRemoteConfigOnChannel() error {
  1750  	return v.watchKeyValueConfigOnChannel()
  1751  }
  1752  
  1753  // Retrieve the first found remote configuration.
  1754  func (v *Viper) getKeyValueConfig() error {
  1755  	if RemoteConfig == nil {
  1756  		return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ github.com/spf13/viper/remote'")
  1757  	}
  1758  
  1759  	for _, rp := range v.remoteProviders {
  1760  		val, err := v.getRemoteConfig(rp)
  1761  		if err != nil {
  1762  			continue
  1763  		}
  1764  		v.kvstore = val
  1765  		return nil
  1766  	}
  1767  	return RemoteConfigError("No Files Found")
  1768  }
  1769  
  1770  func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) {
  1771  	reader, err := RemoteConfig.Get(provider)
  1772  	if err != nil {
  1773  		return nil, err
  1774  	}
  1775  	err = v.unmarshalReader(reader, v.kvstore)
  1776  	return v.kvstore, err
  1777  }
  1778  
  1779  // Retrieve the first found remote configuration.
  1780  func (v *Viper) watchKeyValueConfigOnChannel() error {
  1781  	for _, rp := range v.remoteProviders {
  1782  		respc, _ := RemoteConfig.WatchChannel(rp)
  1783  		// Todo: Add quit channel
  1784  		go func(rc <-chan *RemoteResponse) {
  1785  			for {
  1786  				b := <-rc
  1787  				reader := bytes.NewReader(b.Value)
  1788  				v.unmarshalReader(reader, v.kvstore)
  1789  			}
  1790  		}(respc)
  1791  		return nil
  1792  	}
  1793  	return RemoteConfigError("No Files Found")
  1794  }
  1795  
  1796  // Retrieve the first found remote configuration.
  1797  func (v *Viper) watchKeyValueConfig() error {
  1798  	for _, rp := range v.remoteProviders {
  1799  		val, err := v.watchRemoteConfig(rp)
  1800  		if err != nil {
  1801  			continue
  1802  		}
  1803  		v.kvstore = val
  1804  		return nil
  1805  	}
  1806  	return RemoteConfigError("No Files Found")
  1807  }
  1808  
  1809  func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) {
  1810  	reader, err := RemoteConfig.Watch(provider)
  1811  	if err != nil {
  1812  		return nil, err
  1813  	}
  1814  	err = v.unmarshalReader(reader, v.kvstore)
  1815  	return v.kvstore, err
  1816  }
  1817  
  1818  // AllKeys returns all keys holding a value, regardless of where they are set.
  1819  // Nested keys are returned with a v.keyDelim separator
  1820  func AllKeys() []string { return v.AllKeys() }
  1821  func (v *Viper) AllKeys() []string {
  1822  	m := map[string]bool{}
  1823  	// add all paths, by order of descending priority to ensure correct shadowing
  1824  	m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "")
  1825  	m = v.flattenAndMergeMap(m, v.override, "")
  1826  	m = v.mergeFlatMap(m, castMapFlagToMapInterface(v.pflags))
  1827  	m = v.mergeFlatMap(m, castMapStringToMapInterface(v.env))
  1828  	m = v.flattenAndMergeMap(m, v.config, "")
  1829  	m = v.flattenAndMergeMap(m, v.kvstore, "")
  1830  	m = v.flattenAndMergeMap(m, v.defaults, "")
  1831  
  1832  	// convert set of paths to list
  1833  	a := make([]string, 0, len(m))
  1834  	for x := range m {
  1835  		a = append(a, x)
  1836  	}
  1837  	return a
  1838  }
  1839  
  1840  // flattenAndMergeMap recursively flattens the given map into a map[string]bool
  1841  // of key paths (used as a set, easier to manipulate than a []string):
  1842  // - each path is merged into a single key string, delimited with v.keyDelim
  1843  // - if a path is shadowed by an earlier value in the initial shadow map,
  1844  //   it is skipped.
  1845  // The resulting set of paths is merged to the given shadow set at the same time.
  1846  func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool {
  1847  	if shadow != nil && prefix != "" && shadow[prefix] {
  1848  		// prefix is shadowed => nothing more to flatten
  1849  		return shadow
  1850  	}
  1851  	if shadow == nil {
  1852  		shadow = make(map[string]bool)
  1853  	}
  1854  
  1855  	var m2 map[string]interface{}
  1856  	if prefix != "" {
  1857  		prefix += v.keyDelim
  1858  	}
  1859  	for k, val := range m {
  1860  		fullKey := prefix + k
  1861  		switch val.(type) {
  1862  		case map[string]interface{}:
  1863  			m2 = val.(map[string]interface{})
  1864  		case map[interface{}]interface{}:
  1865  			m2 = cast.ToStringMap(val)
  1866  		default:
  1867  			// immediate value
  1868  			shadow[strings.ToLower(fullKey)] = true
  1869  			continue
  1870  		}
  1871  		// recursively merge to shadow map
  1872  		shadow = v.flattenAndMergeMap(shadow, m2, fullKey)
  1873  	}
  1874  	return shadow
  1875  }
  1876  
  1877  // mergeFlatMap merges the given maps, excluding values of the second map
  1878  // shadowed by values from the first map.
  1879  func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool {
  1880  	// scan keys
  1881  outer:
  1882  	for k := range m {
  1883  		path := strings.Split(k, v.keyDelim)
  1884  		// scan intermediate paths
  1885  		var parentKey string
  1886  		for i := 1; i < len(path); i++ {
  1887  			parentKey = strings.Join(path[0:i], v.keyDelim)
  1888  			if shadow[parentKey] {
  1889  				// path is shadowed, continue
  1890  				continue outer
  1891  			}
  1892  		}
  1893  		// add key
  1894  		shadow[strings.ToLower(k)] = true
  1895  	}
  1896  	return shadow
  1897  }
  1898  
  1899  // AllSettings merges all settings and returns them as a map[string]interface{}.
  1900  func AllSettings() map[string]interface{} { return v.AllSettings() }
  1901  func (v *Viper) AllSettings() map[string]interface{} {
  1902  	m := map[string]interface{}{}
  1903  	// start from the list of keys, and construct the map one value at a time
  1904  	for _, k := range v.AllKeys() {
  1905  		value := v.Get(k)
  1906  		if value == nil {
  1907  			// should not happen, since AllKeys() returns only keys holding a value,
  1908  			// check just in case anything changes
  1909  			continue
  1910  		}
  1911  		path := strings.Split(k, v.keyDelim)
  1912  		lastKey := strings.ToLower(path[len(path)-1])
  1913  		deepestMap := deepSearch(m, path[0:len(path)-1])
  1914  		// set innermost value
  1915  		deepestMap[lastKey] = value
  1916  	}
  1917  	return m
  1918  }
  1919  
  1920  // SetFs sets the filesystem to use to read configuration.
  1921  func SetFs(fs afero.Fs) { v.SetFs(fs) }
  1922  func (v *Viper) SetFs(fs afero.Fs) {
  1923  	v.fs = fs
  1924  }
  1925  
  1926  // SetConfigName sets name for the config file.
  1927  // Does not include extension.
  1928  func SetConfigName(in string) { v.SetConfigName(in) }
  1929  func (v *Viper) SetConfigName(in string) {
  1930  	if in != "" {
  1931  		v.configName = in
  1932  		v.configFile = ""
  1933  	}
  1934  }
  1935  
  1936  // SetConfigType sets the type of the configuration returned by the
  1937  // remote source, e.g. "json".
  1938  func SetConfigType(in string) { v.SetConfigType(in) }
  1939  func (v *Viper) SetConfigType(in string) {
  1940  	if in != "" {
  1941  		v.configType = in
  1942  	}
  1943  }
  1944  
  1945  // SetConfigPermissions sets the permissions for the config file.
  1946  func SetConfigPermissions(perm os.FileMode) { v.SetConfigPermissions(perm) }
  1947  func (v *Viper) SetConfigPermissions(perm os.FileMode) {
  1948  	v.configPermissions = perm.Perm()
  1949  }
  1950  
  1951  func (v *Viper) getConfigType() string {
  1952  	if v.configType != "" {
  1953  		return v.configType
  1954  	}
  1955  
  1956  	cf, err := v.getConfigFile()
  1957  	if err != nil {
  1958  		return ""
  1959  	}
  1960  
  1961  	ext := filepath.Ext(cf)
  1962  
  1963  	if len(ext) > 1 {
  1964  		return ext[1:]
  1965  	}
  1966  
  1967  	return ""
  1968  }
  1969  
  1970  func (v *Viper) getConfigFile() (string, error) {
  1971  	if v.configFile == "" {
  1972  		cf, err := v.findConfigFile()
  1973  		if err != nil {
  1974  			return "", err
  1975  		}
  1976  		v.configFile = cf
  1977  	}
  1978  	return v.configFile, nil
  1979  }
  1980  
  1981  func (v *Viper) searchInPath(in string) (filename string) {
  1982  	jww.DEBUG.Println("Searching for config in ", in)
  1983  	for _, ext := range SupportedExts {
  1984  		jww.DEBUG.Println("Checking for", filepath.Join(in, v.configName+"."+ext))
  1985  		if b, _ := exists(v.fs, filepath.Join(in, v.configName+"."+ext)); b {
  1986  			jww.DEBUG.Println("Found: ", filepath.Join(in, v.configName+"."+ext))
  1987  			return filepath.Join(in, v.configName+"."+ext)
  1988  		}
  1989  	}
  1990  
  1991  	if v.configType != "" {
  1992  		if b, _ := exists(v.fs, filepath.Join(in, v.configName)); b {
  1993  			return filepath.Join(in, v.configName)
  1994  		}
  1995  	}
  1996  
  1997  	return ""
  1998  }
  1999  
  2000  // Search all configPaths for any config file.
  2001  // Returns the first path that exists (and is a config file).
  2002  func (v *Viper) findConfigFile() (string, error) {
  2003  	jww.INFO.Println("Searching for config in ", v.configPaths)
  2004  
  2005  	for _, cp := range v.configPaths {
  2006  		file := v.searchInPath(cp)
  2007  		if file != "" {
  2008  			return file, nil
  2009  		}
  2010  	}
  2011  	return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)}
  2012  }
  2013  
  2014  // Debug prints all configuration registries for debugging
  2015  // purposes.
  2016  func Debug() { v.Debug() }
  2017  func (v *Viper) Debug() {
  2018  	fmt.Printf("Aliases:\n%#v\n", v.aliases)
  2019  	fmt.Printf("Override:\n%#v\n", v.override)
  2020  	fmt.Printf("PFlags:\n%#v\n", v.pflags)
  2021  	fmt.Printf("Env:\n%#v\n", v.env)
  2022  	fmt.Printf("Key/Value Store:\n%#v\n", v.kvstore)
  2023  	fmt.Printf("Config:\n%#v\n", v.config)
  2024  	fmt.Printf("Defaults:\n%#v\n", v.defaults)
  2025  }