mirror of
https://github.com/spf13/viper
synced 2024-12-22 19:47:01 +00:00
Add key delimiter setter
This commit is contained in:
parent
b6ced70067
commit
a73303ee89
2 changed files with 82 additions and 5 deletions
19
viper.go
19
viper.go
|
@ -34,14 +34,14 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
"github.com/hashicorp/hcl"
|
"github.com/hashicorp/hcl"
|
||||||
"github.com/hashicorp/hcl/hcl/printer"
|
"github.com/hashicorp/hcl/hcl/printer"
|
||||||
"github.com/magiconair/properties"
|
"github.com/magiconair/properties"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
toml "github.com/pelletier/go-toml"
|
"github.com/pelletier/go-toml"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
jww "github.com/spf13/jwalterweatherman"
|
||||||
|
@ -245,6 +245,15 @@ func Reset() {
|
||||||
SupportedRemoteProviders = []string{"etcd", "consul"}
|
SupportedRemoteProviders = []string{"etcd", "consul"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetKeyDelimiter sets the delimiter used for determining key parts.
|
||||||
|
// By default it's value is ".".
|
||||||
|
func SetKeyDelimiter(keyDelim string) { v.SetKeyDelimiter(keyDelim) }
|
||||||
|
func (v *Viper) SetKeyDelimiter(keyDelim string) {
|
||||||
|
if keyDelim != "" {
|
||||||
|
v.keyDelim = keyDelim
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type defaultRemoteProvider struct {
|
type defaultRemoteProvider struct {
|
||||||
provider string
|
provider string
|
||||||
endpoint string
|
endpoint string
|
||||||
|
@ -1720,7 +1729,7 @@ func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}
|
||||||
func (v *Viper) watchKeyValueConfigOnChannel() error {
|
func (v *Viper) watchKeyValueConfigOnChannel() error {
|
||||||
for _, rp := range v.remoteProviders {
|
for _, rp := range v.remoteProviders {
|
||||||
respc, _ := RemoteConfig.WatchChannel(rp)
|
respc, _ := RemoteConfig.WatchChannel(rp)
|
||||||
//Todo: Add quit channel
|
// Todo: Add quit channel
|
||||||
go func(rc <-chan *RemoteResponse) {
|
go func(rc <-chan *RemoteResponse) {
|
||||||
for {
|
for {
|
||||||
b := <-rc
|
b := <-rc
|
||||||
|
@ -1756,7 +1765,7 @@ func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllKeys returns all keys holding a value, regardless of where they are set.
|
// AllKeys returns all keys holding a value, regardless of where they are set.
|
||||||
// Nested keys are returned with a v.keyDelim (= ".") separator
|
// Nested keys are returned with a v.keyDelim separator
|
||||||
func AllKeys() []string { return v.AllKeys() }
|
func AllKeys() []string { return v.AllKeys() }
|
||||||
func (v *Viper) AllKeys() []string {
|
func (v *Viper) AllKeys() []string {
|
||||||
m := map[string]bool{}
|
m := map[string]bool{}
|
||||||
|
@ -1779,7 +1788,7 @@ func (v *Viper) AllKeys() []string {
|
||||||
|
|
||||||
// flattenAndMergeMap recursively flattens the given map into a map[string]bool
|
// flattenAndMergeMap recursively flattens the given map into a map[string]bool
|
||||||
// of key paths (used as a set, easier to manipulate than a []string):
|
// of key paths (used as a set, easier to manipulate than a []string):
|
||||||
// - each path is merged into a single key string, delimited with v.keyDelim (= ".")
|
// - each path is merged into a single key string, delimited with v.keyDelim
|
||||||
// - if a path is shadowed by an earlier value in the initial shadow map,
|
// - if a path is shadowed by an earlier value in the initial shadow map,
|
||||||
// it is skipped.
|
// it is skipped.
|
||||||
// The resulting set of paths is merged to the given shadow set at the same time.
|
// The resulting set of paths is merged to the given shadow set at the same time.
|
||||||
|
|
|
@ -2009,6 +2009,74 @@ func TestUnmarshal_DotSeparatorBackwardCompatibility(t *testing.T) {
|
||||||
assert.Equal(t, "cobra_flag", config.Foo.Bar)
|
assert.Equal(t, "cobra_flag", config.Foo.Bar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var yamlExampleWithDot = []byte(`Hacker: true
|
||||||
|
name: steve
|
||||||
|
hobbies:
|
||||||
|
- skateboarding
|
||||||
|
- snowboarding
|
||||||
|
- go
|
||||||
|
clothing:
|
||||||
|
jacket: leather
|
||||||
|
trousers: denim
|
||||||
|
pants:
|
||||||
|
size: large
|
||||||
|
age: 35
|
||||||
|
eyes : brown
|
||||||
|
beard: true
|
||||||
|
emails:
|
||||||
|
steve@hacker.com:
|
||||||
|
created: 01/02/03
|
||||||
|
active: true
|
||||||
|
`)
|
||||||
|
|
||||||
|
func TestSetKeyDelimiter(t *testing.T) {
|
||||||
|
v := New()
|
||||||
|
v.SetKeyDelimiter("::")
|
||||||
|
v.SetConfigType("yaml")
|
||||||
|
r := strings.NewReader(string(yamlExampleWithDot))
|
||||||
|
|
||||||
|
err := v.unmarshalReader(r, v.config)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
values := map[string]interface{}{
|
||||||
|
"image": map[string]interface{}{
|
||||||
|
"repository": "someImage",
|
||||||
|
"tag": "1.0.0",
|
||||||
|
},
|
||||||
|
"ingress": map[string]interface{}{
|
||||||
|
"annotations": map[string]interface{}{
|
||||||
|
"traefik.frontend.rule.type": "PathPrefix",
|
||||||
|
"traefik.ingress.kubernetes.io/ssl-redirect": "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
v.SetDefault("charts::values", values)
|
||||||
|
|
||||||
|
assert.Equal(t, "leather", v.GetString("clothing::jacket"))
|
||||||
|
assert.Equal(t, "01/02/03", v.GetString("emails::steve@hacker.com::created"))
|
||||||
|
|
||||||
|
type config struct {
|
||||||
|
Charts struct {
|
||||||
|
Values map[string]interface{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := config{
|
||||||
|
Charts: struct {
|
||||||
|
Values map[string]interface{}
|
||||||
|
}{
|
||||||
|
Values: values,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var actual config
|
||||||
|
|
||||||
|
assert.NoError(t, v.Unmarshal(&actual))
|
||||||
|
|
||||||
|
assert.Equal(t, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkGetBool(b *testing.B) {
|
func BenchmarkGetBool(b *testing.B) {
|
||||||
key := "BenchmarkGetBool"
|
key := "BenchmarkGetBool"
|
||||||
v = New()
|
v = New()
|
||||||
|
|
Loading…
Reference in a new issue