vendor/github.com/spf13/viper/viper.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
child 256 6d9efbef00a9
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
     1 // Copyright © 2014 Steve Francia <spf@spf13.com>.
     1 // Copyright © 2014 Steve Francia <spf@spf13.com>.
     2 //
     2 //
     3 // Use of this source code is governed by an MIT-style
     3 // Use of this source code is governed by an MIT-style
     4 // license that can be found in the LICENSE file.
     4 // license that can be found in the LICENSE file.
     5 
     5 
     6 // Viper is a application configuration system.
     6 // Viper is an application configuration system.
     7 // It believes that applications can be configured a variety of ways
     7 // It believes that applications can be configured a variety of ways
     8 // via flags, ENVIRONMENT variables, configuration files retrieved
     8 // via flags, ENVIRONMENT variables, configuration files retrieved
     9 // from the file system, or a remote key/value store.
     9 // from the file system, or a remote key/value store.
    10 
    10 
    11 // Each item takes precedence over the item below it:
    11 // Each item takes precedence over the item below it:
    21 
    21 
    22 import (
    22 import (
    23 	"bytes"
    23 	"bytes"
    24 	"encoding/csv"
    24 	"encoding/csv"
    25 	"encoding/json"
    25 	"encoding/json"
       
    26 	"errors"
    26 	"fmt"
    27 	"fmt"
    27 	"io"
    28 	"io"
    28 	"log"
    29 	"log"
    29 	"os"
    30 	"os"
    30 	"path/filepath"
    31 	"path/filepath"
    31 	"reflect"
    32 	"reflect"
    32 	"strings"
    33 	"strings"
       
    34 	"sync"
    33 	"time"
    35 	"time"
    34 
       
    35 	yaml "gopkg.in/yaml.v2"
       
    36 
    36 
    37 	"github.com/fsnotify/fsnotify"
    37 	"github.com/fsnotify/fsnotify"
    38 	"github.com/hashicorp/hcl"
    38 	"github.com/hashicorp/hcl"
    39 	"github.com/hashicorp/hcl/hcl/printer"
    39 	"github.com/hashicorp/hcl/hcl/printer"
    40 	"github.com/magiconair/properties"
    40 	"github.com/magiconair/properties"
    41 	"github.com/mitchellh/mapstructure"
    41 	"github.com/mitchellh/mapstructure"
    42 	toml "github.com/pelletier/go-toml"
    42 	"github.com/pelletier/go-toml"
    43 	"github.com/spf13/afero"
    43 	"github.com/spf13/afero"
    44 	"github.com/spf13/cast"
    44 	"github.com/spf13/cast"
    45 	jww "github.com/spf13/jwalterweatherman"
    45 	jww "github.com/spf13/jwalterweatherman"
    46 	"github.com/spf13/pflag"
    46 	"github.com/spf13/pflag"
       
    47 	"github.com/subosito/gotenv"
       
    48 	"gopkg.in/ini.v1"
       
    49 	"gopkg.in/yaml.v2"
    47 )
    50 )
    48 
    51 
    49 // ConfigMarshalError happens when failing to marshal the configuration.
    52 // ConfigMarshalError happens when failing to marshal the configuration.
    50 type ConfigMarshalError struct {
    53 type ConfigMarshalError struct {
    51 	err error
    54 	err error
   109 }
   112 }
   110 
   113 
   111 // Error returns the formatted configuration error.
   114 // Error returns the formatted configuration error.
   112 func (fnfe ConfigFileNotFoundError) Error() string {
   115 func (fnfe ConfigFileNotFoundError) Error() string {
   113 	return fmt.Sprintf("Config File %q Not Found in %q", fnfe.name, fnfe.locations)
   116 	return fmt.Sprintf("Config File %q Not Found in %q", fnfe.name, fnfe.locations)
       
   117 }
       
   118 
       
   119 // ConfigFileAlreadyExistsError denotes failure to write new configuration file.
       
   120 type ConfigFileAlreadyExistsError string
       
   121 
       
   122 // Error returns the formatted error when configuration already exists.
       
   123 func (faee ConfigFileAlreadyExistsError) Error() string {
       
   124 	return fmt.Sprintf("Config File %q Already Exists", string(faee))
   114 }
   125 }
   115 
   126 
   116 // A DecoderConfigOption can be passed to viper.Unmarshal to configure
   127 // A DecoderConfigOption can be passed to viper.Unmarshal to configure
   117 // mapstructure.DecoderConfig options
   128 // mapstructure.DecoderConfig options
   118 type DecoderConfigOption func(*mapstructure.DecoderConfig)
   129 type DecoderConfigOption func(*mapstructure.DecoderConfig)
   177 
   188 
   178 	// A set of remote providers to search for the configuration
   189 	// A set of remote providers to search for the configuration
   179 	remoteProviders []*defaultRemoteProvider
   190 	remoteProviders []*defaultRemoteProvider
   180 
   191 
   181 	// Name of file to look for inside the path
   192 	// Name of file to look for inside the path
   182 	configName string
   193 	configName        string
   183 	configFile string
   194 	configFile        string
   184 	configType string
   195 	configType        string
   185 	envPrefix  string
   196 	configPermissions os.FileMode
       
   197 	envPrefix         string
   186 
   198 
   187 	automaticEnvApplied bool
   199 	automaticEnvApplied bool
   188 	envKeyReplacer      *strings.Replacer
   200 	envKeyReplacer      StringReplacer
       
   201 	allowEmptyEnv       bool
   189 
   202 
   190 	config         map[string]interface{}
   203 	config         map[string]interface{}
   191 	override       map[string]interface{}
   204 	override       map[string]interface{}
   192 	defaults       map[string]interface{}
   205 	defaults       map[string]interface{}
   193 	kvstore        map[string]interface{}
   206 	kvstore        map[string]interface{}
   206 // New returns an initialized Viper instance.
   219 // New returns an initialized Viper instance.
   207 func New() *Viper {
   220 func New() *Viper {
   208 	v := new(Viper)
   221 	v := new(Viper)
   209 	v.keyDelim = "."
   222 	v.keyDelim = "."
   210 	v.configName = "config"
   223 	v.configName = "config"
       
   224 	v.configPermissions = os.FileMode(0644)
   211 	v.fs = afero.NewOsFs()
   225 	v.fs = afero.NewOsFs()
   212 	v.config = make(map[string]interface{})
   226 	v.config = make(map[string]interface{})
   213 	v.override = make(map[string]interface{})
   227 	v.override = make(map[string]interface{})
   214 	v.defaults = make(map[string]interface{})
   228 	v.defaults = make(map[string]interface{})
   215 	v.kvstore = make(map[string]interface{})
   229 	v.kvstore = make(map[string]interface{})
   219 	v.typeByDefValue = false
   233 	v.typeByDefValue = false
   220 
   234 
   221 	return v
   235 	return v
   222 }
   236 }
   223 
   237 
   224 // Intended for testing, will reset all to default settings.
   238 // Option configures Viper using the functional options paradigm popularized by Rob Pike and Dave Cheney.
       
   239 // If you're unfamiliar with this style,
       
   240 // see https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html and
       
   241 // https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis.
       
   242 type Option interface {
       
   243 	apply(v *Viper)
       
   244 }
       
   245 
       
   246 type optionFunc func(v *Viper)
       
   247 
       
   248 func (fn optionFunc) apply(v *Viper) {
       
   249 	fn(v)
       
   250 }
       
   251 
       
   252 // KeyDelimiter sets the delimiter used for determining key parts.
       
   253 // By default it's value is ".".
       
   254 func KeyDelimiter(d string) Option {
       
   255 	return optionFunc(func(v *Viper) {
       
   256 		v.keyDelim = d
       
   257 	})
       
   258 }
       
   259 
       
   260 // StringReplacer applies a set of replacements to a string.
       
   261 type StringReplacer interface {
       
   262 	// Replace returns a copy of s with all replacements performed.
       
   263 	Replace(s string) string
       
   264 }
       
   265 
       
   266 // EnvKeyReplacer sets a replacer used for mapping environment variables to internal keys.
       
   267 func EnvKeyReplacer(r StringReplacer) Option {
       
   268 	return optionFunc(func(v *Viper) {
       
   269 		v.envKeyReplacer = r
       
   270 	})
       
   271 }
       
   272 
       
   273 // NewWithOptions creates a new Viper instance.
       
   274 func NewWithOptions(opts ...Option) *Viper {
       
   275 	v := New()
       
   276 
       
   277 	for _, opt := range opts {
       
   278 		opt.apply(v)
       
   279 	}
       
   280 
       
   281 	return v
       
   282 }
       
   283 
       
   284 // Reset is intended for testing, will reset all to default settings.
   225 // In the public interface for the viper package so applications
   285 // In the public interface for the viper package so applications
   226 // can use it in their testing as well.
   286 // can use it in their testing as well.
   227 func Reset() {
   287 func Reset() {
   228 	v = New()
   288 	v = New()
   229 	SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl"}
   289 	SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"}
   230 	SupportedRemoteProviders = []string{"etcd", "consul"}
   290 	SupportedRemoteProviders = []string{"etcd", "consul"}
   231 }
   291 }
   232 
   292 
   233 type defaultRemoteProvider struct {
   293 type defaultRemoteProvider struct {
   234 	provider      string
   294 	provider      string
   263 	Path() string
   323 	Path() string
   264 	SecretKeyring() string
   324 	SecretKeyring() string
   265 }
   325 }
   266 
   326 
   267 // SupportedExts are universally supported extensions.
   327 // SupportedExts are universally supported extensions.
   268 var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl"}
   328 var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"}
   269 
   329 
   270 // SupportedRemoteProviders are universally supported remote providers.
   330 // SupportedRemoteProviders are universally supported remote providers.
   271 var SupportedRemoteProviders = []string{"etcd", "consul"}
   331 var SupportedRemoteProviders = []string{"etcd", "consul"}
   272 
   332 
   273 func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
   333 func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
   274 func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) {
   334 func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) {
   275 	v.onConfigChange = run
   335 	v.onConfigChange = run
   276 }
   336 }
   277 
   337 
   278 func WatchConfig() { v.WatchConfig() }
   338 func WatchConfig() { v.WatchConfig() }
       
   339 
   279 func (v *Viper) WatchConfig() {
   340 func (v *Viper) WatchConfig() {
       
   341 	initWG := sync.WaitGroup{}
       
   342 	initWG.Add(1)
   280 	go func() {
   343 	go func() {
   281 		watcher, err := fsnotify.NewWatcher()
   344 		watcher, err := fsnotify.NewWatcher()
   282 		if err != nil {
   345 		if err != nil {
   283 			log.Fatal(err)
   346 			log.Fatal(err)
   284 		}
   347 		}
   285 		defer watcher.Close()
   348 		defer watcher.Close()
   286 
       
   287 		// we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way
   349 		// we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way
   288 		filename, err := v.getConfigFile()
   350 		filename, err := v.getConfigFile()
   289 		if err != nil {
   351 		if err != nil {
   290 			log.Println("error:", err)
   352 			log.Printf("error: %v\n", err)
       
   353 			initWG.Done()
   291 			return
   354 			return
   292 		}
   355 		}
   293 
   356 
   294 		configFile := filepath.Clean(filename)
   357 		configFile := filepath.Clean(filename)
   295 		configDir, _ := filepath.Split(configFile)
   358 		configDir, _ := filepath.Split(configFile)
   296 
   359 		realConfigFile, _ := filepath.EvalSymlinks(filename)
   297 		done := make(chan bool)
   360 
       
   361 		eventsWG := sync.WaitGroup{}
       
   362 		eventsWG.Add(1)
   298 		go func() {
   363 		go func() {
   299 			for {
   364 			for {
   300 				select {
   365 				select {
   301 				case event := <-watcher.Events:
   366 				case event, ok := <-watcher.Events:
   302 					// we only care about the config file
   367 					if !ok { // 'Events' channel is closed
   303 					if filepath.Clean(event.Name) == configFile {
   368 						eventsWG.Done()
   304 						if event.Op&fsnotify.Write == fsnotify.Write || event.Op&fsnotify.Create == fsnotify.Create {
   369 						return
   305 							err := v.ReadInConfig()
   370 					}
   306 							if err != nil {
   371 					currentConfigFile, _ := filepath.EvalSymlinks(filename)
   307 								log.Println("error:", err)
   372 					// we only care about the config file with the following cases:
   308 							}
   373 					// 1 - if the config file was modified or created
   309 							if v.onConfigChange != nil {
   374 					// 2 - if the real path to the config file changed (eg: k8s ConfigMap replacement)
   310 								v.onConfigChange(event)
   375 					const writeOrCreateMask = fsnotify.Write | fsnotify.Create
   311 							}
   376 					if (filepath.Clean(event.Name) == configFile &&
       
   377 						event.Op&writeOrCreateMask != 0) ||
       
   378 						(currentConfigFile != "" && currentConfigFile != realConfigFile) {
       
   379 						realConfigFile = currentConfigFile
       
   380 						err := v.ReadInConfig()
       
   381 						if err != nil {
       
   382 							log.Printf("error reading config file: %v\n", err)
   312 						}
   383 						}
       
   384 						if v.onConfigChange != nil {
       
   385 							v.onConfigChange(event)
       
   386 						}
       
   387 					} else if filepath.Clean(event.Name) == configFile &&
       
   388 						event.Op&fsnotify.Remove&fsnotify.Remove != 0 {
       
   389 						eventsWG.Done()
       
   390 						return
   313 					}
   391 					}
   314 				case err := <-watcher.Errors:
   392 
   315 					log.Println("error:", err)
   393 				case err, ok := <-watcher.Errors:
       
   394 					if ok { // 'Errors' channel is not closed
       
   395 						log.Printf("watcher error: %v\n", err)
       
   396 					}
       
   397 					eventsWG.Done()
       
   398 					return
   316 				}
   399 				}
   317 			}
   400 			}
   318 		}()
   401 		}()
   319 
       
   320 		watcher.Add(configDir)
   402 		watcher.Add(configDir)
   321 		<-done
   403 		initWG.Done()   // done initializing the watch in this go routine, so the parent routine can move on...
       
   404 		eventsWG.Wait() // now, wait for event loop to end in this go-routine...
   322 	}()
   405 	}()
       
   406 	initWG.Wait() // make sure that the go routine above fully ended before returning
   323 }
   407 }
   324 
   408 
   325 // SetConfigFile explicitly defines the path, name and extension of the config file.
   409 // 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.
   410 // Viper will use this and not check any of the config paths.
   327 func SetConfigFile(in string) { v.SetConfigFile(in) }
   411 func SetConfigFile(in string) { v.SetConfigFile(in) }
   347 	}
   431 	}
   348 
   432 
   349 	return strings.ToUpper(in)
   433 	return strings.ToUpper(in)
   350 }
   434 }
   351 
   435 
       
   436 // AllowEmptyEnv tells Viper to consider set,
       
   437 // but empty environment variables as valid values instead of falling back.
       
   438 // For backward compatibility reasons this is false by default.
       
   439 func AllowEmptyEnv(allowEmptyEnv bool) { v.AllowEmptyEnv(allowEmptyEnv) }
       
   440 func (v *Viper) AllowEmptyEnv(allowEmptyEnv bool) {
       
   441 	v.allowEmptyEnv = allowEmptyEnv
       
   442 }
       
   443 
   352 // TODO: should getEnv logic be moved into find(). Can generalize the use of
   444 // TODO: should getEnv logic be moved into find(). Can generalize the use of
   353 // rewriting keys many things, Ex: Get('someKey') -> some_key
   445 // rewriting keys many things, Ex: Get('someKey') -> some_key
   354 // (camel case to snake case for JSON keys perhaps)
   446 // (camel case to snake case for JSON keys perhaps)
   355 
   447 
   356 // getEnv is a wrapper around os.Getenv which replaces characters in the original
   448 // 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
   449 // key. This allows env vars which have different keys than the config object
   358 // keys.
   450 // keys.
   359 func (v *Viper) getEnv(key string) string {
   451 func (v *Viper) getEnv(key string) (string, bool) {
   360 	if v.envKeyReplacer != nil {
   452 	if v.envKeyReplacer != nil {
   361 		key = v.envKeyReplacer.Replace(key)
   453 		key = v.envKeyReplacer.Replace(key)
   362 	}
   454 	}
   363 	return os.Getenv(key)
   455 
       
   456 	val, ok := os.LookupEnv(key)
       
   457 
       
   458 	return val, ok && (v.allowEmptyEnv || val != "")
   364 }
   459 }
   365 
   460 
   366 // ConfigFileUsed returns the file used to populate the config registry.
   461 // ConfigFileUsed returns the file used to populate the config registry.
   367 func ConfigFileUsed() string            { return v.ConfigFileUsed() }
   462 func ConfigFileUsed() string            { return v.ConfigFileUsed() }
   368 func (v *Viper) ConfigFileUsed() string { return v.configFile }
   463 func (v *Viper) ConfigFileUsed() string { return v.configFile }
   585 // in the environment, when automatic env is on.
   680 // in the environment, when automatic env is on.
   586 // e.g., if "foo.bar" has a value in the environment, it “shadows”
   681 // e.g., if "foo.bar" has a value in the environment, it “shadows”
   587 //       "foo.bar.baz" in a lower-priority map
   682 //       "foo.bar.baz" in a lower-priority map
   588 func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
   683 func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
   589 	var parentKey string
   684 	var parentKey string
   590 	var val string
       
   591 	for i := 1; i < len(path); i++ {
   685 	for i := 1; i < len(path); i++ {
   592 		parentKey = strings.Join(path[0:i], v.keyDelim)
   686 		parentKey = strings.Join(path[0:i], v.keyDelim)
   593 		if val = v.getEnv(v.mergeWithEnvPrefix(parentKey)); val != "" {
   687 		if _, ok := v.getEnv(v.mergeWithEnvPrefix(parentKey)); ok {
   594 			return parentKey
   688 			return parentKey
   595 		}
   689 		}
   596 	}
   690 	}
   597 	return ""
   691 	return ""
   598 }
   692 }
   629 //
   723 //
   630 // Get returns an interface. For a specific value use one of the Get____ methods.
   724 // Get returns an interface. For a specific value use one of the Get____ methods.
   631 func Get(key string) interface{} { return v.Get(key) }
   725 func Get(key string) interface{} { return v.Get(key) }
   632 func (v *Viper) Get(key string) interface{} {
   726 func (v *Viper) Get(key string) interface{} {
   633 	lcaseKey := strings.ToLower(key)
   727 	lcaseKey := strings.ToLower(key)
   634 	val := v.find(lcaseKey)
   728 	val := v.find(lcaseKey, true)
   635 	if val == nil {
   729 	if val == nil {
   636 		return nil
   730 		return nil
   637 	}
   731 	}
   638 
   732 
   639 	if v.typeByDefValue {
   733 	if v.typeByDefValue {
   650 			return cast.ToBool(val)
   744 			return cast.ToBool(val)
   651 		case string:
   745 		case string:
   652 			return cast.ToString(val)
   746 			return cast.ToString(val)
   653 		case int32, int16, int8, int:
   747 		case int32, int16, int8, int:
   654 			return cast.ToInt(val)
   748 			return cast.ToInt(val)
       
   749 		case uint:
       
   750 			return cast.ToUint(val)
       
   751 		case uint32:
       
   752 			return cast.ToUint32(val)
       
   753 		case uint64:
       
   754 			return cast.ToUint64(val)
   655 		case int64:
   755 		case int64:
   656 			return cast.ToInt64(val)
   756 			return cast.ToInt64(val)
   657 		case float64, float32:
   757 		case float64, float32:
   658 			return cast.ToFloat64(val)
   758 			return cast.ToFloat64(val)
   659 		case time.Time:
   759 		case time.Time:
   660 			return cast.ToTime(val)
   760 			return cast.ToTime(val)
   661 		case time.Duration:
   761 		case time.Duration:
   662 			return cast.ToDuration(val)
   762 			return cast.ToDuration(val)
   663 		case []string:
   763 		case []string:
   664 			return cast.ToStringSlice(val)
   764 			return cast.ToStringSlice(val)
       
   765 		case []int:
       
   766 			return cast.ToIntSlice(val)
   665 		}
   767 		}
   666 	}
   768 	}
   667 
   769 
   668 	return val
   770 	return val
   669 }
   771 }
   713 func GetInt64(key string) int64 { return v.GetInt64(key) }
   815 func GetInt64(key string) int64 { return v.GetInt64(key) }
   714 func (v *Viper) GetInt64(key string) int64 {
   816 func (v *Viper) GetInt64(key string) int64 {
   715 	return cast.ToInt64(v.Get(key))
   817 	return cast.ToInt64(v.Get(key))
   716 }
   818 }
   717 
   819 
       
   820 // GetUint returns the value associated with the key as an unsigned integer.
       
   821 func GetUint(key string) uint { return v.GetUint(key) }
       
   822 func (v *Viper) GetUint(key string) uint {
       
   823 	return cast.ToUint(v.Get(key))
       
   824 }
       
   825 
       
   826 // GetUint32 returns the value associated with the key as an unsigned integer.
       
   827 func GetUint32(key string) uint32 { return v.GetUint32(key) }
       
   828 func (v *Viper) GetUint32(key string) uint32 {
       
   829 	return cast.ToUint32(v.Get(key))
       
   830 }
       
   831 
       
   832 // GetUint64 returns the value associated with the key as an unsigned integer.
       
   833 func GetUint64(key string) uint64 { return v.GetUint64(key) }
       
   834 func (v *Viper) GetUint64(key string) uint64 {
       
   835 	return cast.ToUint64(v.Get(key))
       
   836 }
       
   837 
   718 // GetFloat64 returns the value associated with the key as a float64.
   838 // GetFloat64 returns the value associated with the key as a float64.
   719 func GetFloat64(key string) float64 { return v.GetFloat64(key) }
   839 func GetFloat64(key string) float64 { return v.GetFloat64(key) }
   720 func (v *Viper) GetFloat64(key string) float64 {
   840 func (v *Viper) GetFloat64(key string) float64 {
   721 	return cast.ToFloat64(v.Get(key))
   841 	return cast.ToFloat64(v.Get(key))
   722 }
   842 }
   729 
   849 
   730 // GetDuration returns the value associated with the key as a duration.
   850 // GetDuration returns the value associated with the key as a duration.
   731 func GetDuration(key string) time.Duration { return v.GetDuration(key) }
   851 func GetDuration(key string) time.Duration { return v.GetDuration(key) }
   732 func (v *Viper) GetDuration(key string) time.Duration {
   852 func (v *Viper) GetDuration(key string) time.Duration {
   733 	return cast.ToDuration(v.Get(key))
   853 	return cast.ToDuration(v.Get(key))
       
   854 }
       
   855 
       
   856 // GetIntSlice returns the value associated with the key as a slice of int values.
       
   857 func GetIntSlice(key string) []int { return v.GetIntSlice(key) }
       
   858 func (v *Viper) GetIntSlice(key string) []int {
       
   859 	return cast.ToIntSlice(v.Get(key))
   734 }
   860 }
   735 
   861 
   736 // GetStringSlice returns the value associated with the key as a slice of strings.
   862 // GetStringSlice returns the value associated with the key as a slice of strings.
   737 func GetStringSlice(key string) []string { return v.GetStringSlice(key) }
   863 func GetStringSlice(key string) []string { return v.GetStringSlice(key) }
   738 func (v *Viper) GetStringSlice(key string) []string {
   864 func (v *Viper) GetStringSlice(key string) []string {
   774 
   900 
   775 	if err != nil {
   901 	if err != nil {
   776 		return err
   902 		return err
   777 	}
   903 	}
   778 
   904 
   779 	v.insensitiviseMaps()
       
   780 
       
   781 	return nil
   905 	return nil
   782 }
   906 }
   783 
   907 
   784 // Unmarshal unmarshals the config into a Struct. Make sure that the tags
   908 // Unmarshal unmarshals the config into a Struct. Make sure that the tags
   785 // on the fields of the structure are properly set.
   909 // on the fields of the structure are properly set.
   790 	err := decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...))
   914 	err := decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...))
   791 
   915 
   792 	if err != nil {
   916 	if err != nil {
   793 		return err
   917 		return err
   794 	}
   918 	}
   795 
       
   796 	v.insensitiviseMaps()
       
   797 
   919 
   798 	return nil
   920 	return nil
   799 }
   921 }
   800 
   922 
   801 // defaultDecoderConfig returns default mapsstructure.DecoderConfig with suppot
   923 // defaultDecoderConfig returns default mapsstructure.DecoderConfig with suppot
   825 	return decoder.Decode(input)
   947 	return decoder.Decode(input)
   826 }
   948 }
   827 
   949 
   828 // UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent
   950 // UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent
   829 // in the destination struct.
   951 // in the destination struct.
   830 func (v *Viper) UnmarshalExact(rawVal interface{}) error {
   952 func UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error {
   831 	config := defaultDecoderConfig(rawVal)
   953 	return v.UnmarshalExact(rawVal, opts...)
       
   954 }
       
   955 func (v *Viper) UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error {
       
   956 	config := defaultDecoderConfig(rawVal, opts...)
   832 	config.ErrorUnused = true
   957 	config.ErrorUnused = true
   833 
   958 
   834 	err := decode(v.AllSettings(), config)
   959 	err := decode(v.AllSettings(), config)
   835 
   960 
   836 	if err != nil {
   961 	if err != nil {
   837 		return err
   962 		return err
   838 	}
   963 	}
   839 
       
   840 	v.insensitiviseMaps()
       
   841 
   964 
   842 	return nil
   965 	return nil
   843 }
   966 }
   844 
   967 
   845 // BindPFlags binds a full flag set to the configuration, using each flag's long
   968 // BindPFlags binds a full flag set to the configuration, using each flag's long
   893 // EnvPrefix will be used when set when env name is not provided.
  1016 // EnvPrefix will be used when set when env name is not provided.
   894 func BindEnv(input ...string) error { return v.BindEnv(input...) }
  1017 func BindEnv(input ...string) error { return v.BindEnv(input...) }
   895 func (v *Viper) BindEnv(input ...string) error {
  1018 func (v *Viper) BindEnv(input ...string) error {
   896 	var key, envkey string
  1019 	var key, envkey string
   897 	if len(input) == 0 {
  1020 	if len(input) == 0 {
   898 		return fmt.Errorf("BindEnv missing key to bind to")
  1021 		return fmt.Errorf("missing key to bind to")
   899 	}
  1022 	}
   900 
  1023 
   901 	key = strings.ToLower(input[0])
  1024 	key = strings.ToLower(input[0])
   902 
  1025 
   903 	if len(input) == 1 {
  1026 	if len(input) == 1 {
   910 
  1033 
   911 	return nil
  1034 	return nil
   912 }
  1035 }
   913 
  1036 
   914 // Given a key, find the value.
  1037 // Given a key, find the value.
   915 // Viper will check in the following order:
  1038 //
   916 // flag, env, config file, key/value store, default.
       
   917 // Viper will check to see if an alias exists first.
  1039 // Viper will check to see if an alias exists first.
       
  1040 // Viper will then check in the following order:
       
  1041 // flag, env, config file, key/value store.
       
  1042 // Lastly, if no value was found and flagDefault is true, and if the key
       
  1043 // corresponds to a flag, the flag's default value is returned.
       
  1044 //
   918 // Note: this assumes a lower-cased key given.
  1045 // Note: this assumes a lower-cased key given.
   919 func (v *Viper) find(lcaseKey string) interface{} {
  1046 func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} {
   920 
       
   921 	var (
  1047 	var (
   922 		val    interface{}
  1048 		val    interface{}
   923 		exists bool
  1049 		exists bool
   924 		path   = strings.Split(lcaseKey, v.keyDelim)
  1050 		path   = strings.Split(lcaseKey, v.keyDelim)
   925 		nested = len(path) > 1
  1051 		nested = len(path) > 1
   955 		case "stringSlice":
  1081 		case "stringSlice":
   956 			s := strings.TrimPrefix(flag.ValueString(), "[")
  1082 			s := strings.TrimPrefix(flag.ValueString(), "[")
   957 			s = strings.TrimSuffix(s, "]")
  1083 			s = strings.TrimSuffix(s, "]")
   958 			res, _ := readAsCSV(s)
  1084 			res, _ := readAsCSV(s)
   959 			return res
  1085 			return res
       
  1086 		case "intSlice":
       
  1087 			s := strings.TrimPrefix(flag.ValueString(), "[")
       
  1088 			s = strings.TrimSuffix(s, "]")
       
  1089 			res, _ := readAsCSV(s)
       
  1090 			return cast.ToIntSlice(res)
   960 		default:
  1091 		default:
   961 			return flag.ValueString()
  1092 			return flag.ValueString()
   962 		}
  1093 		}
   963 	}
  1094 	}
   964 	if nested && v.isPathShadowedInFlatMap(path, v.pflags) != "" {
  1095 	if nested && v.isPathShadowedInFlatMap(path, v.pflags) != "" {
   967 
  1098 
   968 	// Env override next
  1099 	// Env override next
   969 	if v.automaticEnvApplied {
  1100 	if v.automaticEnvApplied {
   970 		// even if it hasn't been registered, if automaticEnv is used,
  1101 		// even if it hasn't been registered, if automaticEnv is used,
   971 		// check any Get request
  1102 		// check any Get request
   972 		if val = v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); val != "" {
  1103 		if val, ok := v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); ok {
   973 			return val
  1104 			return val
   974 		}
  1105 		}
   975 		if nested && v.isPathShadowedInAutoEnv(path) != "" {
  1106 		if nested && v.isPathShadowedInAutoEnv(path) != "" {
   976 			return nil
  1107 			return nil
   977 		}
  1108 		}
   978 	}
  1109 	}
   979 	envkey, exists := v.env[lcaseKey]
  1110 	envkey, exists := v.env[lcaseKey]
   980 	if exists {
  1111 	if exists {
   981 		if val = v.getEnv(envkey); val != "" {
  1112 		if val, ok := v.getEnv(envkey); ok {
   982 			return val
  1113 			return val
   983 		}
  1114 		}
   984 	}
  1115 	}
   985 	if nested && v.isPathShadowedInFlatMap(path, v.env) != "" {
  1116 	if nested && v.isPathShadowedInFlatMap(path, v.env) != "" {
   986 		return nil
  1117 		return nil
  1011 	}
  1142 	}
  1012 	if nested && v.isPathShadowedInDeepMap(path, v.defaults) != "" {
  1143 	if nested && v.isPathShadowedInDeepMap(path, v.defaults) != "" {
  1013 		return nil
  1144 		return nil
  1014 	}
  1145 	}
  1015 
  1146 
  1016 	// last chance: if no other value is returned and a flag does exist for the value,
  1147 	if flagDefault {
  1017 	// get the flag's value even if the flag's value has not changed
  1148 		// last chance: if no value is found and a flag does exist for the key,
  1018 	if flag, exists := v.pflags[lcaseKey]; exists {
  1149 		// get the flag's default value even if the flag's value has not been set.
  1019 		switch flag.ValueType() {
  1150 		if flag, exists := v.pflags[lcaseKey]; exists {
  1020 		case "int", "int8", "int16", "int32", "int64":
  1151 			switch flag.ValueType() {
  1021 			return cast.ToInt(flag.ValueString())
  1152 			case "int", "int8", "int16", "int32", "int64":
  1022 		case "bool":
  1153 				return cast.ToInt(flag.ValueString())
  1023 			return cast.ToBool(flag.ValueString())
  1154 			case "bool":
  1024 		case "stringSlice":
  1155 				return cast.ToBool(flag.ValueString())
  1025 			s := strings.TrimPrefix(flag.ValueString(), "[")
  1156 			case "stringSlice":
  1026 			s = strings.TrimSuffix(s, "]")
  1157 				s := strings.TrimPrefix(flag.ValueString(), "[")
  1027 			res, _ := readAsCSV(s)
  1158 				s = strings.TrimSuffix(s, "]")
  1028 			return res
  1159 				res, _ := readAsCSV(s)
  1029 		default:
  1160 				return res
  1030 			return flag.ValueString()
  1161 			case "intSlice":
  1031 		}
  1162 				s := strings.TrimPrefix(flag.ValueString(), "[")
  1032 	}
  1163 				s = strings.TrimSuffix(s, "]")
  1033 	// last item, no need to check shadowing
  1164 				res, _ := readAsCSV(s)
       
  1165 				return cast.ToIntSlice(res)
       
  1166 			default:
       
  1167 				return flag.ValueString()
       
  1168 			}
       
  1169 		}
       
  1170 		// last item, no need to check shadowing
       
  1171 	}
  1034 
  1172 
  1035 	return nil
  1173 	return nil
  1036 }
  1174 }
  1037 
  1175 
  1038 func readAsCSV(val string) ([]string, error) {
  1176 func readAsCSV(val string) ([]string, error) {
  1047 // IsSet checks to see if the key has been set in any of the data locations.
  1185 // IsSet checks to see if the key has been set in any of the data locations.
  1048 // IsSet is case-insensitive for a key.
  1186 // IsSet is case-insensitive for a key.
  1049 func IsSet(key string) bool { return v.IsSet(key) }
  1187 func IsSet(key string) bool { return v.IsSet(key) }
  1050 func (v *Viper) IsSet(key string) bool {
  1188 func (v *Viper) IsSet(key string) bool {
  1051 	lcaseKey := strings.ToLower(key)
  1189 	lcaseKey := strings.ToLower(key)
  1052 	val := v.find(lcaseKey)
  1190 	val := v.find(lcaseKey, false)
  1053 	return val != nil
  1191 	return val != nil
  1054 }
  1192 }
  1055 
  1193 
  1056 // AutomaticEnv has Viper check ENV variables for all.
  1194 // AutomaticEnv has Viper check ENV variables for all.
  1057 // keys set in config, default & flags
  1195 // keys set in config, default & flags
  1066 func SetEnvKeyReplacer(r *strings.Replacer) { v.SetEnvKeyReplacer(r) }
  1204 func SetEnvKeyReplacer(r *strings.Replacer) { v.SetEnvKeyReplacer(r) }
  1067 func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) {
  1205 func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) {
  1068 	v.envKeyReplacer = r
  1206 	v.envKeyReplacer = r
  1069 }
  1207 }
  1070 
  1208 
  1071 // Aliases provide another accessor for the same key.
  1209 // RegisterAlias creates an alias that provides another accessor for the same key.
  1072 // This enables one to change a name without breaking the application
  1210 // This enables one to change a name without breaking the application.
  1073 func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) }
  1211 func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) }
  1074 func (v *Viper) RegisterAlias(alias string, key string) {
  1212 func (v *Viper) RegisterAlias(alias string, key string) {
  1075 	v.registerAlias(alias, strings.ToLower(key))
  1213 	v.registerAlias(alias, strings.ToLower(key))
  1076 }
  1214 }
  1077 
  1215 
  1222 }
  1360 }
  1223 
  1361 
  1224 // MergeConfig merges a new configuration with an existing config.
  1362 // MergeConfig merges a new configuration with an existing config.
  1225 func MergeConfig(in io.Reader) error { return v.MergeConfig(in) }
  1363 func MergeConfig(in io.Reader) error { return v.MergeConfig(in) }
  1226 func (v *Viper) MergeConfig(in io.Reader) error {
  1364 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{})
  1365 	cfg := make(map[string]interface{})
  1231 	if err := v.unmarshalReader(in, cfg); err != nil {
  1366 	if err := v.unmarshalReader(in, cfg); err != nil {
  1232 		return err
  1367 		return err
  1233 	}
  1368 	}
       
  1369 	return v.MergeConfigMap(cfg)
       
  1370 }
       
  1371 
       
  1372 // MergeConfigMap merges the configuration from the map given with an existing config.
       
  1373 // Note that the map given may be modified.
       
  1374 func MergeConfigMap(cfg map[string]interface{}) error { return v.MergeConfigMap(cfg) }
       
  1375 func (v *Viper) MergeConfigMap(cfg map[string]interface{}) error {
       
  1376 	if v.config == nil {
       
  1377 		v.config = make(map[string]interface{})
       
  1378 	}
       
  1379 	insensitiviseMap(cfg)
  1234 	mergeMaps(cfg, v.config, nil)
  1380 	mergeMaps(cfg, v.config, nil)
  1235 	return nil
  1381 	return nil
  1236 }
  1382 }
  1237 
  1383 
  1238 // WriteConfig writes the current configuration to a file.
  1384 // WriteConfig writes the current configuration to a file.
  1246 }
  1392 }
  1247 
  1393 
  1248 // SafeWriteConfig writes current configuration to file only if the file does not exist.
  1394 // SafeWriteConfig writes current configuration to file only if the file does not exist.
  1249 func SafeWriteConfig() error { return v.SafeWriteConfig() }
  1395 func SafeWriteConfig() error { return v.SafeWriteConfig() }
  1250 func (v *Viper) SafeWriteConfig() error {
  1396 func (v *Viper) SafeWriteConfig() error {
  1251 	filename, err := v.getConfigFile()
  1397 	if len(v.configPaths) < 1 {
  1252 	if err != nil {
  1398 		return errors.New("missing configuration for 'configPath'")
  1253 		return err
  1399 	}
  1254 	}
  1400 	return v.SafeWriteConfigAs(filepath.Join(v.configPaths[0], v.configName+"."+v.configType))
  1255 	return v.writeConfig(filename, false)
       
  1256 }
  1401 }
  1257 
  1402 
  1258 // WriteConfigAs writes current configuration to a given filename.
  1403 // WriteConfigAs writes current configuration to a given filename.
  1259 func WriteConfigAs(filename string) error { return v.WriteConfigAs(filename) }
  1404 func WriteConfigAs(filename string) error { return v.WriteConfigAs(filename) }
  1260 func (v *Viper) WriteConfigAs(filename string) error {
  1405 func (v *Viper) WriteConfigAs(filename string) error {
  1262 }
  1407 }
  1263 
  1408 
  1264 // SafeWriteConfigAs writes current configuration to a given filename if it does not exist.
  1409 // SafeWriteConfigAs writes current configuration to a given filename if it does not exist.
  1265 func SafeWriteConfigAs(filename string) error { return v.SafeWriteConfigAs(filename) }
  1410 func SafeWriteConfigAs(filename string) error { return v.SafeWriteConfigAs(filename) }
  1266 func (v *Viper) SafeWriteConfigAs(filename string) error {
  1411 func (v *Viper) SafeWriteConfigAs(filename string) error {
       
  1412 	alreadyExists, err := afero.Exists(v.fs, filename)
       
  1413 	if alreadyExists && err == nil {
       
  1414 		return ConfigFileAlreadyExistsError(filename)
       
  1415 	}
  1267 	return v.writeConfig(filename, false)
  1416 	return v.writeConfig(filename, false)
  1268 }
  1417 }
  1269 
  1418 
  1270 func writeConfig(filename string, force bool) error { return v.writeConfig(filename, force) }
       
  1271 func (v *Viper) writeConfig(filename string, force bool) error {
  1419 func (v *Viper) writeConfig(filename string, force bool) error {
  1272 	jww.INFO.Println("Attempting to write configuration to file.")
  1420 	jww.INFO.Println("Attempting to write configuration to file.")
  1273 	ext := filepath.Ext(filename)
  1421 	ext := filepath.Ext(filename)
  1274 	if len(ext) <= 1 {
  1422 	if len(ext) <= 1 {
  1275 		return fmt.Errorf("Filename: %s requires valid extension.", filename)
  1423 		return fmt.Errorf("filename: %s requires valid extension", filename)
  1276 	}
  1424 	}
  1277 	configType := ext[1:]
  1425 	configType := ext[1:]
  1278 	if !stringInSlice(configType, SupportedExts) {
  1426 	if !stringInSlice(configType, SupportedExts) {
  1279 		return UnsupportedConfigError(configType)
  1427 		return UnsupportedConfigError(configType)
  1280 	}
  1428 	}
  1281 	if v.config == nil {
  1429 	if v.config == nil {
  1282 		v.config = make(map[string]interface{})
  1430 		v.config = make(map[string]interface{})
  1283 	}
  1431 	}
  1284 	var flags int
  1432 	flags := os.O_CREATE | os.O_TRUNC | os.O_WRONLY
  1285 	if force == true {
  1433 	if !force {
  1286 		flags = os.O_CREATE | os.O_TRUNC | os.O_WRONLY
  1434 		flags |= os.O_EXCL
  1287 	} else {
  1435 	}
  1288 		if _, err := os.Stat(filename); os.IsNotExist(err) {
  1436 	f, err := v.fs.OpenFile(filename, flags, v.configPermissions)
  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 {
  1437 	if err != nil {
  1296 		return err
  1438 		return err
  1297 	}
  1439 	}
  1298 	return v.marshalWriter(f, configType)
  1440 	defer f.Close()
       
  1441 
       
  1442 	if err := v.marshalWriter(f, configType); err != nil {
       
  1443 		return err
       
  1444 	}
       
  1445 
       
  1446 	return f.Sync()
  1299 }
  1447 }
  1300 
  1448 
  1301 // Unmarshal a Reader into a map.
  1449 // Unmarshal a Reader into a map.
  1302 // Should probably be an unexported function.
  1450 // Should probably be an unexported function.
  1303 func unmarshalReader(in io.Reader, c map[string]interface{}) error {
  1451 func unmarshalReader(in io.Reader, c map[string]interface{}) error {
  1317 		if err := json.Unmarshal(buf.Bytes(), &c); err != nil {
  1465 		if err := json.Unmarshal(buf.Bytes(), &c); err != nil {
  1318 			return ConfigParseError{err}
  1466 			return ConfigParseError{err}
  1319 		}
  1467 		}
  1320 
  1468 
  1321 	case "hcl":
  1469 	case "hcl":
  1322 		obj, err := hcl.Parse(string(buf.Bytes()))
  1470 		obj, err := hcl.Parse(buf.String())
  1323 		if err != nil {
  1471 		if err != nil {
  1324 			return ConfigParseError{err}
  1472 			return ConfigParseError{err}
  1325 		}
  1473 		}
  1326 		if err = hcl.DecodeObject(&c, obj); err != nil {
  1474 		if err = hcl.DecodeObject(&c, obj); err != nil {
  1327 			return ConfigParseError{err}
  1475 			return ConfigParseError{err}
  1332 		if err != nil {
  1480 		if err != nil {
  1333 			return ConfigParseError{err}
  1481 			return ConfigParseError{err}
  1334 		}
  1482 		}
  1335 		tmap := tree.ToMap()
  1483 		tmap := tree.ToMap()
  1336 		for k, v := range tmap {
  1484 		for k, v := range tmap {
       
  1485 			c[k] = v
       
  1486 		}
       
  1487 
       
  1488 	case "dotenv", "env":
       
  1489 		env, err := gotenv.StrictParse(buf)
       
  1490 		if err != nil {
       
  1491 			return ConfigParseError{err}
       
  1492 		}
       
  1493 		for k, v := range env {
  1337 			c[k] = v
  1494 			c[k] = v
  1338 		}
  1495 		}
  1339 
  1496 
  1340 	case "properties", "props", "prop":
  1497 	case "properties", "props", "prop":
  1341 		v.properties = properties.NewProperties()
  1498 		v.properties = properties.NewProperties()
  1350 			lastKey := strings.ToLower(path[len(path)-1])
  1507 			lastKey := strings.ToLower(path[len(path)-1])
  1351 			deepestMap := deepSearch(c, path[0:len(path)-1])
  1508 			deepestMap := deepSearch(c, path[0:len(path)-1])
  1352 			// set innermost value
  1509 			// set innermost value
  1353 			deepestMap[lastKey] = value
  1510 			deepestMap[lastKey] = value
  1354 		}
  1511 		}
       
  1512 
       
  1513 	case "ini":
       
  1514 		cfg := ini.Empty()
       
  1515 		err := cfg.Append(buf.Bytes())
       
  1516 		if err != nil {
       
  1517 			return ConfigParseError{err}
       
  1518 		}
       
  1519 		sections := cfg.Sections()
       
  1520 		for i := 0; i < len(sections); i++ {
       
  1521 			section := sections[i]
       
  1522 			keys := section.Keys()
       
  1523 			for j := 0; j < len(keys); j++ {
       
  1524 				key := keys[j]
       
  1525 				value := cfg.Section(section.Name()).Key(key.Name()).String()
       
  1526 				c[section.Name()+"."+key.Name()] = value
       
  1527 			}
       
  1528 		}
  1355 	}
  1529 	}
  1356 
  1530 
  1357 	insensitiviseMap(c)
  1531 	insensitiviseMap(c)
  1358 	return nil
  1532 	return nil
  1359 }
  1533 }
  1360 
  1534 
  1361 // Marshal a map into Writer.
  1535 // 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 {
  1536 func (v *Viper) marshalWriter(f afero.File, configType string) error {
  1366 	c := v.AllSettings()
  1537 	c := v.AllSettings()
  1367 	switch configType {
  1538 	switch configType {
  1368 	case "json":
  1539 	case "json":
  1369 		b, err := json.MarshalIndent(c, "", "  ")
  1540 		b, err := json.MarshalIndent(c, "", "  ")
  1375 			return ConfigMarshalError{err}
  1546 			return ConfigMarshalError{err}
  1376 		}
  1547 		}
  1377 
  1548 
  1378 	case "hcl":
  1549 	case "hcl":
  1379 		b, err := json.Marshal(c)
  1550 		b, err := json.Marshal(c)
       
  1551 		if err != nil {
       
  1552 			return ConfigMarshalError{err}
       
  1553 		}
  1380 		ast, err := hcl.Parse(string(b))
  1554 		ast, err := hcl.Parse(string(b))
  1381 		if err != nil {
  1555 		if err != nil {
  1382 			return ConfigMarshalError{err}
  1556 			return ConfigMarshalError{err}
  1383 		}
  1557 		}
  1384 		err = printer.Fprint(f, ast.Node)
  1558 		err = printer.Fprint(f, ast.Node)
  1400 		_, err := p.WriteComment(f, "#", properties.UTF8)
  1574 		_, err := p.WriteComment(f, "#", properties.UTF8)
  1401 		if err != nil {
  1575 		if err != nil {
  1402 			return ConfigMarshalError{err}
  1576 			return ConfigMarshalError{err}
  1403 		}
  1577 		}
  1404 
  1578 
       
  1579 	case "dotenv", "env":
       
  1580 		lines := []string{}
       
  1581 		for _, key := range v.AllKeys() {
       
  1582 			envName := strings.ToUpper(strings.Replace(key, ".", "_", -1))
       
  1583 			val := v.Get(key)
       
  1584 			lines = append(lines, fmt.Sprintf("%v=%v", envName, val))
       
  1585 		}
       
  1586 		s := strings.Join(lines, "\n")
       
  1587 		if _, err := f.WriteString(s); err != nil {
       
  1588 			return ConfigMarshalError{err}
       
  1589 		}
       
  1590 
  1405 	case "toml":
  1591 	case "toml":
  1406 		t, err := toml.TreeFromMap(c)
  1592 		t, err := toml.TreeFromMap(c)
  1407 		if err != nil {
  1593 		if err != nil {
  1408 			return ConfigMarshalError{err}
  1594 			return ConfigMarshalError{err}
  1409 		}
  1595 		}
  1418 			return ConfigMarshalError{err}
  1604 			return ConfigMarshalError{err}
  1419 		}
  1605 		}
  1420 		if _, err = f.WriteString(string(b)); err != nil {
  1606 		if _, err = f.WriteString(string(b)); err != nil {
  1421 			return ConfigMarshalError{err}
  1607 			return ConfigMarshalError{err}
  1422 		}
  1608 		}
       
  1609 
       
  1610 	case "ini":
       
  1611 		keys := v.AllKeys()
       
  1612 		cfg := ini.Empty()
       
  1613 		ini.PrettyFormat = false
       
  1614 		for i := 0; i < len(keys); i++ {
       
  1615 			key := keys[i]
       
  1616 			lastSep := strings.LastIndex(key, ".")
       
  1617 			sectionName := key[:(lastSep)]
       
  1618 			keyName := key[(lastSep + 1):]
       
  1619 			if sectionName == "default" {
       
  1620 				sectionName = ""
       
  1621 			}
       
  1622 			cfg.Section(sectionName).Key(keyName).SetValue(Get(key).(string))
       
  1623 		}
       
  1624 		cfg.WriteTo(f)
  1423 	}
  1625 	}
  1424 	return nil
  1626 	return nil
  1425 }
  1627 }
  1426 
  1628 
  1427 func keyExists(k string, m map[string]interface{}) string {
  1629 func keyExists(k string, m map[string]interface{}) string {
  1534 
  1736 
  1535 func (v *Viper) WatchRemoteConfigOnChannel() error {
  1737 func (v *Viper) WatchRemoteConfigOnChannel() error {
  1536 	return v.watchKeyValueConfigOnChannel()
  1738 	return v.watchKeyValueConfigOnChannel()
  1537 }
  1739 }
  1538 
  1740 
  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.
  1741 // Retrieve the first found remote configuration.
  1547 func (v *Viper) getKeyValueConfig() error {
  1742 func (v *Viper) getKeyValueConfig() error {
  1548 	if RemoteConfig == nil {
  1743 	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'")
  1744 		return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ github.com/spf13/viper/remote'")
  1550 	}
  1745 	}
  1571 
  1766 
  1572 // Retrieve the first found remote configuration.
  1767 // Retrieve the first found remote configuration.
  1573 func (v *Viper) watchKeyValueConfigOnChannel() error {
  1768 func (v *Viper) watchKeyValueConfigOnChannel() error {
  1574 	for _, rp := range v.remoteProviders {
  1769 	for _, rp := range v.remoteProviders {
  1575 		respc, _ := RemoteConfig.WatchChannel(rp)
  1770 		respc, _ := RemoteConfig.WatchChannel(rp)
  1576 		//Todo: Add quit channel
  1771 		// Todo: Add quit channel
  1577 		go func(rc <-chan *RemoteResponse) {
  1772 		go func(rc <-chan *RemoteResponse) {
  1578 			for {
  1773 			for {
  1579 				b := <-rc
  1774 				b := <-rc
  1580 				reader := bytes.NewReader(b.Value)
  1775 				reader := bytes.NewReader(b.Value)
  1581 				v.unmarshalReader(reader, v.kvstore)
  1776 				v.unmarshalReader(reader, v.kvstore)
  1607 	err = v.unmarshalReader(reader, v.kvstore)
  1802 	err = v.unmarshalReader(reader, v.kvstore)
  1608 	return v.kvstore, err
  1803 	return v.kvstore, err
  1609 }
  1804 }
  1610 
  1805 
  1611 // AllKeys returns all keys holding a value, regardless of where they are set.
  1806 // AllKeys returns all keys holding a value, regardless of where they are set.
  1612 // Nested keys are returned with a v.keyDelim (= ".") separator
  1807 // Nested keys are returned with a v.keyDelim separator
  1613 func AllKeys() []string { return v.AllKeys() }
  1808 func AllKeys() []string { return v.AllKeys() }
  1614 func (v *Viper) AllKeys() []string {
  1809 func (v *Viper) AllKeys() []string {
  1615 	m := map[string]bool{}
  1810 	m := map[string]bool{}
  1616 	// add all paths, by order of descending priority to ensure correct shadowing
  1811 	// add all paths, by order of descending priority to ensure correct shadowing
  1617 	m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "")
  1812 	m = v.flattenAndMergeMap(m, castMapStringToMapInterface(v.aliases), "")
  1621 	m = v.flattenAndMergeMap(m, v.config, "")
  1816 	m = v.flattenAndMergeMap(m, v.config, "")
  1622 	m = v.flattenAndMergeMap(m, v.kvstore, "")
  1817 	m = v.flattenAndMergeMap(m, v.kvstore, "")
  1623 	m = v.flattenAndMergeMap(m, v.defaults, "")
  1818 	m = v.flattenAndMergeMap(m, v.defaults, "")
  1624 
  1819 
  1625 	// convert set of paths to list
  1820 	// convert set of paths to list
  1626 	a := []string{}
  1821 	a := make([]string, 0, len(m))
  1627 	for x := range m {
  1822 	for x := range m {
  1628 		a = append(a, x)
  1823 		a = append(a, x)
  1629 	}
  1824 	}
  1630 	return a
  1825 	return a
  1631 }
  1826 }
  1632 
  1827 
  1633 // flattenAndMergeMap recursively flattens the given map into a map[string]bool
  1828 // 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):
  1829 // 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 (= ".")
  1830 // - 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,
  1831 // - if a path is shadowed by an earlier value in the initial shadow map,
  1637 //   it is skipped.
  1832 //   it is skipped.
  1638 // The resulting set of paths is merged to the given shadow set at the same time.
  1833 // 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 {
  1834 func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool {
  1640 	if shadow != nil && prefix != "" && shadow[prefix] {
  1835 	if shadow != nil && prefix != "" && shadow[prefix] {
  1670 // mergeFlatMap merges the given maps, excluding values of the second map
  1865 // mergeFlatMap merges the given maps, excluding values of the second map
  1671 // shadowed by values from the first map.
  1866 // shadowed by values from the first map.
  1672 func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool {
  1867 func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool {
  1673 	// scan keys
  1868 	// scan keys
  1674 outer:
  1869 outer:
  1675 	for k, _ := range m {
  1870 	for k := range m {
  1676 		path := strings.Split(k, v.keyDelim)
  1871 		path := strings.Split(k, v.keyDelim)
  1677 		// scan intermediate paths
  1872 		// scan intermediate paths
  1678 		var parentKey string
  1873 		var parentKey string
  1679 		for i := 1; i < len(path); i++ {
  1874 		for i := 1; i < len(path); i++ {
  1680 			parentKey = strings.Join(path[0:i], v.keyDelim)
  1875 			parentKey = strings.Join(path[0:i], v.keyDelim)
  1733 	if in != "" {
  1928 	if in != "" {
  1734 		v.configType = in
  1929 		v.configType = in
  1735 	}
  1930 	}
  1736 }
  1931 }
  1737 
  1932 
       
  1933 // SetConfigPermissions sets the permissions for the config file.
       
  1934 func SetConfigPermissions(perm os.FileMode) { v.SetConfigPermissions(perm) }
       
  1935 func (v *Viper) SetConfigPermissions(perm os.FileMode) {
       
  1936 	v.configPermissions = perm.Perm()
       
  1937 }
       
  1938 
  1738 func (v *Viper) getConfigType() string {
  1939 func (v *Viper) getConfigType() string {
  1739 	if v.configType != "" {
  1940 	if v.configType != "" {
  1740 		return v.configType
  1941 		return v.configType
  1741 	}
  1942 	}
  1742 
  1943 
  1770 	for _, ext := range SupportedExts {
  1971 	for _, ext := range SupportedExts {
  1771 		jww.DEBUG.Println("Checking for", filepath.Join(in, v.configName+"."+ext))
  1972 		jww.DEBUG.Println("Checking for", filepath.Join(in, v.configName+"."+ext))
  1772 		if b, _ := exists(v.fs, filepath.Join(in, v.configName+"."+ext)); b {
  1973 		if b, _ := exists(v.fs, filepath.Join(in, v.configName+"."+ext)); b {
  1773 			jww.DEBUG.Println("Found: ", filepath.Join(in, v.configName+"."+ext))
  1974 			jww.DEBUG.Println("Found: ", filepath.Join(in, v.configName+"."+ext))
  1774 			return filepath.Join(in, v.configName+"."+ext)
  1975 			return filepath.Join(in, v.configName+"."+ext)
       
  1976 		}
       
  1977 	}
       
  1978 
       
  1979 	if v.configType != "" {
       
  1980 		if b, _ := exists(v.fs, filepath.Join(in, v.configName)); b {
       
  1981 			return filepath.Join(in, v.configName)
  1775 		}
  1982 		}
  1776 	}
  1983 	}
  1777 
  1984 
  1778 	return ""
  1985 	return ""
  1779 }
  1986 }