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