CliParser.Init() accepts optional flags. Currently una flag is available: ResetOnEqualSign

This commit is contained in:
Celestino Amoroso 2026-03-06 11:45:58 +01:00
parent 9e28ee6545
commit 00b84278d8
3 changed files with 26 additions and 6 deletions

14
cli.go
View File

@ -14,6 +14,7 @@ type cliParser interface {
getCliArgs(startIndex, endIndex int) (args []string) getCliArgs(startIndex, endIndex int) (args []string)
PrintVersion(specs []string) PrintVersion(specs []string)
PrintUsage() PrintUsage()
FlagIsSet(flag int16) bool
} }
type cliOptionParser interface { type cliOptionParser interface {
@ -41,20 +42,31 @@ type OptReference interface {
SetHidden(hidden bool) SetHidden(hidden bool)
} }
const (
ResetOnEqualSign = int16(1 << iota) // for some option types, like arrays, the equal signs reset to empty the accumulator of values
)
type CliParser struct { type CliParser struct {
description string description string
version string version string
options []cliOptionParser options []cliOptionParser
argSpecs []argSpec argSpecs []argSpec
cliArgs []string cliArgs []string
flags int16
} }
func (cli *CliParser) Init(argv []string, version string, description string) { func (cli *CliParser) Init(argv []string, version string, description string, flags ...int16) {
cli.version = version cli.version = version
cli.description = description cli.description = description
cli.cliArgs = argv cli.cliArgs = argv
for _, flag := range flags {
cli.flags |= flag
}
} }
func (cli *CliParser) FlagIsSet(flag int16) bool {
return (cli.flags & flag) == flag
}
func (cli *CliParser) GetOption(name string) (ref OptReference) { func (cli *CliParser) GetOption(name string) (ref OptReference) {
var opt cliOptionParser var opt cliOptionParser
if strings.HasPrefix(name, "-") { if strings.HasPrefix(name, "-") {

View File

@ -75,7 +75,7 @@ func (opt *cliOptionIntArray) parse(parser cliParser, argIndex int, valuePtr *st
err = errInvalidOptionValue(opt.name, boxedValue, "num-array") err = errInvalidOptionValue(opt.name, boxedValue, "num-array")
} }
} else { } else {
if !opt.alreadySeen { if !opt.alreadySeen || (valuePtr != nil && parser.FlagIsSet(ResetOnEqualSign)) {
*opt.targetVar = []int{} *opt.targetVar = []int{}
opt.alreadySeen = true opt.alreadySeen = true
} }

View File

@ -49,12 +49,12 @@ func addBoxOption(cli *CliParser, boxPtr *[]int) {
}) })
} }
func testIntArrayOptOk(t *testing.T, n int, args []string) { func testIntArrayOptOk(t *testing.T, n int, args []string, flags ...int16) {
var box []int var box []int
var cli CliParser var cli CliParser
t.Logf("Arg set n. %d", n) t.Logf("Arg set n. %d", n)
addBoxOption(&cli, &box) addBoxOption(&cli, &box)
cli.Init(args, "1.0.0", "TestIntArrayOpt description") cli.Init(args, "1.0.0", "TestIntArrayOpt description", flags...)
if err := cli.Parse(); err != nil { if err := cli.Parse(); err != nil {
t.Error(err) t.Error(err)
} else if len(box) != 4 { } else if len(box) != 4 {
@ -62,12 +62,12 @@ func testIntArrayOptOk(t *testing.T, n int, args []string) {
} }
} }
func testIntArrayOptKo(t *testing.T, n int, args []string, msg string) { func testIntArrayOptKo(t *testing.T, n int, args []string, msg string, flags ...int16) {
var box []int var box []int
var cli CliParser var cli CliParser
t.Logf("Arg set n. %d", n) t.Logf("Arg set n. %d", n)
addBoxOption(&cli, &box) addBoxOption(&cli, &box)
cli.Init(args, "1.0.0", "TestIntArrayOpt description") cli.Init(args, "1.0.0", "TestIntArrayOpt description", flags...)
if err := cli.Parse(); err == nil { if err := cli.Parse(); err == nil {
t.Errorf("Expected error, got nil") t.Errorf("Expected error, got nil")
} else if err.Error() != msg { } else if err.Error() != msg {
@ -132,4 +132,12 @@ func TestIntArrayOpt(t *testing.T) {
"--box", "450,12", "--box", "450,12",
} }
testIntArrayOptKo(t, n, args, "--box option requires exactly 4 items, 5 provided") testIntArrayOptKo(t, n, args, "--box option requires exactly 4 items, 5 provided")
n++
args = []string{
"TestIntArrayOpt",
"--box", "100,200,150",
"--box=100,200,150,450",
}
testIntArrayOptOk(t, n, args, ResetOnEqualSign)
} }