diff --git a/README.md b/README.md index 62bc80a..66d1ce4 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,7 @@ func TestEnvBind(t *testing.T) { Convey("env bind", t, func(c C) { cc := &Config{} x := xconf.NewWithoutFlagEnv() - x.UpdateWithFieldPathValues("http_address", "${XCONF_HOST}:${XCONF_PORT}") + So(x.UpdateWithFieldPathValues("http_address", "${XCONF_HOST}:${XCONF_PORT}"),ShouldBeNil) err := x.Parse(cc) So(err, ShouldBeNil) So(cc.HttpAddress, ShouldEqual, "") @@ -324,7 +324,7 @@ var atomicConfig unsafe.Pointer func AtomicConfigSet(update interface{}) { atomic.StorePointer(&atomicConfig, (unsafe.Pointer)(update.(*Config))) } -func AtomicConfig() *Config { +func AtomicConfig() ConfigVisitor { current := (*Config)(atomic.LoadPointer(&atomicConfig)) if current == nil { atomic.CompareAndSwapPointer(&atomicConfig, nil, (unsafe.Pointer)(newDefaultConfig())) diff --git a/merge.go b/merge.go index bf869de..de2fe0f 100644 --- a/merge.go +++ b/merge.go @@ -106,22 +106,23 @@ func mergeMap( } logger(fmt.Sprintf("%s%s is leaf key, overide.\n", indentNow, fieldPath)) } else { + var mergeErr error switch dstValType := dstVal.(type) { case map[interface{}]interface{}: logger(fmt.Sprintf("%s%s dstVal is map[interface{}]interface{}, merge deep.\n", indentNow, fieldPath)) tsv := srcVal.(map[interface{}]interface{}) ssv := castToMapStringInterface(tsv) stv := castToMapStringInterface(dstValType) - mergeMap(fieldPath, depth, logger, ssv, stv, isLeafFieldPath, dstValType, changes) + mergeErr = mergeMap(fieldPath, depth, logger, ssv, stv, isLeafFieldPath, dstValType, changes) case map[string]interface{}: switch srcValType := srcVal.(type) { case map[interface{}]interface{}: logger(fmt.Sprintf("%s%s dstVal: map[string]interface{} srcVal:map[interface{}]interface{}, deep merge\n", indentNow, fieldPath)) ssv := castToMapStringInterface(srcValType) - mergeMap(fieldPath, depth, logger, ssv, dstValType, isLeafFieldPath, nil, changes) + mergeErr = mergeMap(fieldPath, depth, logger, ssv, dstValType, isLeafFieldPath, nil, changes) case map[string]interface{}: logger(fmt.Sprintf("%s%s dstVal: map[string]interface{} srcVal:map[string]interface{}, deep merge\n", indentNow, fieldPath)) - mergeMap(fieldPath, depth, logger, srcValType, dstValType, isLeafFieldPath, nil, changes) + mergeErr = mergeMap(fieldPath, depth, logger, srcValType, dstValType, isLeafFieldPath, nil, changes) default: dst[dstKey] = srcVal if changes != nil { @@ -142,6 +143,9 @@ func mergeMap( } logger(fmt.Sprintf("%s%s dstVal type:%v,overide\n", indentNow, fieldPath, reflect.TypeOf(dstVal))) } + if mergeErr != nil { + return fmt.Errorf("got err:%w while merge:%s", mergeErr, fieldPath) + } } } return nil diff --git a/tests/all_test.go b/tests/all_test.go index 3f492c9..031f303 100644 --- a/tests/all_test.go +++ b/tests/all_test.go @@ -25,9 +25,8 @@ func TestParseWithDefaultValue(t *testing.T) { xconf.WithFlagSet(flag.NewFlagSet("TestParseWithDefaultValue", flag.ContinueOnError)), xconf.WithFlagArgs(), ) - - x.Parse(cc) Convey("just parse with default value", t, func(c C) { + So(x.Parse(cc), ShouldBeNil) So(defaultVal, ShouldResemble, cc) }) } @@ -75,7 +74,7 @@ func TestOverideDefaultValue(t *testing.T) { So(cc.Map1, ShouldResemble, map[string]int{"test1": 100, "test2": 200}) So(cc.MapNotLeaf, ShouldResemble, map[string]int{"test1": 100, "test2": 200}) So(cc.Int64Slice, ShouldResemble, []int64{101, 202, 303}) - x.Parse(cc) + So(x.Parse(cc), ShouldBeNil) So(cc.HttpAddress, ShouldEqual, ":3002") // map1作为叶子节点存在 @@ -110,7 +109,7 @@ func TestOverideDefaultValue(t *testing.T) { cc.SubTest.Map2 = map[string]int{"test1": 11111} cc.MapNotLeaf = make(map[string]int) cc.MapNotLeaf["k1"] = 1111 - x.Parse(cc) + So(x.Parse(cc), ShouldBeNil) x.DumpInfo() So(cc.HttpAddress, ShouldEqual, "192.168.0.1") So(cc.Int64Slice, ShouldResemble, []int64{100, 101}) @@ -143,13 +142,11 @@ func TestWatchUpdate(t *testing.T) { updated := make(chan *Config, 1) go func() { for { - select { - case v := <-x.NotifyUpdate(): - updated <- v.(*Config) - } + v := <-x.NotifyUpdate() + updated <- v.(*Config) } }() - x.Parse(cc) + So(x.Parse(cc), ShouldBeNil) cc.HttpAddress = "0.0.0.0" bytesBuffer := bytes.NewBuffer([]byte{}) xconf.MustSaveVarToWriter(cc, xconf.ConfigTypeYAML, bytesBuffer) @@ -174,8 +171,7 @@ func TestWatchUpdate(t *testing.T) { fmt.Printf("sub_test.http_address changed from %v to %v ", from, to) }) to := "123.456.789.000" - err := x.UpdateWithFieldPathValues(watchFieldPath, to) - So(err, ShouldBeNil) + So(x.UpdateWithFieldPathValues(watchFieldPath, to), ShouldBeNil) var got *Config select { case got = <-updated: @@ -188,7 +184,6 @@ func TestWatchUpdate(t *testing.T) { So(got.SubTest.HTTPAddress, ShouldEqual, to) ccHash := x.Hash() - So(err, ShouldBeNil) //保存到字节流 x2 := xconf.NewWithoutFlagEnv(xconf.WithReaders(bytes.NewReader(x.MustAsBytes(xconf.ConfigTypeYAML)))) @@ -231,7 +226,7 @@ func TestMapMerge(t *testing.T) { So(cc.Map1, ShouldResemble, map[string]int{"test1": 100, "test2": 200}) So(cc.MapNotLeaf, ShouldResemble, map[string]int{"test1": 100, "test2": 200}) So(cc.Int64Slice, ShouldResemble, []int64{101, 202, 303}) - x.Parse(cc) + So(x.Parse(cc), ShouldBeNil) So(cc.HttpAddress, ShouldEqual, ":3002") So(cc.Map1, ShouldResemble, map[string]int{"test1": 1000000, "test2": 200}) @@ -311,8 +306,7 @@ func TestFlagProvider(t *testing.T) { xconf.WithFlagArgs("--sub_test.servers="+jsonServer), ) vars.SetProviderByFieldPath("sub_test.servers", newServerProvider) - err := x.Parse(cc) - So(err, ShouldBeNil) + So(x.Parse(cc), ShouldBeNil) So(cc.SubTest.Servers["s1"].Timeouts, ShouldResemble, map[string]time.Duration{"read": time.Duration(5) * time.Second}) }) } @@ -325,8 +319,7 @@ func TestFlagProviderForEnv(t *testing.T) { xconf.WithEnviron("sub_test_servers="+jsonServer), ) vars.SetProviderByFieldPath("sub_test.servers", newServerProvider) - err := x.Parse(cc) - So(err, ShouldBeNil) + So(x.Parse(cc), ShouldBeNil) So(cc.SubTest.Servers["s1"].Timeouts, ShouldResemble, map[string]time.Duration{"read": time.Duration(5) * time.Second}) }) } @@ -340,8 +333,7 @@ func TestFlagProviderByType(t *testing.T) { xconf.WithEnviron("sub_test_servers="+jsonServer), ) vars.SetProviderByFieldType("map[string]Server", newServerProvider) - err := x.Parse(cc) - So(err, ShouldBeNil) + So(x.Parse(cc), ShouldBeNil) So(cc.SubTest.Servers["s1"].Timeouts, ShouldResemble, map[string]time.Duration{"read": time.Duration(5) * time.Second}) }) } @@ -373,9 +365,8 @@ func TestEnvBind(t *testing.T) { Convey("env bind", t, func(c C) { cc := &Config{} x := xconf.NewWithoutFlagEnv() - x.UpdateWithFieldPathValues("http_address", "${XCONF_HOST}:${XCONF_PORT}") - err := x.Parse(cc) - So(err, ShouldBeNil) + So(x.UpdateWithFieldPathValues("http_address", "${XCONF_HOST}:${XCONF_PORT}"), ShouldBeNil) + So(x.Parse(cc), ShouldBeNil) So(cc.HttpAddress, ShouldEqual, "") host := "127.0.0.1" port := "9001" @@ -400,7 +391,7 @@ func TestRemoteReaderWithURL(t *testing.T) { Convey("env bind", t, func(c C) { cc := &Config{} x := xconf.NewWithoutFlagEnv(xconf.WithReaders(xconf.NewRemoteReader("127.0.0.1:0001", time.Duration(1)*time.Second))) - So(func() { x.Parse(cc) }, ShouldPanic) + So(func() { _ = x.Parse(cc) }, ShouldPanic) }) } diff --git a/tests/main/main.go b/tests/main/main.go index 3737ef0..b80eafa 100644 --- a/tests/main/main.go +++ b/tests/main/main.go @@ -2,7 +2,6 @@ package main import ( "flag" - "fmt" "time" "github.com/sandwich-go/xconf" @@ -19,9 +18,12 @@ func main() { cc.SubTest.Servers["s1"] = tests.Server{ Timeouts: map[string]time.Duration{"read": time.Second * time.Duration(5)}, } - xconf.Parse(cc, xconf.WithDebug(true)) + if err := xconf.Parse(cc, xconf.WithDebug(true)); err != nil { + panic(err) + } x := xconf.New(xconf.WithDebug(true), xconf.WithFiles("c2.toml"), xconf.WithFlagSet(flag.NewFlagSet("test", flag.ContinueOnError))) - err := x.Parse(cc) - fmt.Println("result :", cc, err) + if err := x.Parse(cc); err != nil { + panic(err) + } x.DumpInfo() } diff --git a/xconf_reader.go b/xconf_reader.go index a8860fd..9b3f205 100644 --- a/xconf_reader.go +++ b/xconf_reader.go @@ -68,9 +68,6 @@ func (r *remoteReader) do() error { return fmt.Errorf("RemoteReader got invalid status code:%d", resp.StatusCode) } // read response content - buf := new(bytes.Buffer) - buf.ReadFrom(resp.Body) - bb, err := readAll(resp.Body) if err == nil { return fmt.Errorf("RemoteReader got err:%w while read body", err) diff --git a/xconf_remote.go b/xconf_remote.go index 6c62453..59fd1b1 100644 --- a/xconf_remote.go +++ b/xconf_remote.go @@ -83,5 +83,5 @@ func (x *XConf) onContentChanged(name string, confPath string, content []byte) { panicErrWithWrap(err, "unmarshal_error(%v) ", err) panicErr(x.mergeToDest(confPath, data)) - x.notifyChanged() + panicErr(x.notifyChanged()) }