github.com/jyny/viper@v1.4.1/README.md (about)

     1  ![viper logo](https://cloud.githubusercontent.com/assets/173412/10886745/998df88a-8151-11e5-9448-4736db51020d.png)
     2  
     3  Go configuration with fangs!
     4  
     5  Many Go projects are built using Viper including:
     6  
     7  * [Hugo](http://gohugo.io)
     8  * [EMC RexRay](http://rexray.readthedocs.org/en/stable/)
     9  * [Imgur’s Incus](https://github.com/Imgur/incus)
    10  * [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)
    11  * [Docker Notary](https://github.com/docker/Notary)
    12  * [BloomApi](https://www.bloomapi.com/)
    13  * [doctl](https://github.com/digitalocean/doctl)
    14  * [Clairctl](https://github.com/jgsqware/clairctl)
    15  
    16  [![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)
    17  
    18  ## Install
    19  ```console
    20  go get -u github.com/spf13/viper
    21  ```
    22  
    23  ## What is Viper?
    24  
    25  Viper is a complete configuration solution for Go applications including 12-Factor apps. It is designed
    26  to work within an application, and can handle all types of configuration needs
    27  and formats. It supports:
    28  
    29  * setting defaults
    30  * reading from JSON, TOML, YAML, HCL, envfile and Java properties config files
    31  * live watching and re-reading of config files (optional)
    32  * reading from environment variables
    33  * reading from remote config systems (etcd or Consul), and watching changes
    34  * reading from command line flags
    35  * reading from buffer
    36  * setting explicit values
    37  
    38  Viper can be thought of as a registry for all of your applications
    39  configuration needs.
    40  
    41  ## Why Viper?
    42  
    43  When building a modern application, you don’t want to worry about
    44  configuration file formats; you want to focus on building awesome software.
    45  Viper is here to help with that.
    46  
    47  Viper does the following for you:
    48  
    49  1. Find, load, and unmarshal a configuration file in JSON, TOML, YAML, HCL, envfile or Java properties formats.
    50  2. Provide a mechanism to set default values for your different
    51     configuration options.
    52  3. Provide a mechanism to set override values for options specified through
    53     command line flags.
    54  4. Provide an alias system to easily rename parameters without breaking existing
    55     code.
    56  5. Make it easy to tell the difference between when a user has provided a
    57     command line or config file which is the same as the default.
    58  
    59  Viper uses the following precedence order. Each item takes precedence over the
    60  item below it:
    61  
    62   * explicit call to Set
    63   * flag
    64   * env
    65   * config
    66   * key/value store
    67   * default
    68  
    69  Viper configuration keys are case insensitive.
    70  
    71  ## Putting Values into Viper
    72  
    73  ### Establishing Defaults
    74  
    75  A good configuration system will support default values. A default value is not
    76  required for a key, but it’s useful in the event that a key hasn’t been set via
    77  config file, environment variable, remote configuration or flag.
    78  
    79  Examples:
    80  
    81  ```go
    82  viper.SetDefault("ContentDir", "content")
    83  viper.SetDefault("LayoutDir", "layouts")
    84  viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
    85  ```
    86  
    87  ### Reading Config Files
    88  
    89  Viper requires minimal configuration so it knows where to look for config files.
    90  Viper supports JSON, TOML, YAML, HCL, envfile and Java Properties files. Viper can search multiple paths, but
    91  currently a single Viper instance only supports a single configuration file.
    92  Viper does not default to any configuration search paths leaving defaults decision
    93  to an application.
    94  
    95  Here is an example of how to use Viper to search for and read a configuration file.
    96  None of the specific paths are required, but at least one path should be provided
    97  where a configuration file is expected.
    98  
    99  ```go
   100  viper.SetConfigName("config") // name of config file (without extension)
   101  viper.AddConfigPath("/etc/appname/")   // path to look for the config file in
   102  viper.AddConfigPath("$HOME/.appname")  // call multiple times to add many search paths
   103  viper.AddConfigPath(".")               // optionally look for config in the working directory
   104  err := viper.ReadInConfig() // Find and read the config file
   105  if err != nil { // Handle errors reading the config file
   106  	panic(fmt.Errorf("Fatal error config file: %s \n", err))
   107  }
   108  ```
   109  
   110  You can handle the specific case where no config file is found like this:
   111  
   112  ```go
   113  if err := viper.ReadInConfig(); err != nil {
   114      if _, ok := err.(viper.ConfigFileNotFoundError); ok {
   115          // Config file not found; ignore error if desired
   116      } else {
   117          // Config file was found but another error was produced
   118      }
   119  }
   120  
   121  // Config file found and successfully parsed
   122  ```
   123  
   124  ### Writing Config Files
   125  
   126  Reading from config files is useful, but at times you want to store all modifications made at run time.
   127  For that, a bunch of commands are available, each with its own purpose:
   128  
   129  * 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.
   130  * 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.
   131  * WriteConfigAs - writes the current viper configuration to the given filepath. Will overwrite the given file, if it exists.
   132  * SafeWriteConfigAs - writes the current viper configuration to the given filepath. Will not overwrite the given file, if it exists.
   133  
   134  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.
   135  
   136  A small examples section:
   137  
   138  ```go
   139  viper.WriteConfig() // writes current config to predefined path set by 'viper.AddConfigPath()' and 'viper.SetConfigName'
   140  viper.SafeWriteConfig()
   141  viper.WriteConfigAs("/path/to/my/.config")
   142  viper.SafeWriteConfigAs("/path/to/my/.config") // will error since it has already been written
   143  viper.SafeWriteConfigAs("/path/to/my/.other_config")
   144  ```
   145  
   146  ### Watching and re-reading config files
   147  
   148  Viper supports the ability to have your application live read a config file while running.
   149  
   150  Gone are the days of needing to restart a server to have a config take effect,
   151  viper powered applications can read an update to a config file while running and
   152  not miss a beat.
   153  
   154  Simply tell the viper instance to watchConfig.
   155  Optionally you can provide a function for Viper to run each time a change occurs.
   156  
   157  **Make sure you add all of the configPaths prior to calling `WatchConfig()`**
   158  
   159  ```go
   160  viper.WatchConfig()
   161  viper.OnConfigChange(func(e fsnotify.Event) {
   162  	fmt.Println("Config file changed:", e.Name)
   163  })
   164  ```
   165  
   166  ### Reading Config from io.Reader
   167  
   168  Viper predefines many configuration sources such as files, environment
   169  variables, flags, and remote K/V store, but you are not bound to them. You can
   170  also implement your own required configuration source and feed it to viper.
   171  
   172  ```go
   173  viper.SetConfigType("yaml") // or viper.SetConfigType("YAML")
   174  
   175  // any approach to require this configuration into your program.
   176  var yamlExample = []byte(`
   177  Hacker: true
   178  name: steve
   179  hobbies:
   180  - skateboarding
   181  - snowboarding
   182  - go
   183  clothing:
   184    jacket: leather
   185    trousers: denim
   186  age: 35
   187  eyes : brown
   188  beard: true
   189  `)
   190  
   191  viper.ReadConfig(bytes.NewBuffer(yamlExample))
   192  
   193  viper.Get("name") // this would be "steve"
   194  ```
   195  
   196  ### Setting Overrides
   197  
   198  These could be from a command line flag, or from your own application logic.
   199  
   200  ```go
   201  viper.Set("Verbose", true)
   202  viper.Set("LogFile", LogFile)
   203  ```
   204  
   205  ### Registering and Using Aliases
   206  
   207  Aliases permit a single value to be referenced by multiple keys
   208  
   209  ```go
   210  viper.RegisterAlias("loud", "Verbose")
   211  
   212  viper.Set("verbose", true) // same result as next line
   213  viper.Set("loud", true)   // same result as prior line
   214  
   215  viper.GetBool("loud") // true
   216  viper.GetBool("verbose") // true
   217  ```
   218  
   219  ### Working with Environment Variables
   220  
   221  Viper has full support for environment variables. This enables 12 factor
   222  applications out of the box. There are five methods that exist to aid working
   223  with ENV:
   224  
   225   * `AutomaticEnv()`
   226   * `BindEnv(string...) : error`
   227   * `SetEnvPrefix(string)`
   228   * `SetEnvKeyReplacer(string...) *strings.Replacer`
   229   * `AllowEmptyEnv(bool)`
   230  
   231  _When working with ENV variables, it’s important to recognize that Viper
   232  treats ENV variables as case sensitive._
   233  
   234  Viper provides a mechanism to try to ensure that ENV variables are unique. By
   235  using `SetEnvPrefix`, you can tell Viper to use a prefix while reading from
   236  the environment variables. Both `BindEnv` and `AutomaticEnv` will use this
   237  prefix.
   238  
   239  `BindEnv` takes one or two parameters. The first parameter is the key name, the
   240  second is the name of the environment variable. The name of the environment
   241  variable is case sensitive. If the ENV variable name is not provided, then
   242  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),
   243  it **does not** automatically add the prefix. For example if the second parameter is "id",
   244  Viper will look for the ENV variable "ID".
   245  
   246  One important thing to recognize when working with ENV variables is that the
   247  value will be read each time it is accessed. Viper does not fix the value when
   248  the `BindEnv` is called.
   249  
   250  `AutomaticEnv` is a powerful helper especially when combined with
   251  `SetEnvPrefix`. When called, Viper will check for an environment variable any
   252  time a `viper.Get` request is made. It will apply the following rules. It will
   253  check for a environment variable with a name matching the key uppercased and
   254  prefixed with the `EnvPrefix` if set.
   255  
   256  `SetEnvKeyReplacer` allows you to use a `strings.Replacer` object to rewrite Env
   257  keys to an extent. This is useful if you want to use `-` or something in your
   258  `Get()` calls, but want your environmental variables to use `_` delimiters. An
   259  example of using it can be found in `viper_test.go`.
   260  
   261  By default empty environment variables are considered unset and will fall back to
   262  the next configuration source. To treat empty environment variables as set, use
   263  the `AllowEmptyEnv` method.
   264  
   265  #### Env example
   266  
   267  ```go
   268  SetEnvPrefix("spf") // will be uppercased automatically
   269  BindEnv("id")
   270  
   271  os.Setenv("SPF_ID", "13") // typically done outside of the app
   272  
   273  id := Get("id") // 13
   274  ```
   275  
   276  ### Working with Flags
   277  
   278  Viper has the ability to bind to flags. Specifically, Viper supports `Pflags`
   279  as used in the [Cobra](https://github.com/spf13/cobra) library.
   280  
   281  Like `BindEnv`, the value is not set when the binding method is called, but when
   282  it is accessed. This means you can bind as early as you want, even in an
   283  `init()` function.
   284  
   285  For individual flags, the `BindPFlag()` method provides this functionality.
   286  
   287  Example:
   288  
   289  ```go
   290  serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
   291  viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
   292  ```
   293  
   294  You can also bind an existing set of pflags (pflag.FlagSet):
   295  
   296  Example:
   297  
   298  ```go
   299  pflag.Int("flagname", 1234, "help message for flagname")
   300  
   301  pflag.Parse()
   302  viper.BindPFlags(pflag.CommandLine)
   303  
   304  i := viper.GetInt("flagname") // retrieve values from viper instead of pflag
   305  ```
   306  
   307  The use of [pflag](https://github.com/spf13/pflag/) in Viper does not preclude
   308  the use of other packages that use the [flag](https://golang.org/pkg/flag/)
   309  package from the standard library. The pflag package can handle the flags
   310  defined for the flag package by importing these flags. This is accomplished
   311  by a calling a convenience function provided by the pflag package called
   312  AddGoFlagSet().
   313  
   314  Example:
   315  
   316  ```go
   317  package main
   318  
   319  import (
   320  	"flag"
   321  	"github.com/spf13/pflag"
   322  )
   323  
   324  func main() {
   325  
   326  	// using standard library "flag" package
   327  	flag.Int("flagname", 1234, "help message for flagname")
   328  
   329  	pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
   330  	pflag.Parse()
   331  	viper.BindPFlags(pflag.CommandLine)
   332  
   333  	i := viper.GetInt("flagname") // retrieve value from viper
   334  
   335  	...
   336  }
   337  ```
   338  
   339  #### Flag interfaces
   340  
   341  Viper provides two Go interfaces to bind other flag systems if you don’t use `Pflags`.
   342  
   343  `FlagValue` represents a single flag. This is a very simple example on how to implement this interface:
   344  
   345  ```go
   346  type myFlag struct {}
   347  func (f myFlag) HasChanged() bool { return false }
   348  func (f myFlag) Name() string { return "my-flag-name" }
   349  func (f myFlag) ValueString() string { return "my-flag-value" }
   350  func (f myFlag) ValueType() string { return "string" }
   351  ```
   352  
   353  Once your flag implements this interface, you can simply tell Viper to bind it:
   354  
   355  ```go
   356  viper.BindFlagValue("my-flag-name", myFlag{})
   357  ```
   358  
   359  `FlagValueSet` represents a group of flags. This is a very simple example on how to implement this interface:
   360  
   361  ```go
   362  type myFlagSet struct {
   363  	flags []myFlag
   364  }
   365  
   366  func (f myFlagSet) VisitAll(fn func(FlagValue)) {
   367  	for _, flag := range flags {
   368  		fn(flag)
   369  	}
   370  }
   371  ```
   372  
   373  Once your flag set implements this interface, you can simply tell Viper to bind it:
   374  
   375  ```go
   376  fSet := myFlagSet{
   377  	flags: []myFlag{myFlag{}, myFlag{}},
   378  }
   379  viper.BindFlagValues("my-flags", fSet)
   380  ```
   381  
   382  ### Remote Key/Value Store Support
   383  
   384  To enable remote support in Viper, do a blank import of the `viper/remote`
   385  package:
   386  
   387  `import _ "github.com/spf13/viper/remote"`
   388  
   389  Viper will read a config string (as JSON, TOML, YAML, HCL or envfile) retrieved from a path
   390  in a Key/Value store such as etcd or Consul.  These values take precedence over
   391  default values, but are overridden by configuration values retrieved from disk,
   392  flags, or environment variables.
   393  
   394  Viper uses [crypt](https://github.com/xordataexchange/crypt) to retrieve
   395  configuration from the K/V store, which means that you can store your
   396  configuration values encrypted and have them automatically decrypted if you have
   397  the correct gpg keyring.  Encryption is optional.
   398  
   399  You can use remote configuration in conjunction with local configuration, or
   400  independently of it.
   401  
   402  `crypt` has a command-line helper that you can use to put configurations in your
   403  K/V store. `crypt` defaults to etcd on http://127.0.0.1:4001.
   404  
   405  ```bash
   406  $ go get github.com/xordataexchange/crypt/bin/crypt
   407  $ crypt set -plaintext /config/hugo.json /Users/hugo/settings/config.json
   408  ```
   409  
   410  Confirm that your value was set:
   411  
   412  ```bash
   413  $ crypt get -plaintext /config/hugo.json
   414  ```
   415  
   416  See the `crypt` documentation for examples of how to set encrypted values, or
   417  how to use Consul.
   418  
   419  ### Remote Key/Value Store Example - Unencrypted
   420  
   421  #### etcd
   422  ```go
   423  viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001","/config/hugo.json")
   424  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"
   425  err := viper.ReadRemoteConfig()
   426  ```
   427  
   428  #### Consul
   429  You need to set a key to Consul key/value storage with JSON value containing your desired config.  
   430  For example, create a Consul key/value store key `MY_CONSUL_KEY` with value:
   431  
   432  ```json
   433  {
   434      "port": 8080,
   435      "hostname": "myhostname.com"
   436  }
   437  ```
   438  
   439  ```go
   440  viper.AddRemoteProvider("consul", "localhost:8500", "MY_CONSUL_KEY")
   441  viper.SetConfigType("json") // Need to explicitly set this to json
   442  err := viper.ReadRemoteConfig()
   443  
   444  fmt.Println(viper.Get("port")) // 8080
   445  fmt.Println(viper.Get("hostname")) // myhostname.com
   446  ```
   447  
   448  ### Remote Key/Value Store Example - Encrypted
   449  
   450  ```go
   451  viper.AddSecureRemoteProvider("etcd","http://127.0.0.1:4001","/config/hugo.json","/etc/secrets/mykeyring.gpg")
   452  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"
   453  err := viper.ReadRemoteConfig()
   454  ```
   455  
   456  ### Watching Changes in etcd - Unencrypted
   457  
   458  ```go
   459  // alternatively, you can create a new viper instance.
   460  var runtime_viper = viper.New()
   461  
   462  runtime_viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001", "/config/hugo.yml")
   463  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"
   464  
   465  // read from remote config the first time.
   466  err := runtime_viper.ReadRemoteConfig()
   467  
   468  // unmarshal config
   469  runtime_viper.Unmarshal(&runtime_conf)
   470  
   471  // open a goroutine to watch remote changes forever
   472  go func(){
   473  	for {
   474  	    time.Sleep(time.Second * 5) // delay after each request
   475  
   476  	    // currently, only tested with etcd support
   477  	    err := runtime_viper.WatchRemoteConfig()
   478  	    if err != nil {
   479  	        log.Errorf("unable to read remote config: %v", err)
   480  	        continue
   481  	    }
   482  
   483  	    // unmarshal new config into our runtime config struct. you can also use channel
   484  	    // to implement a signal to notify the system of the changes
   485  	    runtime_viper.Unmarshal(&runtime_conf)
   486  	}
   487  }()
   488  ```
   489  
   490  ## Getting Values From Viper
   491  
   492  In Viper, there are a few ways to get a value depending on the value’s type.
   493  The following functions and methods exist:
   494  
   495   * `Get(key string) : interface{}`
   496   * `GetBool(key string) : bool`
   497   * `GetFloat64(key string) : float64`
   498   * `GetInt(key string) : int`
   499   * `GetIntSlice(key string) : []int`
   500   * `GetString(key string) : string`
   501   * `GetStringMap(key string) : map[string]interface{}`
   502   * `GetStringMapString(key string) : map[string]string`
   503   * `GetStringSlice(key string) : []string`
   504   * `GetTime(key string) : time.Time`
   505   * `GetDuration(key string) : time.Duration`
   506   * `IsSet(key string) : bool`
   507   * `AllSettings() : map[string]interface{}`
   508  
   509  One important thing to recognize is that each Get function will return a zero
   510  value if it’s not found. To check if a given key exists, the `IsSet()` method
   511  has been provided.
   512  
   513  Example:
   514  ```go
   515  viper.GetString("logfile") // case-insensitive Setting & Getting
   516  if viper.GetBool("verbose") {
   517      fmt.Println("verbose enabled")
   518  }
   519  ```
   520  ### Accessing nested keys
   521  
   522  The accessor methods also accept formatted paths to deeply nested keys. For
   523  example, if the following JSON file is loaded:
   524  
   525  ```json
   526  {
   527      "host": {
   528          "address": "localhost",
   529          "port": 5799
   530      },
   531      "datastore": {
   532          "metric": {
   533              "host": "127.0.0.1",
   534              "port": 3099
   535          },
   536          "warehouse": {
   537              "host": "198.0.0.1",
   538              "port": 2112
   539          }
   540      }
   541  }
   542  
   543  ```
   544  
   545  Viper can access a nested field by passing a `.` delimited path of keys:
   546  
   547  ```go
   548  GetString("datastore.metric.host") // (returns "127.0.0.1")
   549  ```
   550  
   551  This obeys the precedence rules established above; the search for the path
   552  will cascade through the remaining configuration registries until found.
   553  
   554  For example, given this configuration file, both `datastore.metric.host` and
   555  `datastore.metric.port` are already defined (and may be overridden). If in addition
   556  `datastore.metric.protocol` was defined in the defaults, Viper would also find it.
   557  
   558  However, if `datastore.metric` was overridden (by a flag, an environment variable,
   559  the `Set()` method, …) with an immediate value, then all sub-keys of
   560  `datastore.metric` become undefined, they are “shadowed” by the higher-priority
   561  configuration level.
   562  
   563  Lastly, if there exists a key that matches the delimited key path, its value
   564  will be returned instead. E.g.
   565  
   566  ```json
   567  {
   568      "datastore.metric.host": "0.0.0.0",
   569      "host": {
   570          "address": "localhost",
   571          "port": 5799
   572      },
   573      "datastore": {
   574          "metric": {
   575              "host": "127.0.0.1",
   576              "port": 3099
   577          },
   578          "warehouse": {
   579              "host": "198.0.0.1",
   580              "port": 2112
   581          }
   582      }
   583  }
   584  
   585  GetString("datastore.metric.host") // returns "0.0.0.0"
   586  ```
   587  
   588  ### Extract sub-tree
   589  
   590  Extract sub-tree from Viper.
   591  
   592  For example, `viper` represents:
   593  
   594  ```json
   595  app:
   596    cache1:
   597      max-items: 100
   598      item-size: 64
   599    cache2:
   600      max-items: 200
   601      item-size: 80
   602  ```
   603  
   604  After executing:
   605  
   606  ```go
   607  subv := viper.Sub("app.cache1")
   608  ```
   609  
   610  `subv` represents:
   611  
   612  ```json
   613  max-items: 100
   614  item-size: 64
   615  ```
   616  
   617  Suppose we have:
   618  
   619  ```go
   620  func NewCache(cfg *Viper) *Cache {...}
   621  ```
   622  
   623  which creates a cache based on config information formatted as `subv`.
   624  Now it’s easy to create these 2 caches separately as:
   625  
   626  ```go
   627  cfg1 := viper.Sub("app.cache1")
   628  cache1 := NewCache(cfg1)
   629  
   630  cfg2 := viper.Sub("app.cache2")
   631  cache2 := NewCache(cfg2)
   632  ```
   633  
   634  ### Unmarshaling
   635  
   636  You also have the option of Unmarshaling all or a specific value to a struct, map,
   637  etc.
   638  
   639  There are two methods to do this:
   640  
   641   * `Unmarshal(rawVal interface{}) : error`
   642   * `UnmarshalKey(key string, rawVal interface{}) : error`
   643  
   644  Example:
   645  
   646  ```go
   647  type config struct {
   648  	Port int
   649  	Name string
   650  	PathMap string `mapstructure:"path_map"`
   651  }
   652  
   653  var C config
   654  
   655  err := viper.Unmarshal(&C)
   656  if err != nil {
   657  	t.Fatalf("unable to decode into struct, %v", err)
   658  }
   659  ```
   660  
   661  Viper uses [github.com/mitchellh/mapstructure](https://github.com/mitchellh/mapstructure) under the hood for unmarshaling values which uses `mapstructure` tags by default.
   662  
   663  ### Marshalling to string
   664  
   665  You may need to marshal all the settings held in viper into a string rather than write them to a file. 
   666  You can use your favorite format's marshaller with the config returned by `AllSettings()`.
   667  
   668  ```go
   669  import (
   670      yaml "gopkg.in/yaml.v2"
   671      // ...
   672  ) 
   673  
   674  func yamlStringSettings() string {
   675      c := viper.AllSettings()
   676      bs, err := yaml.Marshal(c)
   677      if err != nil {
   678          log.Fatalf("unable to marshal config to YAML: %v", err)
   679      }
   680      return string(bs)
   681  }
   682  ```
   683  
   684  ## Viper or Vipers?
   685  
   686  Viper comes ready to use out of the box. There is no configuration or
   687  initialization needed to begin using Viper. Since most applications will want
   688  to use a single central repository for their configuration, the viper package
   689  provides this. It is similar to a singleton.
   690  
   691  In all of the examples above, they demonstrate using viper in its singleton
   692  style approach.
   693  
   694  ### Working with multiple vipers
   695  
   696  You can also create many different vipers for use in your application. Each will
   697  have its own unique set of configurations and values. Each can read from a
   698  different config file, key value store, etc. All of the functions that viper
   699  package supports are mirrored as methods on a viper.
   700  
   701  Example:
   702  
   703  ```go
   704  x := viper.New()
   705  y := viper.New()
   706  
   707  x.SetDefault("ContentDir", "content")
   708  y.SetDefault("ContentDir", "foobar")
   709  
   710  //...
   711  ```
   712  
   713  When working with multiple vipers, it is up to the user to keep track of the
   714  different vipers.
   715  
   716  ## Q & A
   717  
   718  Q: Why not INI files?
   719  
   720  A: Ini files are pretty awful. There’s no standard format, and they are hard to
   721  validate. Viper is designed to work with JSON, TOML or YAML files. If someone
   722  really wants to add this feature, I’d be happy to merge it. It’s easy to specify
   723  which formats your application will permit.
   724  
   725  Q: Why is it called “Viper”?
   726  
   727  A: Viper is designed to be a [companion](http://en.wikipedia.org/wiki/Viper_(G.I._Joe))
   728  to [Cobra](https://github.com/spf13/cobra). While both can operate completely
   729  independently, together they make a powerful pair to handle much of your
   730  application foundation needs.
   731  
   732  Q: Why is it called “Cobra”?
   733  
   734  A: Is there a better name for a [commander](http://en.wikipedia.org/wiki/Cobra_Commander)?