Glob as variant of Arg Flag type : accepts multiple files, as shell-expanded. use in um sort and um cat

NOTE: um sort expects .md files, while um cat expects .um : .um filelists are concatted together, while .md lists are just lists
This commit is contained in:
bth 2026-07-15 17:20:09 -07:00
commit 5aac37f8a8
5 changed files with 74 additions and 22 deletions

View file

@ -31,6 +31,11 @@ type Arg struct {
Help string
}
type Glob struct {
Val []string
Help string
}
type String struct {
Long string
Short string
@ -69,6 +74,33 @@ func (f *Arg) MaybeIncrement(i int) int {
return i
}
func (f *Glob) Set(arg string) {
f.Val = append(f.Val, arg)
}
func (f *Glob) Valid(args []string, i int) bool {
return true
}
func (f *Glob) Match(arg string, i, j int) bool {
// NOTE: this is the key difference from Arg: by not requiring that the arg and flag positions
// match, a shell-expanded glob of files of any length will populate the value.
return i >= j && !hasDashPrefix(arg)
}
func (f *Glob) IsSet() bool {
return f.Val != nil && len(f.Val) != 0
}
func (f *Glob) IsHelp() bool {
return false
}
func (f *Glob) MaybeIncrement(i int) int {
// NOTE: because this is only needed where a flag --prefix exists:
return i
}
func (f *String) Set(arg string) {
f.Val = arg
}
@ -145,16 +177,16 @@ func expandOpts(opts any) ([]Flag, error) {
for j := 0; j < v.NumField(); j++ {
field := v.Field(j)
if field.Kind() != reflect.Struct {
return nil, ParseError{fmt.Sprintf("field must be a struct: %#v", field.Kind())}
return nil, ParseError{fmt.Sprintf("field must be a struct: %v", field.Kind())}
}
if !field.CanAddr() {
return nil, ParseError{fmt.Sprintf("field must be addressable type: %#v", field.Type())}
return nil, ParseError{fmt.Sprintf("field must be addressable type: %v", field.Type())}
}
// NOTE: Addr() gets the underlying address:
if f, ok := field.Addr().Interface().(Flag); ok {
flags = append(flags, f)
} else {
return nil, ParseError{fmt.Sprintf("field must be a []Flag interface: %#v", field.Type())}
return nil, ParseError{fmt.Sprintf("field must be a []Flag interface: %v", field.Type())}
}
}
return flags, nil