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