Files
hakurei/command/flag.go
T
cat f1dd3a085b
Test / Create distribution (push) Successful in 53s
Test / Sandbox (push) Successful in 2m51s
Test / Hakurei (push) Successful in 4m29s
Test / Sandbox (race detector) (push) Successful in 5m53s
Test / Hakurei (race detector) (push) Successful in 7m2s
Test / ShareFS (push) Successful in 7m19s
Test / Flake checks (push) Successful in 1m8s
command: hard wrap help message flags
This greatly improves readability when lots of flags are registered.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-08-07 20:32:24 +09:00

84 lines
2.1 KiB
Go

package command
import (
"errors"
"flag"
"strings"
)
// FlagError wraps errors returned by [flag].
type FlagError struct{ error }
func (e FlagError) Success() bool { return errors.Is(e.error, flag.ErrHelp) }
func (e FlagError) Is(target error) bool {
return (e.error == nil && target == nil) ||
((e.error != nil && target != nil) && e.error.Error() == target.Error())
}
func (n *node) Flag(p any, name string, value FlagDefiner, usage string) Node {
var buf strings.Builder
value.Define(&buf, n.set, p, name, usage)
s := buf.String()
if len(s) > 0 && s[0] == ' ' {
s = s[1:]
}
n.suffix = append(n.suffix, s)
return n
}
// StringFlag is the default value of a string flag.
type StringFlag string
func (v StringFlag) Define(b *strings.Builder, set *flag.FlagSet, p any, name, usage string) {
set.StringVar(p.(*string), name, string(v), usage)
b.WriteString(" [" + prettyFlag(name) + " <value>]")
}
// IntFlag is the default value of an int flag.
type IntFlag int
func (v IntFlag) Define(b *strings.Builder, set *flag.FlagSet, p any, name, usage string) {
set.IntVar(p.(*int), name, int(v), usage)
b.WriteString(" [" + prettyFlag(name) + " <int>]")
}
// BoolFlag is the default value of a bool flag.
type BoolFlag bool
func (v BoolFlag) Define(b *strings.Builder, set *flag.FlagSet, p any, name, usage string) {
set.BoolVar(p.(*bool), name, bool(v), usage)
b.WriteString(" [" + prettyFlag(name) + "]")
}
// RepeatableFlag implements an ordered, repeatable string flag.
type RepeatableFlag []string
func (r *RepeatableFlag) String() string {
if r == nil {
return "<nil>"
}
return strings.Join(*r, " ")
}
func (r *RepeatableFlag) Set(v string) error {
*r = append(*r, v)
return nil
}
func (r *RepeatableFlag) Define(b *strings.Builder, set *flag.FlagSet, _ any, name, usage string) {
set.Var(r, name, usage)
b.WriteString(" [" + prettyFlag(name) + " <value>]")
}
// this has no effect on parse outcome
func prettyFlag(name string) string {
switch len(name) {
case 0:
panic("zero length flag name")
case 1:
return "-" + name
default:
return "--" + name
}
}