command/flag: implement repeatable flag
All checks were successful
Test / Create distribution (push) Successful in 25s
Test / Run NixOS test (push) Successful in 3m29s

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-02-23 02:25:31 +09:00
parent 35037705a9
commit 89970f5197
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
2 changed files with 36 additions and 3 deletions

View File

@ -44,6 +44,26 @@ func (v BoolFlag) Define(b *strings.Builder, set *flag.FlagSet, p any, name, usa
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) {

View File

@ -83,6 +83,12 @@ func TestParse(t *testing.T) {
[]string{"--int", "2147483647", "int"},
"2147483647", "", nil,
},
{
"d=0 repeat flag",
buildTestCommand,
[]string{"--repeat", "0", "--repeat", "1", "--repeat", "2", "--repeat", "3", "--repeat", "4", "repeat"},
"[0 1 2 3 4]", "", nil,
},
{
"d=0 bool flag",
buildTestCommand,
@ -144,13 +150,14 @@ func TestParse(t *testing.T) {
buildTestCommand,
[]string{},
`
Usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>] COMMAND [OPTIONS]
Usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>] [--repeat <value>] COMMAND [OPTIONS]
Commands:
error return an error
print wraps Fprint
string print string passed by flag
int print int passed by flag
repeat print repeated values passed by flag
empty empty subcommand
join wraps strings.Join
succeed this command succeeds
@ -163,13 +170,14 @@ Commands:
buildTestCommand,
[]string{"-h"},
`
Usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>] COMMAND [OPTIONS]
Usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>] [--repeat <value>] COMMAND [OPTIONS]
Commands:
error return an error
print wraps Fprint
string print string passed by flag
int print int passed by flag
repeat print repeated values passed by flag
empty empty subcommand
join wraps strings.Join
succeed this command succeeds
@ -180,6 +188,8 @@ Flags:
fail early
-int int
store value for the "int" command (default -1)
-repeat value
store value for the "repeat" command
-string string
store value for the "string" command (default "default")
-v verbose output
@ -269,6 +279,7 @@ func buildTestCommand(wout, wlog io.Writer) (c command.Command) {
flagString string
flagInt int
flagRepeat command.RepeatableFlag
)
logf := newLogFunc(wlog)
@ -297,7 +308,9 @@ func buildTestCommand(wout, wlog io.Writer) (c command.Command) {
Flag(&flagString, "string", command.StringFlag("default"), "store value for the \"string\" command").
Command("string", "print string passed by flag", func(args []string) error { _, err := fmt.Fprint(wout, flagString); return err }).
Flag(&flagInt, "int", command.IntFlag(-1), "store value for the \"int\" command").
Command("int", "print int passed by flag", func(args []string) error { _, err := fmt.Fprint(wout, flagInt); return err })
Command("int", "print int passed by flag", func(args []string) error { _, err := fmt.Fprint(wout, flagInt); return err }).
Flag(nil, "repeat", &flagRepeat, "store value for the \"repeat\" command").
Command("repeat", "print repeated values passed by flag", func(args []string) error { _, err := fmt.Fprint(wout, flagRepeat); return err })
c.New("empty", "empty subcommand")
c.New("hidden", command.UsageInternal)