final checks on opt values moved after option parsing is complete

This commit is contained in:
2026-03-06 10:36:07 +01:00
parent 92267aec50
commit 9e28ee6545
11 changed files with 142 additions and 115 deletions
+66 -42
View File
@@ -25,7 +25,7 @@ type cliOptionParser interface {
isSet() bool
isHidden() bool
requiresValue() bool
finalCheck(cliValue string) (err error)
finalCheck() (err error)
}
type OptManager interface {
@@ -33,7 +33,7 @@ type OptManager interface {
}
type SpecialValueFunc func(manager OptManager, cliValue string, currentValue any) (value any, err error)
type FinalCheckFunc func(cliValue string, currentValue any) (err error)
type FinalCheckFunc func(currentValue any) (err error)
type OptReference interface {
AddSpecialValue(cliValue string, specialFunc SpecialValueFunc)
@@ -158,17 +158,12 @@ func (cli *CliParser) addHelpAndVersion() {
}
func (cli *CliParser) Parse() (err error) {
var arg string
var i int
var commandArgs []string
func (cli *CliParser) parseOptions() (commandArgs []string, err error) {
// var commandArgs []string
var optionsAllowed bool = true
cli.addHelpAndVersion()
// first parse options and collect argument in the args array
skipNext := false
for i, arg = range cli.cliArgs[1:] {
for i, arg := range cli.cliArgs[1:] {
if skipNext {
skipNext = false
} else {
@@ -186,49 +181,78 @@ func (cli *CliParser) Parse() (err error) {
}
}
}
return
}
// then parse collected arguments
if err == nil {
var n int
i = 0
// acquire arguments as required by the argSpecs
specIndex := -1
for index, argSpec := range cli.argSpecs {
specIndex = index
if n, err = argSpec.parse(cli, specIndex, commandArgs, i); err != nil {
break
}
i += n
if i >= len(commandArgs) {
break
}
func (cli *CliParser) checkOptionValues() (err error) {
for _, opt := range cli.options {
if err = opt.finalCheck(); err != nil {
break
}
}
return
}
// check if there are remaining arg-specs that require a value
if err == nil {
if i < len(commandArgs) {
err = fmt.Errorf("too many arguments: %d allowed", i)
} else {
specIndex++
if specIndex < len(cli.argSpecs) {
// skip all non required args
for _, spec := range cli.argSpecs[specIndex:] {
if !spec.getBase().required {
specIndex++
}
func (cli *CliParser) parseCommandArgs(commandArgs []string) (err error) {
var n int
i := 0
// acquire arguments as required by the argSpecs
specIndex := -1
for index, argSpec := range cli.argSpecs {
specIndex = index
if n, err = argSpec.parse(cli, specIndex, commandArgs, i); err != nil {
break
}
i += n
if i >= len(commandArgs) {
break
}
}
// check if there are remaining arg-specs that require a value
if err == nil {
if i < len(commandArgs) {
err = fmt.Errorf("too many arguments: %d allowed", i)
} else {
specIndex++
if specIndex < len(cli.argSpecs) {
// skip all non required args
for _, spec := range cli.argSpecs[specIndex:] {
if !spec.getBase().required {
specIndex++
}
}
// return error if there are remaining arg-specs that require a value
if specIndex < len(cli.argSpecs) {
err = errTooFewArguments(len(cli.argSpecs))
}
}
// return error if there are remaining arg-specs that require a value
if specIndex < len(cli.argSpecs) {
err = errTooFewArguments(len(cli.argSpecs))
}
}
}
return
}
func (cli *CliParser) Parse() (err error) {
var commandArgs []string
cli.addHelpAndVersion()
// first parse options and collect command arguments in the args array
if commandArgs, err = cli.parseOptions(); err != nil {
return
}
// do final checks
if err = cli.checkOptionValues(); err != nil {
return
}
// then parse collected arguments
err = cli.parseCommandArgs(commandArgs)
return
}
func (cli *CliParser) checkCompatibility(arg string) (err error) {
var opti cliOptionParser
if opti = cli.findOptionByArg(arg); opti != nil {