From f23a98fb5d533ddb310f0d356d75e0016fae0e61 Mon Sep 17 00:00:00 2001 From: bth Date: Sun, 18 Jan 2026 09:03:27 -0800 Subject: [PATCH] flags rewrite : just well defined structs and a clear switch block --- flags/flags.go | 42 ++++++++++++++++-------- sort/sort.go | 16 +--------- tag/tag.go | 87 +++++++++++++++++++++----------------------------- 3 files changed, 66 insertions(+), 79 deletions(-) diff --git a/flags/flags.go b/flags/flags.go index bd5e390..5e40ae8 100644 --- a/flags/flags.go +++ b/flags/flags.go @@ -5,20 +5,34 @@ import ( "strings" ) -type Flag string - -func (f Flag) Dash() string { - return fmt.Sprintf("--%s", f) +type Arg struct { + Val string + Help string } -// prepend --flag to args if a flag isn't there: -// allows trailing flags: -// um tag foo --invert -// becomes: -// um tag --query foo --invert -func PrependFlagToArgs(args []string, flag Flag) []string { - if len(args) >= 1 && !strings.HasPrefix(args[0], "-") { - args = append([]string{flag.Dash()}, args...) - } - return args +type Flag struct { + Long string + Short string + Val string + Help string +} + +// there's got to be a way to generalize the val field to string|bool +type FlagBool struct { + Long string + Short string + Val bool + Help string +} + +func HasDashPrefix(s string) bool { + return strings.HasPrefix(s, "-") +} + +func MissingValueArg(args []string, i int) bool { + return i+1 == len(args) || HasDashPrefix(args[i+1]) +} + +func HelpMissingVal(flag string) { + fmt.Printf("%s needs a value assignment\n", flag) } diff --git a/sort/sort.go b/sort/sort.go index 5d9164f..ac02820 100644 --- a/sort/sort.go +++ b/sort/sort.go @@ -1,23 +1,9 @@ package sort import ( - "flag" "fmt" - - "github.com/brtholomy/um/go/flags" -) - -const ( - key flags.Flag = "key" ) func Sort(args []string) { - sortFlags := flag.NewFlagSet("sort", flag.ExitOnError) - sortKey := sortFlags.String(string(key), "", "filename of ordered list to use as key") - - sortFlags.Parse(args) - fmt.Println("subcmd sort") - fmt.Printf("key: %#v\n", *sortKey) - fmt.Printf("args: %#v\n", sortFlags.Args()) - sortFlags.Usage() + fmt.Printf("args: %#v\n", args) } diff --git a/tag/tag.go b/tag/tag.go index 672abc7..3ef2534 100644 --- a/tag/tag.go +++ b/tag/tag.go @@ -2,62 +2,49 @@ package tag import ( "fmt" - "reflect" - "strings" - "unicode" + + "github.com/brtholomy/um/go/flags" ) -var opts struct { - Query string `name:"query" help:"tag query"` - Invert bool `name:"invert" help:"invert match"` +type options struct { + query flags.Arg + date flags.Flag + invert flags.FlagBool } -func flagToField(flag string) string { - s := strings.TrimPrefix(flag, "--") - r := []rune(s) - r[0] = unicode.ToUpper(r[0]) - return string(r) +func InitOpts() options { + return options{ + flags.Arg{"", "tag query"}, + flags.Flag{"--date", "-d", "", "date range"}, + flags.FlagBool{"--invert", "-i", false, "invert match"}, + } +} + +func ParseArgs(args []string) options { + opts := InitOpts() + if len(args) == 0 { + return opts + } + if flags.HasDashPrefix(args[0]) { + opts.query.Val = args[0] + } + for i, arg := range args { + switch arg { + case opts.invert.Long, opts.invert.Short: + opts.invert.Val = true + case opts.date.Long: + if flags.MissingValueArg(args, i) { + flags.HelpMissingVal(arg) + break + } + opts.date.Val = args[i+1] + } + } + return opts } func Tag(args []string) { - - // reflection! - t := reflect.TypeOf(opts) - field := reflect.StructField{} - found := false - for _, a := range args { - field, found = t.FieldByName(flagToField(a)) - if !found { - fmt.Printf("%s not found in opts\n", a) - return - } - } - tag := field.Tag - - fmt.Printf("field name: %#v\n", tag.Get("name")) - fmt.Printf("field help: %#v\n", tag.Get("help")) - - v := reflect.ValueOf(opts) - vfield := reflect.Value{} - for _, a := range args { - vfield = v.FieldByName(flagToField(a)) - if vfield.IsValid() && vfield.CanSet() && vfield.Kind() == reflect.Bool { - vfield.SetBool(true) - fmt.Printf("vfield: %#v\n", vfield) - } - } - fmt.Printf("vfield: %#v\n", vfield) + fmt.Printf("args: %#v\n", args) + opts := ParseArgs(args) fmt.Printf("opts: %#v\n", opts) - // for i := 0; i < t.NumField(); i++ { - // field := t.Field(i) - // if alias, ok := field.Tag.Lookup("name"); ok { - // if alias == "" { - // fmt.Println("(blank)") - // } else { - // fmt.Println(alias) - // } - // } else { - // fmt.Println("(not specified)") - // } - // } }