From 53c60f11ebe707455b861e3c62b2ac88f87e1115 Mon Sep 17 00:00:00 2001 From: "hui.wang" Date: Wed, 23 Mar 2022 09:23:14 +0800 Subject: [PATCH] feat: support dump config to yaml through help command --- tests/main/main.go | 1 - xconf.go | 2 ++ xconf_usage.go | 42 ++++++++++++++++++++++++++++++++++++------ xutil/util.go | 15 +++++++++++++++ 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/tests/main/main.go b/tests/main/main.go index 23d9fd6..f70a45d 100644 --- a/tests/main/main.go +++ b/tests/main/main.go @@ -15,7 +15,6 @@ func main() { xconf.WithFiles("c1.yaml"), xconf.WithDebug(false), xconf.WithEnvironPrefix("test_prefix_"), - xconf.WithOptionUsagePoweredBy(""), ) if err := xx.Parse(cc); err != nil { panic(err) diff --git a/xconf.go b/xconf.go index d1302f8..3f70174 100644 --- a/xconf.go +++ b/xconf.go @@ -34,6 +34,7 @@ type XConf struct { atomicSetFunc func(interface{}) optionUsage string parseForMerge bool + valPtrForUsageDump interface{} } // New 构造新的Xconf @@ -236,6 +237,7 @@ func (x *XConf) parse(valPtr interface{}) (err error) { } if x.cc.FlagSet != nil && x.cc.ReplaceFlagSetUsage { + x.valPtrForUsageDump = valPtr x.cc.FlagSet.Usage = x.Usage } diff --git a/xconf_usage.go b/xconf_usage.go index 60b8ae2..34d7aa9 100644 --- a/xconf_usage.go +++ b/xconf_usage.go @@ -1,6 +1,7 @@ package xconf import ( + "bytes" "errors" "fmt" "io" @@ -17,24 +18,53 @@ import ( func (x *XConf) Usage() { x.UsageToWriter(os.Stderr, x.cc.FlagArgs...) } func (x *XConf) UsageToWriter(w io.Writer, args ...string) { + err := x.usageToWriter(w, args...) + if err == nil { + return + } + x.cc.LogWarning(fmt.Sprintf("UsageToWriter got error:%s", err.Error())) +} + +func (x *XConf) usageToWriter(w io.Writer, args ...string) (err error) { parsedOptions := xflag.ParseArgsToMapStringString(args) val, got := parsedOptions["help"] if !got { val, got = parsedOptions["h"] } - var err error + val = xutil.StringTrim(val) if got && strings.EqualFold(xutil.StringTrim(val), "xconf") { // 指定xconf_usage的FlagArgs为空,避免再次触发help逻辑 xx := New(WithFlagSet(newFlagSetContinueOnError("xconf_usage")), WithFlagArgs(), WithErrorHandling(ContinueOnError)) cc := NewOptions() xutil.PanicErr(xx.Parse(cc)) - err = xx.usageLinesToWriter(w) - } else { - err = x.usageLinesToWriter(w) + return xx.usageLinesToWriter(w) } - if err != nil { - x.cc.LogWarning(fmt.Sprintf("UsageToWriter got error:%s", err.Error())) + if got && strings.EqualFold(xutil.StringTrim(val), "yaml") { + if x.valPtrForUsageDump == nil { + return errors.New("usage for yaml got empty config input") + } + return x.SaveVarToWriterAsYAML(x.valPtrForUsageDump, w) + } + if got && strings.HasSuffix(val, string(ConfigTypeYAML)) { // 输出到文件 + defer func() { + if err == nil { + fmt.Println("\n🍺 save config file as yaml to: ", val) + } else { + fmt.Println("\n🚫 got error while save config file as yaml, err:", err.Error()) + } + err = nil + }() + if x.valPtrForUsageDump == nil { + return errors.New("usage for yaml file got config input") + } + bytesBuffer := bytes.NewBuffer([]byte{}) + err := x.SaveVarToWriterAsYAML(x.valPtrForUsageDump, bytesBuffer) + if err != nil { + return err + } + return xutil.FilePutContents(val, bytesBuffer.Bytes()) } + return x.usageLinesToWriter(w) } // usageLinesToWriter 打印usage信息到io.Writer diff --git a/xutil/util.go b/xutil/util.go index bbe84d3..10f8ffc 100644 --- a/xutil/util.go +++ b/xutil/util.go @@ -5,6 +5,9 @@ import ( "errors" "fmt" "io" + "io/ioutil" + "os" + "path/filepath" "regexp" "strings" ) @@ -189,3 +192,15 @@ func KVListApplyFunc(f func(k, v string) bool, kv ...string) error { } return nil } + +func FilePutContents(filename string, content []byte) error { + err := os.MkdirAll(filepath.Dir(filename), os.ModePerm) + if err != nil { + return fmt.Errorf("got error:%s while mkdir:%s", err.Error(), filepath.Dir(filename)) + } + err = ioutil.WriteFile(filename, content, 0644) + if err != nil { + return fmt.Errorf("got error:%s while write to file:%s", err.Error(), filename) + } + return nil +}