Add error for unknown option

This commit is contained in:
Evan Fiordeliso 2023-11-11 21:29:56 -05:00
parent f4c5adc4c7
commit 981bfaa04e
2 changed files with 48 additions and 24 deletions

View File

@ -68,12 +68,12 @@ func (c *Command) Execute(args []string) {
args = args[1:] args = args[1:]
} }
parser := opts.NewParser(args, c.opts) parser := opts.NewParser(args, c.opts, false)
restArgs, err := parser.Parse() restArgs, err := parser.Parse()
if err != nil { if err != nil {
fmt.Printf("Option error: %s\n", err.Error()) fmt.Println(err.Error())
c.ShowHelp() c.ShowHelp()
return os.Exit(1)
} }
if len(restArgs) > 0 { if len(restArgs) > 0 {

View File

@ -2,10 +2,12 @@ package opts
import ( import (
"errors" "errors"
"fmt"
"strings" "strings"
) )
var ( var (
ErrUnknownOption = errors.New("unknown option")
ErrInvalidShortOption = errors.New("invalid short option") ErrInvalidShortOption = errors.New("invalid short option")
ErrCannotChainOption = errors.New("cannot chain option as it takes an argument") ErrCannotChainOption = errors.New("cannot chain option as it takes an argument")
) )
@ -14,13 +16,17 @@ type Parser struct {
opts Set opts Set
args []string args []string
curr int curr int
ignoreUnknown bool
} }
func NewParser(args []string, opts []Option) *Parser { func NewParser(args []string, opts []Option, ignoreUnknown bool) *Parser {
return &Parser{ return &Parser{
opts: append(opts, globalOpts...), opts: append(opts, globalOpts...),
args: args, args: args,
curr: -1, curr: -1,
ignoreUnknown: ignoreUnknown,
} }
} }
@ -93,10 +99,16 @@ func (p *Parser) parseLongOption(longName string) error {
} }
opt, ok := p.opts.GetByLongName(longName) opt, ok := p.opts.GetByLongName(longName)
if ok { if !ok {
if err := opt.Parse(value); err != nil { if !p.ignoreUnknown {
return err return fmt.Errorf("%w: %s", ErrUnknownOption, "--"+longName)
} }
return nil // Ignore unknown option. Continue parsing.
}
if err := opt.Parse(value); err != nil {
return err
} }
return nil return nil
@ -109,10 +121,16 @@ func (p *Parser) parseShortOption(shortNames string) error {
value := p.value() value := p.value()
opt, ok := p.opts.GetByShortName(shortNames) opt, ok := p.opts.GetByShortName(shortNames)
if ok { if !ok {
if err := opt.Parse(value); err != nil { if !p.ignoreUnknown {
return err return fmt.Errorf("%w: %s", ErrUnknownOption, "-"+shortNames)
} }
return nil // Ignore unknown option. Continue parsing.
}
if err := opt.Parse(value); err != nil {
return err
} }
} else { } else {
for j := 0; j < len(shortNames); j++ { for j := 0; j < len(shortNames); j++ {
@ -120,23 +138,29 @@ func (p *Parser) parseShortOption(shortNames string) error {
value := "" value := ""
opt, ok := p.opts.GetByShortName(string(shortName)) opt, ok := p.opts.GetByShortName(string(shortName))
if ok { if !ok {
if opt.TakesArg() { if !p.ignoreUnknown {
if j > 0 { return fmt.Errorf("%w: %s", ErrUnknownOption, "-"+string(shortName))
return ErrCannotChainOption
}
value = shortNames[1:]
value = strings.TrimPrefix(value, "=")
if len(value) == 0 {
value = p.value()
}
j = len(shortNames)
} }
if err := opt.Parse(value); err != nil { continue // Ignore unknown option. Continue parsing.
return err }
if opt.TakesArg() {
if j > 0 {
return ErrCannotChainOption
} }
value = shortNames[1:]
value = strings.TrimPrefix(value, "=")
if len(value) == 0 {
value = p.value()
}
j = len(shortNames)
}
if err := opt.Parse(value); err != nil {
return err
} }
} }
} }