vendor/github.com/spf13/viper/README.md
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
child 256 6d9efbef00a9
--- a/vendor/github.com/spf13/viper/README.md	Wed Sep 18 19:17:42 2019 +0200
+++ b/vendor/github.com/spf13/viper/README.md	Sun Feb 16 18:54:01 2020 +0100
@@ -2,6 +2,10 @@
 
 Go configuration with fangs!
 
+[![Actions](https://github.com/spf13/viper/workflows/CI/badge.svg)](https://github.com/spf13/viper)
+[![Join the chat at https://gitter.im/spf13/viper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![GoDoc](https://godoc.org/github.com/spf13/viper?status.svg)](https://godoc.org/github.com/spf13/viper)
+
 Many Go projects are built using Viper including:
 
 * [Hugo](http://gohugo.io)
@@ -12,8 +16,14 @@
 * [BloomApi](https://www.bloomapi.com/)
 * [doctl](https://github.com/digitalocean/doctl)
 * [Clairctl](https://github.com/jgsqware/clairctl)
+* [Mercure](https://mercure.rocks)
 
-[![Build Status](https://travis-ci.org/spf13/viper.svg)](https://travis-ci.org/spf13/viper) [![Join the chat at https://gitter.im/spf13/viper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![GoDoc](https://godoc.org/github.com/spf13/viper?status.svg)](https://godoc.org/github.com/spf13/viper)
+
+## Install
+
+```console
+go get github.com/spf13/viper
+```
 
 
 ## What is Viper?
@@ -23,7 +33,7 @@
 and formats. It supports:
 
 * setting defaults
-* reading from JSON, TOML, YAML, HCL, and Java properties config files
+* reading from JSON, TOML, YAML, HCL, envfile and Java properties config files
 * live watching and re-reading of config files (optional)
 * reading from environment variables
 * reading from remote config systems (etcd or Consul), and watching changes
@@ -31,8 +41,8 @@
 * reading from buffer
 * setting explicit values
 
-Viper can be thought of as a registry for all of your applications
-configuration needs.
+Viper can be thought of as a registry for all of your applications configuration needs.
+
 
 ## Why Viper?
 
@@ -42,34 +52,31 @@
 
 Viper does the following for you:
 
-1. Find, load, and unmarshal a configuration file in JSON, TOML, YAML, HCL, or Java properties formats.
-2. Provide a mechanism to set default values for your different
-   configuration options.
-3. Provide a mechanism to set override values for options specified through
-   command line flags.
-4. Provide an alias system to easily rename parameters without breaking existing
-   code.
-5. Make it easy to tell the difference between when a user has provided a
-   command line or config file which is the same as the default.
+1. Find, load, and unmarshal a configuration file in JSON, TOML, YAML, HCL, INI, envfile or Java properties formats.
+2. Provide a mechanism to set default values for your different configuration options.
+3. Provide a mechanism to set override values for options specified through command line flags.
+4. Provide an alias system to easily rename parameters without breaking existing code.
+5. Make it easy to tell the difference between when a user has provided a command line or config file which is the same as the default.
 
-Viper uses the following precedence order. Each item takes precedence over the
-item below it:
+Viper uses the following precedence order. Each item takes precedence over the item below it:
 
- * explicit call to Set
+ * explicit call to `Set`
  * flag
  * env
  * config
  * key/value store
  * default
 
-Viper configuration keys are case insensitive.
+**Important:** Viper configuration keys are case insensitive.
+There are ongoing discussions about making that optional.
+
 
 ## Putting Values into Viper
 
 ### Establishing Defaults
 
 A good configuration system will support default values. A default value is not
-required for a key, but it’s useful in the event that a key hasn’t been set via
+required for a key, but it’s useful in the event that a key hasn't been set via
 config file, environment variable, remote configuration or flag.
 
 Examples:
@@ -83,7 +90,7 @@
 ### Reading Config Files
 
 Viper requires minimal configuration so it knows where to look for config files.
-Viper supports JSON, TOML, YAML, HCL, and Java Properties files. Viper can search multiple paths, but
+Viper supports JSON, TOML, YAML, HCL, INI, envfile and Java Properties files. Viper can search multiple paths, but
 currently a single Viper instance only supports a single configuration file.
 Viper does not default to any configuration search paths leaving defaults decision
 to an application.
@@ -94,6 +101,7 @@
 
 ```go
 viper.SetConfigName("config") // name of config file (without extension)
+viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
 viper.AddConfigPath("/etc/appname/")   // path to look for the config file in
 viper.AddConfigPath("$HOME/.appname")  // call multiple times to add many search paths
 viper.AddConfigPath(".")               // optionally look for config in the working directory
@@ -103,6 +111,44 @@
 }
 ```
 
+You can handle the specific case where no config file is found like this:
+
+```go
+if err := viper.ReadInConfig(); err != nil {
+    if _, ok := err.(viper.ConfigFileNotFoundError); ok {
+        // Config file not found; ignore error if desired
+    } else {
+        // Config file was found but another error was produced
+    }
+}
+
+// Config file found and successfully parsed
+```
+
+*NOTE [since 1.6]:* You can also have a file without an extension and specify the format programmaticaly. For those configuration files that lie in the home of the user without any extension like `.bashrc`
+
+### Writing Config Files
+
+Reading from config files is useful, but at times you want to store all modifications made at run time.
+For that, a bunch of commands are available, each with its own purpose:
+
+* WriteConfig - writes the current viper configuration to the predefined path, if exists. Errors if no predefined path. Will overwrite the current config file, if it exists.
+* SafeWriteConfig - writes the current viper configuration to the predefined path. Errors if no predefined path. Will not overwrite the current config file, if it exists.
+* WriteConfigAs - writes the current viper configuration to the given filepath. Will overwrite the given file, if it exists.
+* SafeWriteConfigAs - writes the current viper configuration to the given filepath. Will not overwrite the given file, if it exists.
+
+As a rule of the thumb, everything marked with safe won't overwrite any file, but just create if not existent, whilst the default behavior is to create or truncate.
+
+A small examples section:
+
+```go
+viper.WriteConfig() // writes current config to predefined path set by 'viper.AddConfigPath()' and 'viper.SetConfigName'
+viper.SafeWriteConfig()
+viper.WriteConfigAs("/path/to/my/.config")
+viper.SafeWriteConfigAs("/path/to/my/.config") // will error since it has already been written
+viper.SafeWriteConfigAs("/path/to/my/.other_config")
+```
+
 ### Watching and re-reading config files
 
 Viper supports the ability to have your application live read a config file while running.
@@ -179,13 +225,14 @@
 ### Working with Environment Variables
 
 Viper has full support for environment variables. This enables 12 factor
-applications out of the box. There are four methods that exist to aid working
+applications out of the box. There are five methods that exist to aid working
 with ENV:
 
  * `AutomaticEnv()`
  * `BindEnv(string...) : error`
  * `SetEnvPrefix(string)`
  * `SetEnvKeyReplacer(string...) *strings.Replacer`
+ * `AllowEmptyEnv(bool)`
 
 _When working with ENV variables, it’s important to recognize that Viper
 treats ENV variables as case sensitive._
@@ -198,9 +245,9 @@
 `BindEnv` takes one or two parameters. The first parameter is the key name, the
 second is the name of the environment variable. The name of the environment
 variable is case sensitive. If the ENV variable name is not provided, then
-Viper will automatically assume that the key name matches the ENV variable name,
-but the ENV variable is IN ALL CAPS. When you explicitly provide the ENV
-variable name, it **does not** automatically add the prefix.
+Viper will automatically assume that the ENV variable matches the following format: prefix + "_" + the key name in ALL CAPS. When you explicitly provide the ENV variable name (the second parameter),
+it **does not** automatically add the prefix. For example if the second parameter is "id",
+Viper will look for the ENV variable "ID".
 
 One important thing to recognize when working with ENV variables is that the
 value will be read each time it is accessed. Viper does not fix the value when
@@ -217,6 +264,13 @@
 `Get()` calls, but want your environmental variables to use `_` delimiters. An
 example of using it can be found in `viper_test.go`.
 
+Alternatively, you can use `EnvKeyReplacer` with `NewWithOptions` factory function.
+Unlike `SetEnvKeyReplacer`, it accepts a `StringReplacer` interface allowing you to write custom string replacing logic.
+
+By default empty environment variables are considered unset and will fall back to
+the next configuration source. To treat empty environment variables as set, use
+the `AllowEmptyEnv` method.
+
 #### Env example
 
 ```go
@@ -341,7 +395,7 @@
 
 `import _ "github.com/spf13/viper/remote"`
 
-Viper will read a config string (as JSON, TOML, YAML or HCL) retrieved from a path
+Viper will read a config string (as JSON, TOML, YAML, HCL or envfile) retrieved from a path
 in a Key/Value store such as etcd or Consul.  These values take precedence over
 default values, but are overridden by configuration values retrieved from disk,
 flags, or environment variables.
@@ -376,7 +430,7 @@
 #### etcd
 ```go
 viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001","/config/hugo.json")
-viper.SetConfigType("json") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop"
+viper.SetConfigType("json") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop", "env", "dotenv"
 err := viper.ReadRemoteConfig()
 ```
 
@@ -404,7 +458,7 @@
 
 ```go
 viper.AddSecureRemoteProvider("etcd","http://127.0.0.1:4001","/config/hugo.json","/etc/secrets/mykeyring.gpg")
-viper.SetConfigType("json") // because there is no file extension in a stream of bytes,  supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop"
+viper.SetConfigType("json") // because there is no file extension in a stream of bytes,  supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop", "env", "dotenv"
 err := viper.ReadRemoteConfig()
 ```
 
@@ -415,7 +469,7 @@
 var runtime_viper = viper.New()
 
 runtime_viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001", "/config/hugo.yml")
-runtime_viper.SetConfigType("yaml") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop"
+runtime_viper.SetConfigType("yaml") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop", "env", "dotenv"
 
 // read from remote config the first time.
 err := runtime_viper.ReadRemoteConfig()
@@ -451,6 +505,7 @@
  * `GetBool(key string) : bool`
  * `GetFloat64(key string) : float64`
  * `GetInt(key string) : int`
+ * `GetIntSlice(key string) : []int`
  * `GetString(key string) : string`
  * `GetStringMap(key string) : map[string]interface{}`
  * `GetStringMapString(key string) : map[string]string`
@@ -606,15 +661,74 @@
 
 var C config
 
-err := Unmarshal(&C)
+err := viper.Unmarshal(&C)
 if err != nil {
 	t.Fatalf("unable to decode into struct, %v", err)
 }
 ```
 
+If you want to unmarshal configuration where the keys themselves contain dot (the default key delimiter),
+you have to change the delimiter:
+
+```go
+v := viper.NewWithOptions(viper.KeyDelimiter("::"))
+
+v.SetDefault("chart::values", map[string]interface{}{
+    "ingress": map[string]interface{}{
+        "annotations": map[string]interface{}{
+            "traefik.frontend.rule.type":                 "PathPrefix",
+            "traefik.ingress.kubernetes.io/ssl-redirect": "true",
+        },
+    },
+})
+
+type config struct {
+	Chart struct{
+        Values map[string]interface{}
+    }
+}
+
+var C config
+
+v.Unmarshal(&C)
+```
+
+Viper also supports unmarshaling into embedded structs:
+
+```go
+/*
+Example config:
+
+module:
+    enabled: true
+    token: 89h3f98hbwf987h3f98wenf89ehf
+*/
+type config struct {
+	Module struct {
+		Enabled bool
+
+		moduleConfig `mapstructure:",squash"`
+	}
+}
+
+// moduleConfig could be in a module specific package
+type moduleConfig struct {
+	Token string
+}
+
+var C config
+
+err := viper.Unmarshal(&C)
+if err != nil {
+	t.Fatalf("unable to decode into struct, %v", err)
+}
+```
+
+Viper uses [github.com/mitchellh/mapstructure](https://github.com/mitchellh/mapstructure) under the hood for unmarshaling values which uses `mapstructure` tags by default.
+
 ### Marshalling to string
 
-You may need to marhsal all the settings held in viper into a string rather than write them to a file. 
+You may need to marshal all the settings held in viper into a string rather than write them to a file. 
 You can use your favorite format's marshaller with the config returned by `AllSettings()`.
 
 ```go
@@ -625,11 +739,11 @@
 
 func yamlStringSettings() string {
     c := viper.AllSettings()
-	bs, err := yaml.Marshal(c)
-	if err != nil {
-        t.Fatalf("unable to marshal config to YAML: %v", err)
+    bs, err := yaml.Marshal(c)
+    if err != nil {
+        log.Fatalf("unable to marshal config to YAML: %v", err)
     }
-	return string(bs)
+    return string(bs)
 }
 ```
 
@@ -667,13 +781,6 @@
 
 ## Q & A
 
-Q: Why not INI files?
-
-A: Ini files are pretty awful. There’s no standard format, and they are hard to
-validate. Viper is designed to work with JSON, TOML or YAML files. If someone
-really wants to add this feature, I’d be happy to merge it. It’s easy to specify
-which formats your application will permit.
-
 Q: Why is it called “Viper”?
 
 A: Viper is designed to be a [companion](http://en.wikipedia.org/wiki/Viper_(G.I._Joe))