Syntax highlighting

This commit is contained in:
Maxime Horcholle 2015-07-16 14:16:31 +02:00 committed by spf13
parent db7ff930a1
commit 1e6a237e05
1 changed files with 109 additions and 86 deletions

195
README.md
View File

@ -63,9 +63,11 @@ remote configuration or flag.
Examples: Examples:
viper.SetDefault("ContentDir", "content") ```go
viper.SetDefault("LayoutDir", "layouts") viper.SetDefault("ContentDir", "content")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"}) viper.SetDefault("LayoutDir", "layouts")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
```
### Reading Config Files ### Reading Config Files
@ -74,13 +76,15 @@ configuration so it knows where to look for the config file. 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 only supports a single config file. currently a single viper only supports a single config file.
viper.SetConfigName("config") // name of config file (without extension) ```go
viper.AddConfigPath("/etc/appname/") // path to look for the config file in viper.SetConfigName("config") // name of config file (without extension)
viper.AddConfigPath("$HOME/.appname") // call multiple times to add many search paths viper.AddConfigPath("/etc/appname/") // path to look for the config file in
err := viper.ReadInConfig() // Find and read the config file viper.AddConfigPath("$HOME/.appname") // call multiple times to add many search paths
if err != nil { // Handle errors reading the config file err := viper.ReadInConfig() // Find and read the config file
panic(fmt.Errorf("Fatal error config file: %s \n", err)) if err != nil { // Handle errors reading the config file
} panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
```
### Reading Config from io.Reader ### Reading Config from io.Reader
@ -88,7 +92,7 @@ Viper predefined many configuration sources, such as files, environment variable
remote K/V store. But you are not bound to them. You can also implement your own way to remote K/V store. But you are not bound to them. You can also implement your own way to
require configuration and feed it to viper. require configuration 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.
@ -110,26 +114,30 @@ beard: true
viper.ReadConfig(bytes.NewBuffer(yamlExample)) viper.ReadConfig(bytes.NewBuffer(yamlExample))
viper.Get("name") // this would be "steve" viper.Get("name") // this would be "steve"
```` ```
### Setting Overrides ### Setting Overrides
These could be from a command line flag, or from your own application logic. These could be from a command line flag, or from your own application logic.
viper.Set("Verbose", true) ```go
viper.Set("LogFile", LogFile) viper.Set("Verbose", true)
viper.Set("LogFile", LogFile)
```
### Registering and Using Aliases ### Registering and Using Aliases
Aliases permit a single value to be referenced by multiple keys Aliases permit a single value to be referenced by multiple keys
viper.RegisterAlias("loud", "Verbose") ```go
viper.RegisterAlias("loud", "Verbose")
viper.Set("verbose", true) // same result as next line viper.Set("verbose", true) // same result as next line
viper.Set("loud", true) // same result as prior line viper.Set("loud", true) // same result as prior line
viper.GetBool("loud") // true viper.GetBool("loud") // true
viper.GetBool("verbose") // true viper.GetBool("verbose") // true
```
### Working with Environment Variables ### Working with Environment Variables
@ -175,13 +183,14 @@ of using it can be found in `viper_test.go`.
#### Env example #### Env example
SetEnvPrefix("spf") // will be uppercased automatically ```go
BindEnv("id") SetEnvPrefix("spf") // will be uppercased automatically
BindEnv("id")
os.Setenv("SPF_ID", "13") // typically done outside of the app os.Setenv("SPF_ID", "13") // typically done outside of the app
id := Get("id") // 13
id := Get("id") // 13
```
### Working with Flags ### Working with Flags
@ -196,9 +205,10 @@ The BindPFlag() method provides this functionality.
Example: Example:
serverCmd.Flags().Int("port", 1138, "Port to run Application server on") ```go
viper.BindPFlag("port", serverCmd.Flags().Lookup("port")) serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
```
### Remote Key/Value Store Support ### Remote Key/Value Store Support
@ -222,60 +232,69 @@ 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 K/V store. `crypt` defaults to etcd on http://127.0.0.1:4001. in your K/V store. `crypt` defaults to etcd on http://127.0.0.1:4001.
go get github.com/xordataexchange/crypt/bin/crypt ```bash
crypt set -plaintext /config/hugo.json /Users/hugo/settings/config.json $ go get github.com/xordataexchange/crypt/bin/crypt
$ crypt set -plaintext /config/hugo.json /Users/hugo/settings/config.json
```
Confirm that your value was set: Confirm that your value was set:
crypt get -plaintext /config/hugo.json ```bash
$ 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 how
to use Consul. to use Consul.
### Remote Key/Value Store Example - Unencrypted ### Remote Key/Value Store Example - Unencrypted
viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001","/config/hugo.json") ```go
viper.SetConfigType("json") // because there is no file extension in a stream of bytes viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001","/config/hugo.json")
err := viper.ReadRemoteConfig() viper.SetConfigType("json") // because there is no file extension in a stream of bytes
err := viper.ReadRemoteConfig()
```
### Remote Key/Value Store Example - Encrypted ### Remote Key/Value Store Example - Encrypted
viper.AddSecureRemoteProvider("etcd","http://127.0.0.1:4001","/config/hugo.json","/etc/secrets/mykeyring.gpg") ```go
viper.SetConfigType("json") // because there is no file extension in a stream of bytes viper.AddSecureRemoteProvider("etcd","http://127.0.0.1:4001","/config/hugo.json","/etc/secrets/mykeyring.gpg")
err := viper.ReadRemoteConfig() viper.SetConfigType("json") // because there is no file extension in a stream of bytes
err := viper.ReadRemoteConfig()
```
### Watching Changes in Etcd - Unencrypted ### Watching Changes in Etcd - Unencrypted
// alternatively, you can create a new viper instance. ```go
var runtime_viper = viper.New() // alternatively, you can create a new viper instance.
var runtime_viper = viper.New()
runtime_viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001", "/config/hugo.yml") 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 runtime_viper.SetConfigType("yaml") // because there is no file extension in a stream of bytes
// read from remote config the first time. // read from remote config the first time.
err := runtime_viper.ReadRemoteConfig() err := runtime_viper.ReadRemoteConfig()
// marshal config // marshal config
runtime_viper.Marshal(&runtime_conf) runtime_viper.Marshal(&runtime_conf)
// open a goroutine to wath remote changes forever
go func(){
for {
time.Sleep(time.Second * 5) // delay after each request
// currenlty, only tested with etcd support
err := runtime_viper.WatchRemoteConfig()
if err != nil {
log.Errorf("unable to read remote config: %v", err)
continue
}
// marshal new config into our runtime config struct. you can also use channel
// to implement a signal to notify the system of the changes
runtime_viper.Marshal(&runtime_conf)
}
}()
// open a goroutine to wath remote changes forever
go func(){
for {
time.Sleep(time.Second * 5) // delay after each request
// currenlty, only tested with etcd support
err := runtime_viper.WatchRemoteConfig()
if err != nil {
log.Errorf("unable to read remote config: %v", err)
continue
}
// marshal new config into our runtime config struct. you can also use channel
// to implement a signal to notify the system of the changes
runtime_viper.Marshal(&runtime_conf)
}
}()
```
## Getting Values From Viper ## Getting Values From Viper
@ -299,18 +318,18 @@ its zero value if its not found. To check if a given key exists, the IsSet()
method has been provided. method has been provided.
Example: Example:
```go
viper.GetString("logfile") // case-insensitive Setting & Getting viper.GetString("logfile") // case-insensitive Setting & Getting
if viper.GetBool("verbose") { if viper.GetBool("verbose") {
fmt.Println("verbose enabled") fmt.Println("verbose enabled")
} }
```
### 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 example, if the following JSON file is loaded: For example, if the following JSON file is loaded:
``` ```json
{ {
"host": { "host": {
"address": "localhost", "address": "localhost",
@ -331,7 +350,8 @@ For example, if the following JSON file is loaded:
``` ```
Viper can access a nested field by passing a `.` delimited path of keys: Viper can access a nested field by passing a `.` delimited path of keys:
```
```go
GetString("datastore.metric.host") // (returns "127.0.0.1") GetString("datastore.metric.host") // (returns "127.0.0.1")
``` ```
@ -348,7 +368,7 @@ 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 will
be returned instead. E.g. be returned instead. E.g.
``` ```json
{ {
"datastore.metric.host": "0.0.0.0", "datastore.metric.host": "0.0.0.0",
"host": { "host": {
@ -381,18 +401,19 @@ There are two methods to do this:
Example: Example:
type config struct { ```go
Port int type config struct {
Name string Port int
} Name string
}
var C config var C config
err := Marshal(&C)
if err != nil {
t.Fatalf("unable to decode into struct, %v", err)
}
err := Marshal(&C)
if err != nil {
t.Fatalf("unable to decode into struct, %v", err)
}
```
## Viper or Vipers? ## Viper or Vipers?
@ -413,13 +434,15 @@ functions that viper package supports are mirrored as methods on a viper.
Example: Example:
x := viper.New() ```go
y := viper.New() x := viper.New()
y := viper.New()
x.SetDefault("ContentDir", "content") x.SetDefault("ContentDir", "content")
y.SetDefault("ContentDir", "foobar") 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 different vipers. the different vipers.