OSDN Git Service

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