mirror of https://github.com/spf13/viper.git
Readme fixes and small edits
This commit is contained in:
parent
f14e1baa25
commit
2abb1bebfd
234
README.md
234
README.md
|
@ -7,41 +7,41 @@ Go configuration with fangs
|
||||||
|
|
||||||
## What is Viper?
|
## What is Viper?
|
||||||
|
|
||||||
Viper is a complete configuration solution for go applications. It has
|
Viper is a complete configuration solution for go applications. It is designed
|
||||||
been designed to work within an application to handle all types of
|
to work within an application, and can handle all types of configuration needs
|
||||||
configuration. It supports
|
and formats. It supports:
|
||||||
|
|
||||||
* setting defaults
|
* setting defaults
|
||||||
* reading from json, toml and yaml config files
|
* reading from JSON, TOML, and YAML config files
|
||||||
* reading from environment variables
|
* reading from environment variables
|
||||||
* reading from remote config systems (Etcd or Consul), watching changes
|
* reading from remote config systems (Etcd or Consul), and watching changes
|
||||||
* reading from command line flags
|
* reading from command line flags
|
||||||
* reading from buffer
|
* reading from buffer
|
||||||
* setting explicit values
|
* setting explicit values
|
||||||
|
|
||||||
It can be thought of as a registry for all of your applications
|
Viper can be thought of as a registry for all of your applications
|
||||||
configuration needs.
|
configuration needs.
|
||||||
|
|
||||||
## Why Viper?
|
## Why Viper?
|
||||||
|
|
||||||
When building a modern application, you don’t want to have to worry about
|
When building a modern application, you don’t want to worry about
|
||||||
configuration file formats; you want to focus on building awesome software.
|
configuration file formats; you want to focus on building awesome software.
|
||||||
Viper is here to help with that.
|
Viper is here to help with that.
|
||||||
|
|
||||||
Viper does the following for you:
|
Viper does the following for you:
|
||||||
|
|
||||||
1. Find, load and marshal a configuration file in JSON, TOML or YAML.
|
1. Find, load, and marshal a configuration file in JSON, TOML, or YAML.
|
||||||
2. Provide a mechanism to set default values for your different
|
2. Provide a mechanism to set default values for your different
|
||||||
configuration options.
|
configuration options.
|
||||||
3. Provide a mechanism to set override values for options specified
|
3. Provide a mechanism to set override values for options specified through
|
||||||
through command line flags.
|
command line flags.
|
||||||
4. Provide an alias system to easily rename parameters without breaking
|
4. Provide an alias system to easily rename parameters without breaking existing
|
||||||
existing code.
|
code.
|
||||||
5. Make it easy to tell the difference between when a user has provided
|
5. Make it easy to tell the difference between when a user has provided a
|
||||||
a command line or config file which is the same as the default.
|
command line or config file which is the same as the default.
|
||||||
|
|
||||||
Viper uses the following precedence order. Each item takes precedence
|
Viper uses the following precedence order. Each item takes precedence over the
|
||||||
over the item below it:
|
item below it:
|
||||||
|
|
||||||
* explicit call to Set
|
* explicit call to Set
|
||||||
* flag
|
* flag
|
||||||
|
@ -56,10 +56,9 @@ Viper configuration keys are case insensitive.
|
||||||
|
|
||||||
### Establishing Defaults
|
### Establishing Defaults
|
||||||
|
|
||||||
A good configuration system will support default values. A default value
|
A good configuration system will support default values. A default value is not
|
||||||
is not required for a key, but can establish a default to be used in the
|
required for a key, but it's useful in the event that a key hasn’t be set via
|
||||||
event that the key hasn’t be set via config file, environment variable,
|
config file, environment variable, remote configuration or flag.
|
||||||
remote configuration or flag.
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
@ -71,10 +70,9 @@ viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "cat
|
||||||
|
|
||||||
### Reading Config Files
|
### Reading Config Files
|
||||||
|
|
||||||
If you want to support a config file, Viper requires a minimal
|
Viper requires minimal configuration so it knows where to look for config files.
|
||||||
configuration so it knows where to look for the config file. Viper
|
Viper supports JSON, TOML and YAML files. Viper can search multiple paths, but
|
||||||
supports json, toml and yaml files. Viper can search multiple paths, but
|
currently a single Viper instance only supports a single configuration file.
|
||||||
currently a single viper only supports a single config file.
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
viper.SetConfigName("config") // name of config file (without extension)
|
viper.SetConfigName("config") // name of config file (without extension)
|
||||||
|
@ -88,14 +86,14 @@ if err != nil { // Handle errors reading the config file
|
||||||
|
|
||||||
### Reading Config from io.Reader
|
### Reading Config from io.Reader
|
||||||
|
|
||||||
Viper predefined many configuration sources, such as files, environment variables, flags and
|
Viper predefines many configuration sources such as files, environment
|
||||||
remote K/V store. But you are not bound to them. You can also implement your own way to
|
variables, flags, and remote K/V store, but you are not bound to them. You can
|
||||||
require configuration and feed it to viper.
|
also implement your own required configuration source and feed it to viper.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
viper.SetConfigType("yaml") // or viper.SetConfigType("YAML")
|
viper.SetConfigType("yaml") // or viper.SetConfigType("YAML")
|
||||||
|
|
||||||
// any approach to require this configuration into your program.
|
// any approach to require this configuration into your program.
|
||||||
var yamlExample = []byte(`
|
var yamlExample = []byte(`
|
||||||
Hacker: true
|
Hacker: true
|
||||||
name: steve
|
name: steve
|
||||||
|
@ -142,44 +140,43 @@ viper.GetBool("verbose") // true
|
||||||
### Working with Environment Variables
|
### Working with Environment Variables
|
||||||
|
|
||||||
Viper has full support for environment variables. This enables 12 factor
|
Viper has full support for environment variables. This enables 12 factor
|
||||||
applications out of the box. There are four methods that exist to aid
|
applications out of the box. There are four methods that exist to aid working
|
||||||
with working with ENV:
|
with ENV:
|
||||||
|
|
||||||
* AutomaticEnv()
|
* `AutomaticEnv()`
|
||||||
* BindEnv(string...) : error
|
* `BindEnv(string...) : error`
|
||||||
* SetEnvPrefix(string)
|
* `SetEnvPrefix(string)`
|
||||||
* SetEnvReplacer(string...) *strings.Replacer
|
* `SetEnvReplacer(string...) *strings.Replacer`
|
||||||
|
|
||||||
_When working with ENV variables, it’s important to recognize that Viper
|
_When working with ENV variables, it’s important to recognize that Viper
|
||||||
treats ENV variables as case sensitive._
|
treats ENV variables as case sensitive._
|
||||||
|
|
||||||
Viper provides a mechanism to try to ensure that ENV variables are
|
Viper provides a mechanism to try to ensure that ENV variables are unique. By
|
||||||
unique. By using SetEnvPrefix, you can tell Viper to use add a prefix
|
using `SetEnvPrefix`, you can tell Viper to use add a prefix while reading from
|
||||||
while reading from the environment variables. Both BindEnv and
|
the environment variables. Both `BindEnv` and `AutomaticEnv` will use this
|
||||||
AutomaticEnv will use this prefix.
|
prefix.
|
||||||
|
|
||||||
BindEnv takes one or two parameters. The first parameter is the key
|
`BindEnv` takes one or two parameters. The first parameter is the key name, the
|
||||||
name, the second is the name of the environment variable. The name of
|
second is the name of the environment variable. The name of the environment
|
||||||
the environment variable is case sensitive. If the ENV variable name is
|
variable is case sensitive. If the ENV variable name is not provided, then
|
||||||
not provided, then Viper will automatically assume that the key name
|
Viper will automatically assume that the key name matches the ENV variable name,
|
||||||
matches the ENV variable name but the ENV variable is IN ALL CAPS. When
|
but the ENV variable is IN ALL CAPS. When you explicitly provide the ENV
|
||||||
you explicitly provide the ENV variable name, it **does not**
|
variable name, it **does not** automatically add the prefix.
|
||||||
automatically add the prefix.
|
|
||||||
|
|
||||||
One important thing to recognize when working with ENV variables is that
|
One important thing to recognize when working with ENV variables is that the
|
||||||
the value will be read each time it is accessed. It does not fix the
|
value will be read each time it is accessed. Viper does not fix the value when
|
||||||
value when the BindEnv is called.
|
the `BindEnv` is called.
|
||||||
|
|
||||||
AutomaticEnv is a powerful helper especially when combined with
|
`AutomaticEnv` is a powerful helper especially when combined with
|
||||||
SetEnvPrefix. When called, Viper will check for an environment variable
|
`SetEnvPrefix`. When called, Viper will check for an environment variable any
|
||||||
any time a viper.Get request is made. It will apply the following rules.
|
time a `viper.Get` request is made. It will apply the following rules. It will
|
||||||
It will check for a environment variable with a name matching the key
|
check for a environment variable with a name matching the key uppercased and
|
||||||
uppercased and prefixed with the EnvPrefix if set.
|
prefixed with the `EnvPrefix` if set.
|
||||||
|
|
||||||
SetEnvReplacer allows you to use a `strings.Replacer` object to rewrite Env keys
|
`SetEnvReplacer` allows you to use a `strings.Replacer` object to rewrite Env
|
||||||
to an extent. This is useful if you want to use `-` or something in your Get()
|
keys to an extent. This is useful if you want to use `-` or something in your
|
||||||
calls, but want your environmental variables to use `_` delimiters. An example
|
`Get()` calls, but want your environmental variables to use `_` delimiters. An
|
||||||
of using it can be found in `viper_test.go`.
|
example of using it can be found in `viper_test.go`.
|
||||||
|
|
||||||
#### Env example
|
#### Env example
|
||||||
|
|
||||||
|
@ -194,14 +191,14 @@ id := Get("id") // 13
|
||||||
|
|
||||||
### Working with Flags
|
### Working with Flags
|
||||||
|
|
||||||
Viper has the ability to bind to flags. Specifically, Viper supports
|
Viper has the ability to bind to flags. Specifically, Viper supports `Pflags`
|
||||||
Pflags as used in the [Cobra](https://github.com/spf13/cobra) library.
|
as used in the [Cobra](https://github.com/spf13/cobra) library.
|
||||||
|
|
||||||
Like BindEnv, the value is not set when the binding method is called, but
|
Like `BindEnv`, the value is not set when the binding method is called, but when
|
||||||
when it is accessed. This means you can bind as early as you want, even
|
it is accessed. This means you can bind as early as you want, even in an
|
||||||
in an init() function.
|
`init()` function.
|
||||||
|
|
||||||
The BindPFlag() method provides this functionality.
|
The `BindPFlag()` method provides this functionality.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -212,25 +209,26 @@ viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
|
||||||
|
|
||||||
### Remote Key/Value Store Support
|
### Remote Key/Value Store Support
|
||||||
|
|
||||||
To enable remote support in Viper, do a blank import of the `viper/remote` package:
|
To enable remote support in Viper, do a blank import of the `viper/remote`
|
||||||
|
package:
|
||||||
|
|
||||||
`import _ github.com/spf13/viper/remote`
|
`import _ github.com/spf13/viper/remote`
|
||||||
|
|
||||||
Viper will read a config string (as JSON, TOML, or YAML) retrieved from a
|
Viper will read a config string (as JSON, TOML, or YAML) retrieved from a path
|
||||||
path in a Key/Value store such as Etcd or Consul. These values take precedence
|
in a Key/Value store such as Etcd or Consul. These values take precedence over
|
||||||
over default values, but are overriden by configuration values retrieved from disk,
|
default values, but are overridden by configuration values retrieved from disk,
|
||||||
flags, or environment variables.
|
flags, or environment variables.
|
||||||
|
|
||||||
Viper uses [crypt](https://github.com/xordataexchange/crypt) to retrieve configuration
|
Viper uses [crypt](https://github.com/xordataexchange/crypt) to retrieve
|
||||||
from the K/V store, which means that you can store your configuration values
|
configuration from the K/V store, which means that you can store your
|
||||||
encrypted and have them automatically decrypted if you have the correct
|
configuration values encrypted and have them automatically decrypted if you have
|
||||||
gpg keyring. Encryption is optional.
|
the correct gpg keyring. Encryption is optional.
|
||||||
|
|
||||||
You can use remote configuration in conjunction with local configuration, or
|
You can use remote configuration in conjunction with local configuration, or
|
||||||
independently of it.
|
independently of it.
|
||||||
|
|
||||||
`crypt` has a command-line helper that you can use to put configurations
|
`crypt` has a command-line helper that you can use to put configurations in your
|
||||||
in your K/V store. `crypt` defaults to etcd on http://127.0.0.1:4001.
|
K/V store. `crypt` defaults to etcd on http://127.0.0.1:4001.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ go get github.com/xordataexchange/crypt/bin/crypt
|
$ go get github.com/xordataexchange/crypt/bin/crypt
|
||||||
|
@ -243,8 +241,8 @@ Confirm that your value was set:
|
||||||
$ crypt get -plaintext /config/hugo.json
|
$ crypt get -plaintext /config/hugo.json
|
||||||
```
|
```
|
||||||
|
|
||||||
See the `crypt` documentation for examples of how to set encrypted values, or how
|
See the `crypt` documentation for examples of how to set encrypted values, or
|
||||||
to use Consul.
|
how to use Consul.
|
||||||
|
|
||||||
### Remote Key/Value Store Example - Unencrypted
|
### Remote Key/Value Store Example - Unencrypted
|
||||||
|
|
||||||
|
@ -298,24 +296,24 @@ go func(){
|
||||||
|
|
||||||
## Getting Values From Viper
|
## Getting Values From Viper
|
||||||
|
|
||||||
In Viper, there are a few ways to get a value depending on what type of value you want to retrieved.
|
In Viper, there are a few ways to get a value depending on the value's type.
|
||||||
The following functions and methods exist:
|
The following functions and methods exist:
|
||||||
|
|
||||||
* Get(key string) : interface{}
|
* `Get(key string) : interface{}`
|
||||||
* GetBool(key string) : bool
|
* `GetBool(key string) : bool`
|
||||||
* GetFloat64(key string) : float64
|
* `GetFloat64(key string) : float64`
|
||||||
* GetInt(key string) : int
|
* `GetInt(key string) : int`
|
||||||
* GetString(key string) : string
|
* `GetString(key string) : string`
|
||||||
* GetStringMap(key string) : map[string]interface{}
|
* `GetStringMap(key string) : map[string]interface{}`
|
||||||
* GetStringMapString(key string) : map[string]string
|
* `GetStringMapString(key string) : map[string]string`
|
||||||
* GetStringSlice(key string) : []string
|
* `GetStringSlice(key string) : []string`
|
||||||
* GetTime(key string) : time.Time
|
* `GetTime(key string) : time.Time`
|
||||||
* GetDuration(key string) : time.Duration
|
* `GetDuration(key string) : time.Duration`
|
||||||
* IsSet(key string) : bool
|
* `IsSet(key string) : bool`
|
||||||
|
|
||||||
One important thing to recognize is that each Get function will return
|
One important thing to recognize is that each Get function will return a zero
|
||||||
its zero value if it’s not found. To check if a given key exists, the IsSet()
|
value if it’s not found. To check if a given key exists, the `IsSet()` method
|
||||||
method has been provided.
|
has been provided.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```go
|
```go
|
||||||
|
@ -326,8 +324,8 @@ if viper.GetBool("verbose") {
|
||||||
```
|
```
|
||||||
### Accessing nested keys
|
### Accessing nested keys
|
||||||
|
|
||||||
The accessor methods also accept formatted paths to deeply nested keys.
|
The accessor methods also accept formatted paths to deeply nested keys. For
|
||||||
For example, if the following JSON file is loaded:
|
example, if the following JSON file is loaded:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -355,18 +353,19 @@ Viper can access a nested field by passing a `.` delimited path of keys:
|
||||||
GetString("datastore.metric.host") // (returns "127.0.0.1")
|
GetString("datastore.metric.host") // (returns "127.0.0.1")
|
||||||
```
|
```
|
||||||
|
|
||||||
This obeys the precendense rules established above; the search for the root key
|
This obeys the precedence rules established above; the search for the root key
|
||||||
(in this examole, `datastore`) will cascade through the remaining configuration registries
|
(in this example, `datastore`) will cascade through the remaining configuration
|
||||||
until found. The search for the subkeys (`metric` and `host`), however, will not.
|
registries until found. The search for the sub-keys (`metric` and `host`),
|
||||||
|
however, will not.
|
||||||
|
|
||||||
For example, if the `metric` key was not defined in the configuration loaded
|
For example, if the `metric` key was not defined in the configuration loaded
|
||||||
from file, but was defined in the defaults, Viper would return the zero value.
|
from file, but was defined in the defaults, Viper would return the zero value.
|
||||||
|
|
||||||
On the other hand, if the primary key was not defined, Viper would go through the
|
On the other hand, if the primary key was not defined, Viper would go through
|
||||||
remaining registries looking for it.
|
the remaining registries looking for it.
|
||||||
|
|
||||||
Lastly, if there exists a key that matches the delimited key path, its value will
|
Lastly, if there exists a key that matches the delimited key path, its value
|
||||||
be returned instead. E.g.
|
will be returned instead. E.g.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -392,12 +391,13 @@ GetString("datastore.metric.host") //returns "0.0.0.0"
|
||||||
|
|
||||||
### Marshaling
|
### Marshaling
|
||||||
|
|
||||||
You also have the option of Marshaling all or a specific value to a struct, map, etc.
|
You also have the option of Marshaling all or a specific value to a struct, map,
|
||||||
|
etc.
|
||||||
|
|
||||||
There are two methods to do this:
|
There are two methods to do this:
|
||||||
|
|
||||||
* Marshal(rawVal interface{}) : error
|
* `Marshal(rawVal interface{}) : error`
|
||||||
* MarshalKey(key string, rawVal interface{}) : error
|
* `MarshalKey(key string, rawVal interface{}) : error`
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -418,19 +418,19 @@ if err != nil {
|
||||||
## Viper or Vipers?
|
## Viper or Vipers?
|
||||||
|
|
||||||
Viper comes ready to use out of the box. There is no configuration or
|
Viper comes ready to use out of the box. There is no configuration or
|
||||||
initialization needed to begin using Viper. Since most applications will
|
initialization needed to begin using Viper. Since most applications will want
|
||||||
want to use a single central repository for their configuration, the
|
to use a single central repository for their configuration, the viper package
|
||||||
viper package provides this. It is similar to a singleton.
|
provides this. It is similar to a singleton.
|
||||||
|
|
||||||
In all of the examples above, they demonstrate using viper in its
|
In all of the examples above, they demonstrate using viper in it's singleton
|
||||||
singleton style approach.
|
style approach.
|
||||||
|
|
||||||
### Working with multiple vipers
|
### Working with multiple vipers
|
||||||
|
|
||||||
You can also create many different vipers for use in your application.
|
You can also create many different vipers for use in your application. Each will
|
||||||
Each will have it’s own unique set of configurations and values. Each
|
have it’s own unique set of configurations and values. Each can read from a
|
||||||
can read from a different config file, key value store, etc. All of the
|
different config file, key value store, etc. All of the functions that viper
|
||||||
functions that viper package supports are mirrored as methods on a viper.
|
package supports are mirrored as methods on a viper.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -444,8 +444,8 @@ y.SetDefault("ContentDir", "foobar")
|
||||||
//...
|
//...
|
||||||
```
|
```
|
||||||
|
|
||||||
When working with multiple vipers, it is up to the user to keep track of
|
When working with multiple vipers, it is up to the user to keep track of the
|
||||||
the different vipers.
|
different vipers.
|
||||||
|
|
||||||
## Q & A
|
## Q & A
|
||||||
|
|
||||||
|
@ -453,13 +453,13 @@ Q: Why not INI files?
|
||||||
|
|
||||||
A: Ini files are pretty awful. There’s no standard format, and they are hard to
|
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
|
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
|
really wants to add this feature, I’d be happy to merge it. It’s easy to specify
|
||||||
specify which formats your application will permit.
|
which formats your application will permit.
|
||||||
|
|
||||||
Q: Why is it called “Viper”?
|
Q: Why is it called “Viper”?
|
||||||
|
|
||||||
A: Viper is designed to be a [companion](http://en.wikipedia.org/wiki/Viper_(G.I._Joe)) to
|
A: Viper is designed to be a [companion](http://en.wikipedia.org/wiki/Viper_(G.I._Joe))
|
||||||
[Cobra](https://github.com/spf13/cobra). While both can operate completely
|
to [Cobra](https://github.com/spf13/cobra). While both can operate completely
|
||||||
independently, together they make a powerful pair to handle much of your
|
independently, together they make a powerful pair to handle much of your
|
||||||
application foundation needs.
|
application foundation needs.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue