vendor/github.com/spf13/viper/viper.go
changeset 262 8d3354485fc3
parent 260 445e01aede7e
child 265 05c40b36d3b2
equal deleted inserted replaced
261:270cc4dda0c5 262:8d3354485fc3
   130 type DecoderConfigOption func(*mapstructure.DecoderConfig)
   130 type DecoderConfigOption func(*mapstructure.DecoderConfig)
   131 
   131 
   132 // DecodeHook returns a DecoderConfigOption which overrides the default
   132 // DecodeHook returns a DecoderConfigOption which overrides the default
   133 // DecoderConfig.DecodeHook value, the default is:
   133 // DecoderConfig.DecodeHook value, the default is:
   134 //
   134 //
   135 //  mapstructure.ComposeDecodeHookFunc(
   135 //	 mapstructure.ComposeDecodeHookFunc(
   136 //		mapstructure.StringToTimeDurationHookFunc(),
   136 //			mapstructure.StringToTimeDurationHookFunc(),
   137 //		mapstructure.StringToSliceHookFunc(","),
   137 //			mapstructure.StringToSliceHookFunc(","),
   138 //	)
   138 //		)
   139 func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption {
   139 func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption {
   140 	return func(c *mapstructure.DecoderConfig) {
   140 	return func(c *mapstructure.DecoderConfig) {
   141 		c.DecodeHook = hook
   141 		c.DecodeHook = hook
   142 	}
   142 	}
   143 }
   143 }
   154 // 5. key/value store
   154 // 5. key/value store
   155 // 6. defaults
   155 // 6. defaults
   156 //
   156 //
   157 // For example, if values from the following sources were loaded:
   157 // For example, if values from the following sources were loaded:
   158 //
   158 //
   159 //  Defaults : {
   159 //	Defaults : {
   160 //  	"secret": "",
   160 //		"secret": "",
   161 //  	"user": "default",
   161 //		"user": "default",
   162 //  	"endpoint": "https://localhost"
   162 //		"endpoint": "https://localhost"
   163 //  }
   163 //	}
   164 //  Config : {
   164 //	Config : {
   165 //  	"user": "root"
   165 //		"user": "root"
   166 //  	"secret": "defaultsecret"
   166 //		"secret": "defaultsecret"
   167 //  }
   167 //	}
   168 //  Env : {
   168 //	Env : {
   169 //  	"secret": "somesecretkey"
   169 //		"secret": "somesecretkey"
   170 //  }
   170 //	}
   171 //
   171 //
   172 // The resulting config will have the following values:
   172 // The resulting config will have the following values:
   173 //
   173 //
   174 //	{
   174 //	{
   175 //		"secret": "somesecretkey",
   175 //		"secret": "somesecretkey",
   298 // In the public interface for the viper package so applications
   298 // In the public interface for the viper package so applications
   299 // can use it in their testing as well.
   299 // can use it in their testing as well.
   300 func Reset() {
   300 func Reset() {
   301 	v = New()
   301 	v = New()
   302 	SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"}
   302 	SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"}
   303 	SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
   303 	SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore"}
   304 }
   304 }
   305 
   305 
   306 // TODO: make this lazy initialization instead
   306 // TODO: make this lazy initialization instead
   307 func (v *Viper) resetEncoding() {
   307 func (v *Viper) resetEncoding() {
   308 	encoderRegistry := encoding.NewEncoderRegistry()
   308 	encoderRegistry := encoding.NewEncoderRegistry()
   417 
   417 
   418 // SupportedExts are universally supported extensions.
   418 // SupportedExts are universally supported extensions.
   419 var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"}
   419 var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"}
   420 
   420 
   421 // SupportedRemoteProviders are universally supported remote providers.
   421 // SupportedRemoteProviders are universally supported remote providers.
   422 var SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
   422 var SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore"}
   423 
   423 
   424 func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
   424 func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
   425 func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) {
   425 func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) {
   426 	v.onConfigChange = run
   426 	v.onConfigChange = run
   427 }
   427 }
   571 	}
   571 	}
   572 }
   572 }
   573 
   573 
   574 // AddRemoteProvider adds a remote configuration source.
   574 // AddRemoteProvider adds a remote configuration source.
   575 // Remote Providers are searched in the order they are added.
   575 // Remote Providers are searched in the order they are added.
   576 // provider is a string value: "etcd", "consul" or "firestore" are currently supported.
   576 // provider is a string value: "etcd", "etcd3", "consul" or "firestore" are currently supported.
   577 // endpoint is the url.  etcd requires http://ip:port  consul requires ip:port
   577 // endpoint is the url.  etcd requires http://ip:port  consul requires ip:port
   578 // path is the path in the k/v store to retrieve configuration
   578 // path is the path in the k/v store to retrieve configuration
   579 // To retrieve a config file called myapp.json from /configs/myapp.json
   579 // To retrieve a config file called myapp.json from /configs/myapp.json
   580 // you should set path to /configs and set config name (SetConfigName()) to
   580 // you should set path to /configs and set config name (SetConfigName()) to
   581 // "myapp"
   581 // "myapp"
   602 	return nil
   602 	return nil
   603 }
   603 }
   604 
   604 
   605 // AddSecureRemoteProvider adds a remote configuration source.
   605 // AddSecureRemoteProvider adds a remote configuration source.
   606 // Secure Remote Providers are searched in the order they are added.
   606 // Secure Remote Providers are searched in the order they are added.
   607 // provider is a string value: "etcd", "consul" or "firestore" are currently supported.
   607 // provider is a string value: "etcd", "etcd3", "consul" or "firestore" are currently supported.
   608 // endpoint is the url.  etcd requires http://ip:port  consul requires ip:port
   608 // endpoint is the url.  etcd requires http://ip:port  consul requires ip:port
   609 // secretkeyring is the filepath to your openpgp secret keyring.  e.g. /etc/secrets/myring.gpg
   609 // secretkeyring is the filepath to your openpgp secret keyring.  e.g. /etc/secrets/myring.gpg
   610 // path is the path in the k/v store to retrieve configuration
   610 // path is the path in the k/v store to retrieve configuration
   611 // To retrieve a config file called myapp.json from /configs/myapp.json
   611 // To retrieve a config file called myapp.json from /configs/myapp.json
   612 // you should set path to /configs and set config name (SetConfigName()) to
   612 // you should set path to /configs and set config name (SetConfigName()) to
   783 }
   783 }
   784 
   784 
   785 // isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere
   785 // isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere
   786 // on its path in the map.
   786 // on its path in the map.
   787 // e.g., if "foo.bar" has a value in the given map, it “shadows”
   787 // e.g., if "foo.bar" has a value in the given map, it “shadows”
   788 //       "foo.bar.baz" in a lower-priority map
   788 //
       
   789 //	"foo.bar.baz" in a lower-priority map
   789 func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string {
   790 func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string {
   790 	var parentVal interface{}
   791 	var parentVal interface{}
   791 	for i := 1; i < len(path); i++ {
   792 	for i := 1; i < len(path); i++ {
   792 		parentVal = v.searchMap(m, path[0:i])
   793 		parentVal = v.searchMap(m, path[0:i])
   793 		if parentVal == nil {
   794 		if parentVal == nil {
   808 }
   809 }
   809 
   810 
   810 // isPathShadowedInFlatMap makes sure the given path is not shadowed somewhere
   811 // isPathShadowedInFlatMap makes sure the given path is not shadowed somewhere
   811 // in a sub-path of the map.
   812 // in a sub-path of the map.
   812 // e.g., if "foo.bar" has a value in the given map, it “shadows”
   813 // e.g., if "foo.bar" has a value in the given map, it “shadows”
   813 //       "foo.bar.baz" in a lower-priority map
   814 //
       
   815 //	"foo.bar.baz" in a lower-priority map
   814 func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
   816 func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
   815 	// unify input map
   817 	// unify input map
   816 	var m map[string]interface{}
   818 	var m map[string]interface{}
   817 	switch mi.(type) {
   819 	switch mi.(type) {
   818 	case map[string]string, map[string]FlagValue:
   820 	case map[string]string, map[string]FlagValue:
   833 }
   835 }
   834 
   836 
   835 // isPathShadowedInAutoEnv makes sure the given path is not shadowed somewhere
   837 // isPathShadowedInAutoEnv makes sure the given path is not shadowed somewhere
   836 // in the environment, when automatic env is on.
   838 // in the environment, when automatic env is on.
   837 // e.g., if "foo.bar" has a value in the environment, it “shadows”
   839 // e.g., if "foo.bar" has a value in the environment, it “shadows”
   838 //       "foo.bar.baz" in a lower-priority map
   840 //
       
   841 //	"foo.bar.baz" in a lower-priority map
   839 func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
   842 func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
   840 	var parentKey string
   843 	var parentKey string
   841 	for i := 1; i < len(path); i++ {
   844 	for i := 1; i < len(path); i++ {
   842 		parentKey = strings.Join(path[0:i], v.keyDelim)
   845 		parentKey = strings.Join(path[0:i], v.keyDelim)
   843 		if _, ok := v.getEnv(v.mergeWithEnvPrefix(parentKey)); ok {
   846 		if _, ok := v.getEnv(v.mergeWithEnvPrefix(parentKey)); ok {
   854 // For example, if a key has a default value of []string{} and the same key
   857 // For example, if a key has a default value of []string{} and the same key
   855 // is set via an environment variable to "a b c", a call to the Get function
   858 // is set via an environment variable to "a b c", a call to the Get function
   856 // would return a string slice for the key if the key's type is inferred by
   859 // would return a string slice for the key if the key's type is inferred by
   857 // the default value and the Get function would return:
   860 // the default value and the Get function would return:
   858 //
   861 //
   859 //   []string {"a", "b", "c"}
   862 //	[]string {"a", "b", "c"}
   860 //
   863 //
   861 // Otherwise the Get function would return:
   864 // Otherwise the Get function would return:
   862 //
   865 //
   863 //   "a b c"
   866 //	"a b c"
   864 func SetTypeByDefaultValue(enable bool) { v.SetTypeByDefaultValue(enable) }
   867 func SetTypeByDefaultValue(enable bool) { v.SetTypeByDefaultValue(enable) }
   865 
   868 
   866 func (v *Viper) SetTypeByDefaultValue(enable bool) {
   869 func (v *Viper) SetTypeByDefaultValue(enable bool) {
   867 	v.typeByDefValue = enable
   870 	v.typeByDefValue = enable
   868 }
   871 }
   986 
   989 
   987 func (v *Viper) GetUint(key string) uint {
   990 func (v *Viper) GetUint(key string) uint {
   988 	return cast.ToUint(v.Get(key))
   991 	return cast.ToUint(v.Get(key))
   989 }
   992 }
   990 
   993 
       
   994 // GetUint16 returns the value associated with the key as an unsigned integer.
       
   995 func GetUint16(key string) uint16 { return v.GetUint16(key) }
       
   996 
       
   997 func (v *Viper) GetUint16(key string) uint16 {
       
   998 	return cast.ToUint16(v.Get(key))
       
   999 }
       
  1000 
   991 // GetUint32 returns the value associated with the key as an unsigned integer.
  1001 // GetUint32 returns the value associated with the key as an unsigned integer.
   992 func GetUint32(key string) uint32 { return v.GetUint32(key) }
  1002 func GetUint32(key string) uint32 { return v.GetUint32(key) }
   993 
  1003 
   994 func (v *Viper) GetUint32(key string) uint32 {
  1004 func (v *Viper) GetUint32(key string) uint32 {
   995 	return cast.ToUint32(v.Get(key))
  1005 	return cast.ToUint32(v.Get(key))
  1135 }
  1145 }
  1136 
  1146 
  1137 // BindPFlag binds a specific key to a pflag (as used by cobra).
  1147 // BindPFlag binds a specific key to a pflag (as used by cobra).
  1138 // Example (where serverCmd is a Cobra instance):
  1148 // Example (where serverCmd is a Cobra instance):
  1139 //
  1149 //
  1140 //	 serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
  1150 //	serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
  1141 //	 Viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
  1151 //	Viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
  1142 //
       
  1143 func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) }
  1152 func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) }
  1144 
  1153 
  1145 func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error {
  1154 func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error {
  1146 	if flag == nil {
  1155 	if flag == nil {
  1147 		return fmt.Errorf("flag for %q is nil", key)
  1156 		return fmt.Errorf("flag for %q is nil", key)
  1868 func (v *Viper) getKeyValueConfig() error {
  1877 func (v *Viper) getKeyValueConfig() error {
  1869 	if RemoteConfig == nil {
  1878 	if RemoteConfig == nil {
  1870 		return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ github.com/spf13/viper/remote'")
  1879 		return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ github.com/spf13/viper/remote'")
  1871 	}
  1880 	}
  1872 
  1881 
       
  1882 	if len(v.remoteProviders) == 0 {
       
  1883 		return RemoteConfigError("No Remote Providers")
       
  1884 	}
       
  1885 
  1873 	for _, rp := range v.remoteProviders {
  1886 	for _, rp := range v.remoteProviders {
  1874 		val, err := v.getRemoteConfig(rp)
  1887 		val, err := v.getRemoteConfig(rp)
  1875 		if err != nil {
  1888 		if err != nil {
  1876 			v.logger.Error(fmt.Errorf("get remote config: %w", err).Error())
  1889 			v.logger.Error(fmt.Errorf("get remote config: %w", err).Error())
  1877 
  1890 
  1894 	return v.kvstore, err
  1907 	return v.kvstore, err
  1895 }
  1908 }
  1896 
  1909 
  1897 // Retrieve the first found remote configuration.
  1910 // Retrieve the first found remote configuration.
  1898 func (v *Viper) watchKeyValueConfigOnChannel() error {
  1911 func (v *Viper) watchKeyValueConfigOnChannel() error {
       
  1912 	if len(v.remoteProviders) == 0 {
       
  1913 		return RemoteConfigError("No Remote Providers")
       
  1914 	}
       
  1915 
  1899 	for _, rp := range v.remoteProviders {
  1916 	for _, rp := range v.remoteProviders {
  1900 		respc, _ := RemoteConfig.WatchChannel(rp)
  1917 		respc, _ := RemoteConfig.WatchChannel(rp)
  1901 		// Todo: Add quit channel
  1918 		// Todo: Add quit channel
  1902 		go func(rc <-chan *RemoteResponse) {
  1919 		go func(rc <-chan *RemoteResponse) {
  1903 			for {
  1920 			for {
  1911 	return RemoteConfigError("No Files Found")
  1928 	return RemoteConfigError("No Files Found")
  1912 }
  1929 }
  1913 
  1930 
  1914 // Retrieve the first found remote configuration.
  1931 // Retrieve the first found remote configuration.
  1915 func (v *Viper) watchKeyValueConfig() error {
  1932 func (v *Viper) watchKeyValueConfig() error {
       
  1933 	if len(v.remoteProviders) == 0 {
       
  1934 		return RemoteConfigError("No Remote Providers")
       
  1935 	}
       
  1936 
  1916 	for _, rp := range v.remoteProviders {
  1937 	for _, rp := range v.remoteProviders {
  1917 		val, err := v.watchRemoteConfig(rp)
  1938 		val, err := v.watchRemoteConfig(rp)
  1918 		if err != nil {
  1939 		if err != nil {
       
  1940 			v.logger.Error(fmt.Errorf("watch remote config: %w", err).Error())
       
  1941 
  1919 			continue
  1942 			continue
  1920 		}
  1943 		}
  1921 		v.kvstore = val
  1944 		v.kvstore = val
  1922 		return nil
  1945 		return nil
  1923 	}
  1946 	}
  1956 	return a
  1979 	return a
  1957 }
  1980 }
  1958 
  1981 
  1959 // flattenAndMergeMap recursively flattens the given map into a map[string]bool
  1982 // flattenAndMergeMap recursively flattens the given map into a map[string]bool
  1960 // of key paths (used as a set, easier to manipulate than a []string):
  1983 // of key paths (used as a set, easier to manipulate than a []string):
  1961 // - each path is merged into a single key string, delimited with v.keyDelim
  1984 //   - each path is merged into a single key string, delimited with v.keyDelim
  1962 // - if a path is shadowed by an earlier value in the initial shadow map,
  1985 //   - if a path is shadowed by an earlier value in the initial shadow map,
  1963 //   it is skipped.
  1986 //     it is skipped.
       
  1987 //
  1964 // The resulting set of paths is merged to the given shadow set at the same time.
  1988 // The resulting set of paths is merged to the given shadow set at the same time.
  1965 func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool {
  1989 func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool {
  1966 	if shadow != nil && prefix != "" && shadow[prefix] {
  1990 	if shadow != nil && prefix != "" && shadow[prefix] {
  1967 		// prefix is shadowed => nothing more to flatten
  1991 		// prefix is shadowed => nothing more to flatten
  1968 		return shadow
  1992 		return shadow
  2109 	return v.configFile, nil
  2133 	return v.configFile, nil
  2110 }
  2134 }
  2111 
  2135 
  2112 // Debug prints all configuration registries for debugging
  2136 // Debug prints all configuration registries for debugging
  2113 // purposes.
  2137 // purposes.
  2114 func Debug() { v.Debug() }
  2138 func Debug()              { v.Debug() }
  2115 
  2139 func DebugTo(w io.Writer) { v.DebugTo(w) }
  2116 func (v *Viper) Debug() {
  2140 
  2117 	fmt.Printf("Aliases:\n%#v\n", v.aliases)
  2141 func (v *Viper) Debug() { v.DebugTo(os.Stdout) }
  2118 	fmt.Printf("Override:\n%#v\n", v.override)
  2142 
  2119 	fmt.Printf("PFlags:\n%#v\n", v.pflags)
  2143 func (v *Viper) DebugTo(w io.Writer) {
  2120 	fmt.Printf("Env:\n%#v\n", v.env)
  2144 	fmt.Fprintf(w, "Aliases:\n%#v\n", v.aliases)
  2121 	fmt.Printf("Key/Value Store:\n%#v\n", v.kvstore)
  2145 	fmt.Fprintf(w, "Override:\n%#v\n", v.override)
  2122 	fmt.Printf("Config:\n%#v\n", v.config)
  2146 	fmt.Fprintf(w, "PFlags:\n%#v\n", v.pflags)
  2123 	fmt.Printf("Defaults:\n%#v\n", v.defaults)
  2147 	fmt.Fprintf(w, "Env:\n%#v\n", v.env)
  2124 }
  2148 	fmt.Fprintf(w, "Key/Value Store:\n%#v\n", v.kvstore)
       
  2149 	fmt.Fprintf(w, "Config:\n%#v\n", v.config)
       
  2150 	fmt.Fprintf(w, "Defaults:\n%#v\n", v.defaults)
       
  2151 }