mirror of
https://github.com/spf13/viper
synced 2024-12-22 19:47:01 +00:00
Rewriting the documentation
This commit is contained in:
parent
91b076eec5
commit
cacbc4c733
1 changed files with 173 additions and 23 deletions
196
README.md
196
README.md
|
@ -5,11 +5,19 @@ Go configuration with fangs
|
|||
|
||||
## What is Viper?
|
||||
|
||||
Viper is a complete configuration solution. Designed to work within an
|
||||
application to handle file based configuration and seamlessly marry that with
|
||||
command line flags which can also be used to control application behavior.
|
||||
Viper also supports retrieving configuration values from remote key/value stores.
|
||||
Etcd and Consul are supported.
|
||||
Viper is a complete configuration solution for go applications. It has
|
||||
been designed to work within an application to handle all types of
|
||||
configuration. It supports
|
||||
|
||||
* setting defaults
|
||||
* reading from yaml, toml and json config files
|
||||
* reading from environment variables
|
||||
* reading from remote config systems (Etcd or Consul)
|
||||
* reading from command line flags
|
||||
* setting explicit values
|
||||
|
||||
It can be thought of as a registry for all of your applications
|
||||
configuration needs.
|
||||
|
||||
## Why Viper?
|
||||
|
||||
|
@ -19,42 +27,66 @@ Viper is here to help with that.
|
|||
|
||||
Viper does the following for you:
|
||||
|
||||
1. Find, load and marshall a configuration file in YAML, TOML or JSON.
|
||||
2. Provide a mechanism to setDefault values for your different configuration options
|
||||
3. Provide a mechanism to setOverride 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 marshal a configuration file in YAML, TOML or JSON.
|
||||
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 believes that:
|
||||
Viper uses the following precedence order. Each item takes precedence
|
||||
over the item below it:
|
||||
|
||||
1. command line flags take precedence over options set in config files
|
||||
2. config files take precedence over options set in remote key/value stores
|
||||
3. remote key/value stores take precedence over defaults
|
||||
* explicit call to Set
|
||||
* flag
|
||||
* env
|
||||
* config
|
||||
* key/value store
|
||||
* default
|
||||
|
||||
Viper configuration keys are case insensitive.
|
||||
|
||||
## Usage
|
||||
|
||||
### Initialization
|
||||
### Establishing Defaults
|
||||
|
||||
A good configuration system will support default values. A default value
|
||||
is not required for a key, but can establish a default to be used in the
|
||||
event that the key hasn’t be set via config file, environment variable,
|
||||
remote configuration or flag.
|
||||
|
||||
Examples:
|
||||
|
||||
viper.SetDefault("ContentDir", "content")
|
||||
viper.SetDefault("LayoutDir", "layouts")
|
||||
viper.SetDefault("Indexes", map[string]string{"tag": "tags", "category": "categories"})
|
||||
|
||||
### Reading Config Files
|
||||
|
||||
If you want to support a config file, Viper requires a minimal
|
||||
configuration so it knows where to look for the config file. Viper
|
||||
supports yaml, toml and json files. Viper can search multiple paths, but
|
||||
currently a single viper only supports a single config file.
|
||||
|
||||
viper.SetConfigName("config") // name of config file (without extension)
|
||||
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.ReadInConfig() // Find and read the config file
|
||||
|
||||
### Setting Defaults
|
||||
|
||||
viper.SetDefault("ContentDir", "content")
|
||||
viper.SetDefault("LayoutDir", "layouts")
|
||||
viper.SetDefault("Indexes", map[string]string{"tag": "tags", "category": "categories"})
|
||||
|
||||
### Setting Overrides
|
||||
|
||||
These could be from a command line flag, or from your own application logic.
|
||||
|
||||
viper.Set("Verbose", true)
|
||||
viper.Set("LogFile", LogFile)
|
||||
|
||||
### Registering and Using Aliases
|
||||
|
||||
Aliases permit a single value to be referenced by multiple keys
|
||||
|
||||
viper.RegisterAlias("loud", "Verbose")
|
||||
|
||||
viper.Set("verbose", true) // same result as next line
|
||||
|
@ -65,11 +97,102 @@ Viper configuration keys are case insensitive.
|
|||
|
||||
### Getting Values
|
||||
|
||||
In Viper there are a few ways to get a value depending on what type of value you want to retrieved.
|
||||
The following functions and methods exist:
|
||||
|
||||
* Get(key string) : interface{}
|
||||
* GetBool(key string) : bool
|
||||
* GetFloat64(key string) : float64
|
||||
* GetInt(key string) : int
|
||||
* GetString(key string) : string
|
||||
* GetStringMap(key string) : map[string]interface{}
|
||||
* GetStringMapString(key string) : map[string]string
|
||||
* GetStringSlice(key string) : []string
|
||||
* GetTime(key string) : time.Time
|
||||
* IsSet(key string) : bool
|
||||
|
||||
One important thing to recognize is that each Get function will return
|
||||
it’s zero value if it’s not found. To check if it’s found, the IsSet()
|
||||
method has been provided.
|
||||
|
||||
Example:
|
||||
|
||||
viper.GetString("logfile") // case insensitive Setting & Getting
|
||||
if viper.GetBool("verbose") {
|
||||
fmt.Println("verbose enabled")
|
||||
}
|
||||
|
||||
### Marshaling
|
||||
|
||||
You also have the option of Marshaling all or a specific value to a struct, map, etc.
|
||||
|
||||
There are two methods to do this:
|
||||
|
||||
* Marshal(rawVal interface{}) : error
|
||||
* MarshalKey(key string, rawVal interface{}) : error
|
||||
|
||||
Example:
|
||||
|
||||
type config struct {
|
||||
Port int
|
||||
Name string
|
||||
}
|
||||
|
||||
var C config
|
||||
|
||||
err := Marshal(&C)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to decode into struct, %v", err)
|
||||
}
|
||||
|
||||
### Working with Environment Variables
|
||||
|
||||
Viper has full support for environment variables. This enables 12 factor
|
||||
applications out of the box. There are two methods that exist to aid
|
||||
with working with ENV:
|
||||
|
||||
* AutomaticEnv()
|
||||
* BindEnv(input ) : error
|
||||
|
||||
When working with ENV variables it’s important to recognize that Viper
|
||||
treats ENV variables as case sensitive.
|
||||
|
||||
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.
|
||||
|
||||
One important thing to recognize when working with ENV variables is that
|
||||
the value will be read each time it is accessed. It does not fix the
|
||||
value when the BindEnv is called.
|
||||
|
||||
|
||||
AutomaticEnv is intended to be a convience helper. It will look for all
|
||||
keys that have been set (via defaults, config file, flag, or remote key
|
||||
value) and call BindEnv on that key. It does
|
||||
not simply import all ENV variables. Because of this behavior it’s
|
||||
usually best to call it last.
|
||||
|
||||
### Working with Flags
|
||||
|
||||
Viper has the ability to bind to flags. Specifically Viper supports
|
||||
Pflags as used in the [Cobra](http://github.com/spf13/cobra) library.
|
||||
|
||||
Like BindEnv the value is not set when the binding method is called, but
|
||||
when it is accessed. This means you can bind as early as you want, even
|
||||
in an init() function.
|
||||
|
||||
The BindPFlag() method provides this functionality.
|
||||
|
||||
Example:
|
||||
|
||||
serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
|
||||
viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
|
||||
|
||||
|
||||
### Remote Key/Value Store Support
|
||||
Viper will read a config string (as JSON, TOML, or YAML) retrieved from a
|
||||
path in a Key/Value store such as Etcd or Consul. These values take precedence
|
||||
|
@ -110,6 +233,35 @@ to use Consul.
|
|||
err := viper.ReadRemoteConfig()
|
||||
|
||||
|
||||
### Viper or Vipers?
|
||||
|
||||
Viper comes ready to use out of the box. There is no configuration or
|
||||
initialization needed to begin using Viper. Since most applications will
|
||||
want to use a single central repository for their configuration the
|
||||
viper package provides this. It is similar to a singleton.
|
||||
|
||||
In all of the examples above they demonstrate using viper in it’s
|
||||
singleton style approach.
|
||||
|
||||
### Working with multiple vipers
|
||||
|
||||
You can also create many different vipers for use in your application.
|
||||
Each will have it’s own unique set of configurations and values. Each
|
||||
can read from a different config file, key value store, etc. All of the
|
||||
functions that viper package supports are mirrored as methods on a viper.
|
||||
|
||||
Example:
|
||||
|
||||
x := viper.New()
|
||||
y := viper.New()
|
||||
|
||||
x.SetDefault("ContentDir", "content")
|
||||
y.SetDefault("ContentDir", "foobar")
|
||||
|
||||
...
|
||||
|
||||
When working with multiple vipers it is up to the user to keep track of
|
||||
the different vipers.
|
||||
|
||||
## Q & A
|
||||
|
||||
|
@ -130,5 +282,3 @@ application foundation needs.
|
|||
Q: Why is it called "Cobra"?
|
||||
|
||||
A: Is there a better name for a commander?
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue