mirror of
https://github.com/spf13/viper
synced 2024-12-22 19:47:01 +00:00
Syntax highlighting
This commit is contained in:
parent
db7ff930a1
commit
1e6a237e05
1 changed files with 109 additions and 86 deletions
195
README.md
195
README.md
|
@ -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 it’s 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.
|
||||||
|
|
Loading…
Reference in a new issue