...

Source file src/github.com/ory/viper/viper.go

Documentation: github.com/ory/viper

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

View as plain text