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:]
}
parser := opts.NewParser(args, c.opts)
parser := opts.NewParser(args, c.opts, false)
restArgs, err := parser.Parse()
if err != nil {
fmt.Printf("Option error: %s\n", err.Error())
fmt.Println(err.Error())
c.ShowHelp()
return
os.Exit(1)
}
if len(restArgs) > 0 {

View File

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