add case
This commit is contained in:
parent
ff4c06dd0a
commit
cf86d63d24
74
flag.go
74
flag.go
|
@ -4,7 +4,9 @@ import (
|
|||
"errors"
|
||||
"flag"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type FVSet struct {
|
||||
|
@ -19,6 +21,56 @@ func (f *FVSet) Parse(args []string) error {
|
|||
func isPtr(v interface{}) bool {
|
||||
return reflect.TypeOf(v).Kind() == reflect.Ptr
|
||||
}
|
||||
func (f *FVSet) Args() interface{} {
|
||||
return f.flags.Args()
|
||||
}
|
||||
|
||||
func (f *FVSet) Usage() {
|
||||
f.flags.Usage()
|
||||
}
|
||||
|
||||
type FVSets struct {
|
||||
flagSets []*FVSet
|
||||
subcommands []string
|
||||
}
|
||||
|
||||
func (f *FVSets) Add(v interface{}) error {
|
||||
fv, err := NewFVSet(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fv.flags.Usage = func() {
|
||||
f.Usage()
|
||||
}
|
||||
f.flagSets = append(f.flagSets, fv)
|
||||
return nil
|
||||
}
|
||||
func (f *FVSets) Parse(args []string) error {
|
||||
for _, v := range f.flagSets {
|
||||
err := v.Parse(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (f *FVSets) Usage() {
|
||||
//for _, v := range f.flagSets {
|
||||
//
|
||||
//}
|
||||
}
|
||||
|
||||
func ToKebabCase(input string) string {
|
||||
// 将字符串中的大写字母前插入连字符,并转换为小写
|
||||
re := regexp.MustCompile("([a-z])([A-Z])")
|
||||
kebab := re.ReplaceAllString(input, "${1}-${2}")
|
||||
kebab = strings.ToLower(kebab)
|
||||
|
||||
// 去除字符串开头和结尾的连字符
|
||||
kebab = strings.Trim(kebab, "-")
|
||||
|
||||
return kebab
|
||||
}
|
||||
|
||||
// NewFVSet 创建一个新的FVSet实例,用于处理命令行标志。
|
||||
// 参数v是一个指向结构体的指针,该结构体的字段将被用作命令行标志。
|
||||
|
@ -51,23 +103,35 @@ func NewFVSet(v interface{}) (*FVSet, error) {
|
|||
if flaName == "" {
|
||||
flaName = stField.Name
|
||||
}
|
||||
flaName = ToKebabCase(flaName)
|
||||
flShort := stField.Tag.Get("flag_short")
|
||||
defVal := stField.Tag.Get("flag_default")
|
||||
usageStr := stField.Tag.Get("flag_usage")
|
||||
if usageStr == "" {
|
||||
usageStr = "Set " + flaName + "(default " + defVal + ")"
|
||||
}
|
||||
|
||||
addr := field.Addr()
|
||||
if field.CanSet() {
|
||||
switch expression := field.Interface().(type) {
|
||||
switch field.Interface().(type) {
|
||||
case string:
|
||||
flags.StringVar(&expression, flaName, defVal, usageStr)
|
||||
flags.StringVar(addr.Interface().(*string), flaName, defVal, usageStr)
|
||||
if flShort != "" {
|
||||
flags.StringVar(addr.Interface().(*string), flShort, defVal, usageStr)
|
||||
}
|
||||
break
|
||||
case int:
|
||||
v, _ := strconv.Atoi(defVal)
|
||||
flags.IntVar(&expression, flaName, v, usageStr)
|
||||
flags.IntVar(addr.Interface().(*int), flaName, v, usageStr)
|
||||
if flShort != "" {
|
||||
|
||||
flags.IntVar(addr.Interface().(*int), flShort, v, usageStr)
|
||||
}
|
||||
break
|
||||
case bool:
|
||||
flags.BoolVar(&expression, flaName, false, usageStr)
|
||||
flags.BoolVar(addr.Interface().(*bool), flaName, false, usageStr)
|
||||
if flShort != "" {
|
||||
flags.BoolVar(addr.Interface().(*bool), flShort, false, usageStr)
|
||||
}
|
||||
break
|
||||
|
||||
default:
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseSingle(t *testing.T) {
|
||||
type targs struct {
|
||||
Test string `flag_default:"test" flag_usage:"this is test"`
|
||||
TestBool bool `flag_short:"b"`
|
||||
TestInt int
|
||||
}
|
||||
sargs := &targs{}
|
||||
v, _ := NewFVSet(sargs)
|
||||
v.Usage()
|
||||
err := Parse([]string{"--test", "test", "--test-bool", "--test-int", "1"}, v)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if sargs.Test != "test" {
|
||||
t.Error("test failed")
|
||||
}
|
||||
if !sargs.TestBool {
|
||||
t.Error("test failed")
|
||||
}
|
||||
if sargs.TestInt != 1 {
|
||||
t.Error("test failed")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue