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

191
README.md
View File

@ -63,9 +63,11 @@ remote configuration or flag.
Examples:
viper.SetDefault("ContentDir", "content")
viper.SetDefault("LayoutDir", "layouts")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
```go
viper.SetDefault("ContentDir", "content")
viper.SetDefault("LayoutDir", "layouts")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
```
### 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
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
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
```go
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
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
```
### 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
require configuration and feed it to viper.
````go
```go
viper.SetConfigType("yaml") // or viper.SetConfigType("YAML")
// any approach to require this configuration into your program.
@ -110,26 +114,30 @@ beard: true
viper.ReadConfig(bytes.NewBuffer(yamlExample))
viper.Get("name") // this would be "steve"
````
```
### Setting Overrides
These could be from a command line flag, or from your own application logic.
viper.Set("Verbose", true)
viper.Set("LogFile", LogFile)
```go
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")
```go
viper.RegisterAlias("loud", "Verbose")
viper.Set("verbose", true) // same result as next line
viper.Set("loud", true) // same result as prior line
viper.Set("verbose", true) // same result as next line
viper.Set("loud", true) // same result as prior line
viper.GetBool("loud") // true
viper.GetBool("verbose") // true
viper.GetBool("loud") // true
viper.GetBool("verbose") // true
```
### Working with Environment Variables
@ -175,13 +183,14 @@ of using it can be found in `viper_test.go`.
#### Env example
SetEnvPrefix("spf") // will be uppercased automatically
BindEnv("id")
```go
SetEnvPrefix("spf") // will be uppercased automatically
BindEnv("id")
os.Setenv("SPF_ID", "13") // typically done outside of the app
id := Get("id") // 13
os.Setenv("SPF_ID", "13") // typically done outside of the app
id := Get("id") // 13
```
### Working with Flags
@ -196,9 +205,10 @@ 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"))
```go
serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
```
### 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
in your K/V store. `crypt` defaults to etcd on http://127.0.0.1:4001.
go get github.com/xordataexchange/crypt/bin/crypt
crypt set -plaintext /config/hugo.json /Users/hugo/settings/config.json
```bash
$ 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:
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
to use Consul.
### Remote Key/Value Store Example - Unencrypted
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
err := viper.ReadRemoteConfig()
```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
err := viper.ReadRemoteConfig()
```
### Remote Key/Value Store Example - Encrypted
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
err := viper.ReadRemoteConfig()
```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
err := viper.ReadRemoteConfig()
```
### Watching Changes in Etcd - Unencrypted
// alternatively, you can create a new viper instance.
var runtime_viper = viper.New()
```go
// 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.SetConfigType("yaml") // because there is no file extension in a stream of bytes
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
// read from remote config the first time.
err := runtime_viper.ReadRemoteConfig()
// read from remote config the first time.
err := runtime_viper.ReadRemoteConfig()
// marshal config
runtime_viper.Marshal(&runtime_conf)
// marshal config
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
// 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)
}
}()
// 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
@ -299,18 +318,18 @@ its zero value if its not found. To check if a given key exists, the IsSet()
method has been provided.
Example:
viper.GetString("logfile") // case-insensitive Setting & Getting
if viper.GetBool("verbose") {
fmt.Println("verbose enabled")
}
```go
viper.GetString("logfile") // case-insensitive Setting & Getting
if viper.GetBool("verbose") {
fmt.Println("verbose enabled")
}
```
### Accessing nested keys
The accessor methods also accept formatted paths to deeply nested keys.
For example, if the following JSON file is loaded:
```
```json
{
"host": {
"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:
```
```go
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
be returned instead. E.g.
```
```json
{
"datastore.metric.host": "0.0.0.0",
"host": {
@ -381,18 +401,19 @@ There are two methods to do this:
Example:
type config struct {
Port int
Name string
}
```go
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)
}
var C config
err := Marshal(&C)
if err != nil {
t.Fatalf("unable to decode into struct, %v", err)
}
```
## Viper or Vipers?
@ -413,13 +434,15 @@ functions that viper package supports are mirrored as methods on a viper.
Example:
x := viper.New()
y := viper.New()
```go
x := viper.New()
y := viper.New()
x.SetDefault("ContentDir", "content")
y.SetDefault("ContentDir", "foobar")
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.