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"
|
||||
"time"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/hashicorp/hcl"
|
||||
"github.com/hashicorp/hcl/hcl/printer"
|
||||
"github.com/magiconair/properties"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
toml "github.com/pelletier/go-toml"
|
||||
"github.com/pelletier/go-toml"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cast"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
|
@ -245,6 +245,15 @@ func Reset() {
|
|||
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 {
|
||||
provider string
|
||||
endpoint string
|
||||
|
@ -1720,7 +1729,7 @@ func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}
|
|||
func (v *Viper) watchKeyValueConfigOnChannel() error {
|
||||
for _, rp := range v.remoteProviders {
|
||||
respc, _ := RemoteConfig.WatchChannel(rp)
|
||||
//Todo: Add quit channel
|
||||
// Todo: Add quit channel
|
||||
go func(rc <-chan *RemoteResponse) {
|
||||
for {
|
||||
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.
|
||||
// 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 (v *Viper) AllKeys() []string {
|
||||
m := map[string]bool{}
|
||||
|
@ -1779,7 +1788,7 @@ func (v *Viper) AllKeys() []string {
|
|||
|
||||
// flattenAndMergeMap recursively flattens the given map into a map[string]bool
|
||||
// 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,
|
||||
// it is skipped.
|
||||
// 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)
|
||||
}
|
||||
|
||||
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) {
|
||||
key := "BenchmarkGetBool"
|
||||
v = New()
|
||||
|
|
Loading…
Reference in a new issue