Skip to content

Commit ba8067f

Browse files
committed
bump to v1.1.4. added MergeWith(mapFromYaml/JSON/TOML).
1 parent 72f9fa9 commit ba8067f

File tree

3 files changed

+90
-21
lines changed

3 files changed

+90
-21
lines changed

base_opt_test.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -202,16 +202,8 @@ func TestSetGetIntSlice2(t *testing.T) {
202202
}
203203
}
204204

205-
func TestTomlLoad(t *testing.T) {
206-
var (
207-
err error
208-
b []byte
209-
mm map[string]map[string]interface{}
210-
config tomlConfig
211-
meta toml.MetaData
212-
)
213-
214-
b = []byte(`
205+
var (
206+
tomlSample = []byte(`
215207
216208
runmode="devel"
217209
@@ -254,8 +246,18 @@ hosts = [
254246
]
255247
256248
`)
249+
)
250+
251+
func TestTomlLoad(t *testing.T) {
252+
var (
253+
err error
254+
b []byte
255+
mm map[string]map[string]interface{}
256+
config tomlConfig
257+
meta toml.MetaData
258+
)
257259

258-
if err = ioutil.WriteFile(".tmp.toml", b, 0644); err != nil {
260+
if err = ioutil.WriteFile(".tmp.toml", tomlSample, 0644); err != nil {
259261
t.Fatal(err)
260262
}
261263

opt_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package cmdr_test
77
import (
88
"fmt"
99
"github.com/hedzr/cmdr"
10+
"gopkg.in/yaml.v2"
1011
"testing"
1112
)
1213

@@ -245,3 +246,33 @@ func TestFluentAPI(t *testing.T) {
245246
})
246247

247248
}
249+
250+
func TestMergeWith(t *testing.T) {
251+
cmdr.Set("test.1", 8)
252+
cmdr.Set("test.deep.branch.1", "test")
253+
254+
var m = make(map[string]interface{})
255+
err := yaml.Unmarshal([]byte(`
256+
app:
257+
test:
258+
1: 9
259+
deep:
260+
branch:
261+
1: test-ok
262+
`), &m)
263+
if err != nil {
264+
t.Fatal(err)
265+
}
266+
267+
err = cmdr.MergeWith(m)
268+
if err != nil {
269+
t.Fatal(err)
270+
}
271+
272+
if cmdr.GetInt("app.test.1") != 9 {
273+
t.Fatalf("err, expect 9, but got %v", cmdr.GetInt("app.test.1"))
274+
}
275+
if cmdr.GetString("app.test.deep.branch.1") != "test-ok" {
276+
t.Fatalf("err, expect 'test-ok', but got '%v'", cmdr.GetString("app.test.deep.branch.1"))
277+
}
278+
}

options.go

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -571,13 +571,13 @@ func wrapWithRxxtPrefix(key string) string {
571571
}
572572

573573
// Set set the value of an `Option` key (with prefix auto-wrap). The key MUST not have an `app` prefix. eg:
574-
// ```golang
575-
// cmdr.Set("logger.level", "DEBUG")
576-
// cmdr.Set("ms.tags.port", 8500)
577-
// ...
578-
// cmdr.Set("debug", true)
579-
// cmdr.GetBool("app.debug") => true
580-
// ```
574+
//
575+
// cmdr.Set("logger.level", "DEBUG")
576+
// cmdr.Set("ms.tags.port", 8500)
577+
// ...
578+
// cmdr.Set("debug", true)
579+
// cmdr.GetBool("app.debug") => true
580+
//
581581
//
582582
func Set(key string, val interface{}) {
583583
rxxtOptions.Set(key, val)
@@ -616,29 +616,65 @@ func (s *Options) SetNx(key string, val interface{}) {
616616

617617
s.entries[key] = val
618618
a := strings.Split(key, ".")
619-
mergeMap(s.hierarchy, a[0], et(a, 1, val))
619+
s.mergeMap(s.hierarchy, a[0], "", et(a, 1, val))
620+
}
621+
622+
// MergeWith will merge a map recursive.
623+
// You could merge a yaml/json/toml options into cmdr Hierarchy Options.
624+
func MergeWith(m map[string]interface{}) (err error) {
625+
err = rxxtOptions.MergeWith(m)
626+
return
627+
}
628+
629+
// MergeWith will merge a map recursive.
630+
func (s *Options) MergeWith(m map[string]interface{}) (err error) {
631+
for k, v := range m {
632+
s.mergeMap(s.hierarchy, k, "", v)
633+
}
634+
return
620635
}
621636

622-
func mergeMap(m map[string]interface{}, key string, val interface{}) map[string]interface{} {
637+
func (s *Options) mergeMap(m map[string]interface{}, key, path string, val interface{}) map[string]interface{} {
638+
if len(path) > 0 {
639+
path = fmt.Sprintf("%v.%v", path, key)
640+
} else {
641+
path = key
642+
}
643+
623644
if z, ok := m[key]; ok {
624645
if zm, ok := z.(map[string]interface{}); ok {
625646
if vm, ok := val.(map[string]interface{}); ok {
626647
for k, v := range vm {
627-
zm = mergeMap(zm, k, v)
648+
zm = s.mergeMap(zm, k, path, v)
649+
}
650+
m[key] = zm
651+
s.entries[path] = zm
652+
} else if vm, ok := val.(map[interface{}]interface{}); ok {
653+
for k, v := range vm {
654+
kk, ok := k.(string)
655+
if !ok {
656+
kk = fmt.Sprintf("%v", k)
657+
}
658+
zm = s.mergeMap(zm, kk, path, v)
628659
}
629660
m[key] = zm
661+
s.entries[path] = zm
630662
} else {
631663
m[key] = val
664+
s.entries[path] = val
632665
}
633666
} else {
634667
m[key] = val
668+
s.entries[path] = val
635669
}
636670
} else {
637671
m[key] = val
672+
s.entries[path] = val
638673
}
639674
return m
640675
}
641676

677+
// et will eat the left part string from `keys[ix:]`
642678
func et(keys []string, ix int, val interface{}) interface{} {
643679
if ix <= len(keys)-1 {
644680
p := make(map[string]interface{})

0 commit comments

Comments
 (0)