Skip to content

Commit

Permalink
refactor: support string value alias
Browse files Browse the repository at this point in the history
  • Loading branch information
hui.wang committed Jan 20, 2022
1 parent 6362353 commit d4b089d
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 25 deletions.
88 changes: 67 additions & 21 deletions gen_options_optiongen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions mapstructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func (x *XConf) defaultDecoderConfig(output interface{}) *mapstructure.DecoderCo
WeaklyTypedInput: true,
ZeroFields: true,
DecodeHook: mapstructure.ComposeDecodeHookFunc(
StringAlias(x.cc.StringAlias, x.cc.StringAliasFunc),
parseEnvVarStringHookFunc(x.cc.EnvBindShouldErrorWhenFailed),
mapstructure.StringToTimeDurationHookFunc(),
mapstructure.StringToSliceHookFunc(","),
Expand All @@ -26,6 +27,24 @@ func (x *XConf) defaultDecoderConfig(output interface{}) *mapstructure.DecoderCo
return c
}

func StringAlias(alias map[string]string, aliasFunc map[string]func(string) string) mapstructure.DecodeHookFunc {
return func(
f reflect.Type,
t reflect.Type,
data interface{}) (interface{}, error) {
if f.Kind() != reflect.String {
return data, nil
}
if v, ok := alias[data.(string)]; ok {
return v, nil
}
if v, ok := aliasFunc[data.(string)]; ok {
return v(data.(string)), nil
}
return data, nil
}
}

func parseEnvVarStringHookFunc(envBindShouldErrorWhenFailed bool) mapstructure.DecodeHookFunc {
return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
if f.Kind() != reflect.String {
Expand Down
23 changes: 22 additions & 1 deletion option.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import (
"flag"
"io"
"log"
"math"
"os"
"runtime"
"strconv"

"github.com/sandwich-go/xconf/xutil"
)
Expand Down Expand Up @@ -78,9 +81,27 @@ func OptionsOptionDeclareWithDefault() interface{} {
"TagNameForDefaultValue": string(DefaultValueTagName),
// annotation@ReplaceFlagSetUsage(comment="是否替换FlagSet的Usage,使用xconf内置版本")
"ReplaceFlagSetUsage": true,
// annotation@StringAlias(comment="值别名")
"StringAlias": (map[string]string)(map[string]string{
"math.MaxInt": strconv.Itoa(math.MaxInt),
"math.MaxInt8": strconv.Itoa(math.MaxInt8),
"math.MaxInt16": strconv.Itoa(math.MaxInt16),
"math.MaxInt32": strconv.Itoa(math.MaxInt32),
"math.MaxInt64": strconv.FormatInt(math.MaxInt32, 10),
"math.MaxUint": strconv.FormatUint(math.MaxUint, 10),
"math.MaxUint8": strconv.FormatUint(math.MaxUint8, 10),
"math.MaxUint16": strconv.FormatUint(math.MaxUint16, 10),
"math.MaxUint32": strconv.FormatUint(math.MaxUint32, 10),
"math.MaxUint64": strconv.FormatUint(math.MaxUint64, 10),
}),
// annotation@StringAliasFunc(comment="值别名计算逻辑")
"StringAliasFunc": (map[string]func(s string) string)(map[string]func(s string) string{
"runtime.NumCPU": func(s string) string {
return strconv.Itoa(runtime.NumCPU())
},
}),
}
}

func init() {
InstallOptionsWatchDog(func(cc *Options) {
if cc.MapMerge {
Expand Down
2 changes: 2 additions & 0 deletions tests/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ func ConfigOptionDeclareWithDefault() interface{} {
"test1": 100,
"test2": 200,
},
"ProcessCount": int8(1),
"MaxUint64": uint64(0),
"Int8": int8(1),
"TimeDurations": []time.Duration([]time.Duration{time.Second, time.Second}), // @MethodComment(延迟队列)
"DefaultEmptyMap": map[string]int{},
Expand Down
26 changes: 26 additions & 0 deletions tests/gen_config_optiongen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions tests/main/c1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,5 @@ redis_as_pointer:
redis_address: 127.0.0.1:6639
redis:
redis_address: 127.0.0.1:6638
process_count: runtime.NumCPU
max_uint64: math.MaxUint64
2 changes: 2 additions & 0 deletions tests/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ func main() {
}
fmt.Println("cc.RedisAsPointer.RedisAddress ", cc.RedisAsPointer.RedisAddress)
fmt.Println("cc.Redis.RedisAddress ", cc.Redis.RedisAddress)
fmt.Println("cc.ProcessCount ", cc.ProcessCount)
fmt.Println("cc.MaxUint64 ", cc.MaxUint64)
xx.Usage()
}
6 changes: 6 additions & 0 deletions xcmd/commander.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ func (c *Command) Execute(ctx context.Context, args ...string) error {
// 默认 usage 无参
ff.Usage = func() {
c.Explain(c.Output)
fmt.Fprintf(c.Output, "Flags:\n")
xflag.PrintDefaults(ff)
}

Expand All @@ -137,7 +138,12 @@ func (c *Command) Execute(ctx context.Context, args ...string) error {
return err
}

const HasParsed = "xcmd_has_parsed"

func parser(ctx context.Context, c *Command, ff *flag.FlagSet, args []string, next Executer) error {
if v := ctx.Value(HasParsed); v != nil {
return next(ctx, c, ff, args)
}
if c.cc.GetBind() == nil {
err := ff.Parse(args)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion xcmd/explain.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func explainGroup(w io.Writer, c *Command) {
fmt.Fprintf(w, "Usage: %s <subcommand> <flags> <args>\n\n", strings.Join(c.usageNamePath, " "))
}
sort.Sort(byGroupName(c.commands))
fmt.Fprintf(w, "Available Commands:\n\n")
fmt.Fprintf(w, "Available Commands:\n")
sort.Sort(byGroupName(c.commands))
var level = []bool{}
lines := printCommand(c, level)
Expand Down
2 changes: 2 additions & 0 deletions xcmd/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ func main() {
manual.UsePre(binding)
xcmd.AddCommand(manual)

xcmd.Add("empty")

// panicPrintErr("comamnd check with err: %v", xcmd.Check())
panicPrintErr("comamnd Execute with err: %v", xcmd.Execute(context.Background(), os.Args[1:]...))
}
Expand Down
1 change: 1 addition & 0 deletions xcmd/parser_xconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func ParserXConf(ctx context.Context, c *Command, ff *flag.FlagSet, args []strin
// 更新FlagSet的Usage,使用xconf内置版本
cc.FlagSet.Usage = func() {
c.Explain(c.Output)
fmt.Fprintf(c.Output, "Flags:\n")
x.UsageToWriter(c.Output, args...)
}
err := x.Parse(c.cc.GetBind())
Expand Down
3 changes: 1 addition & 2 deletions xflag/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,13 @@ func GetFlagInfo(f *flag.FlagSet) (ret FlagList) {
func PrintDefaults(f *flag.FlagSet, suffixLines ...string) {
lines := make([]string, 0)
magic := "\x00"
lines = append(lines, "FLAG"+"\x00"+"ENV"+"\x00"+"TYPE"+"\x00"+"USAGE")
lines = append(lines, "FLAG"+"\x00"+"TYPE"+"\x00"+"USAGE")

allFlag := GetFlagInfo(f)
for _, v := range allFlag.List {
line := ""
line = fmt.Sprintf("--%s", v.Name)
line += magic
line += magic
line += v.TypeName
line += magic
line += fmt.Sprintf("|%s| %s", "-", v.Usage)
Expand Down

0 comments on commit d4b089d

Please sign in to comment.