Return error when value is not specified and add more test cases
This commit is contained in:
parent
9456b4097b
commit
b8a7d72433
|
@ -9,6 +9,7 @@ import (
|
||||||
var (
|
var (
|
||||||
ErrUnknownOption = errors.New("unknown option")
|
ErrUnknownOption = errors.New("unknown option")
|
||||||
ErrCannotChainOption = errors.New("cannot chain option")
|
ErrCannotChainOption = errors.New("cannot chain option")
|
||||||
|
ErrOptionRequiresValue = errors.New("option requires value")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Parser struct {
|
type Parser struct {
|
||||||
|
@ -76,12 +77,12 @@ func (p *Parser) peek() string {
|
||||||
return p.args[p.curr+1]
|
return p.args[p.curr+1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) value() string {
|
func (p *Parser) value() (string, bool) {
|
||||||
if !p.hasNext() || (p.peek() != "-" && strings.HasPrefix(p.peek(), "-")) {
|
if !p.hasNext() || (p.peek() != "-" && strings.HasPrefix(p.peek(), "-")) {
|
||||||
return ""
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.next()
|
return p.next(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) restArgs() []string {
|
func (p *Parser) restArgs() []string {
|
||||||
|
@ -109,7 +110,11 @@ func (p *Parser) parseLongOption(longName string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if value == "" && opt.TakesArg() {
|
if value == "" && opt.TakesArg() {
|
||||||
value = p.value()
|
var ok bool
|
||||||
|
value, ok = p.value()
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("%w: %s", ErrOptionRequiresValue, "--"+longName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := opt.Parse(value); err != nil {
|
if err := opt.Parse(value); err != nil {
|
||||||
|
@ -121,7 +126,7 @@ func (p *Parser) parseLongOption(longName string) error {
|
||||||
|
|
||||||
func (p *Parser) parseShortOption(shortNames string) error {
|
func (p *Parser) parseShortOption(shortNames string) error {
|
||||||
if len(shortNames) == 1 {
|
if len(shortNames) == 1 {
|
||||||
value := p.value()
|
value, valOk := p.value()
|
||||||
|
|
||||||
opt, ok := p.opts.GetByShortName(shortNames)
|
opt, ok := p.opts.GetByShortName(shortNames)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -132,6 +137,10 @@ func (p *Parser) parseShortOption(shortNames string) error {
|
||||||
return nil // Ignore unknown option. Continue parsing.
|
return nil // Ignore unknown option. Continue parsing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !valOk && opt.TakesArg() {
|
||||||
|
return fmt.Errorf("%w: %s", ErrOptionRequiresValue, "-"+shortNames)
|
||||||
|
}
|
||||||
|
|
||||||
if err := opt.Parse(value); err != nil {
|
if err := opt.Parse(value); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -156,9 +165,6 @@ func (p *Parser) parseShortOption(shortNames string) error {
|
||||||
|
|
||||||
value = shortNames[1:]
|
value = shortNames[1:]
|
||||||
value = strings.TrimPrefix(value, "=")
|
value = strings.TrimPrefix(value, "=")
|
||||||
if len(value) == 0 {
|
|
||||||
value = p.value()
|
|
||||||
}
|
|
||||||
j = len(shortNames)
|
j = len(shortNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,15 +168,15 @@ func TestParseLongOptionWithValueAndSpace(t *testing.T) {
|
||||||
func TestParseOptionTerminator(t *testing.T) {
|
func TestParseOptionTerminator(t *testing.T) {
|
||||||
opt := opts.String("fruit", "f", "banana", "")
|
opt := opts.String("fruit", "f", "banana", "")
|
||||||
set := opts.Set{opt}
|
set := opts.Set{opt}
|
||||||
args := []string{"--fruit", "--", "hello", "world"}
|
args := []string{"--fruit", "apple", "--", "hello", "world"}
|
||||||
parser := opts.NewParser(args, set, false)
|
parser := opts.NewParser(args, set, false)
|
||||||
restArgs, err := parser.Parse()
|
restArgs, err := parser.Parse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error, got: %s", err.Error())
|
t.Errorf("Expected no error, got: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if opt.Value() != "banana" {
|
if opt.Value() != "apple" {
|
||||||
t.Errorf("Expected fruit to be 'banana', got: %s", opt.Value())
|
t.Errorf("Expected fruit to be 'apple', got: %s", opt.Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(restArgs) != 2 {
|
if len(restArgs) != 2 {
|
||||||
|
@ -311,3 +311,25 @@ func TestParseShortOptionWithEqualBadValue(t *testing.T) {
|
||||||
t.Error("Expected error")
|
t.Error("Expected error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseLongOptionMissingValue(t *testing.T) {
|
||||||
|
opt := opts.Int("fruit", "f", 0, "")
|
||||||
|
set := opts.Set{opt}
|
||||||
|
args := []string{"--fruit"}
|
||||||
|
parser := opts.NewParser(args, set, false)
|
||||||
|
_, err := parser.Parse()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Expected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseShortOptionMissingValue(t *testing.T) {
|
||||||
|
opt := opts.Int("fruit", "f", 0, "")
|
||||||
|
set := opts.Set{opt}
|
||||||
|
args := []string{"-f"}
|
||||||
|
parser := opts.NewParser(args, set, false)
|
||||||
|
_, err := parser.Parse()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Expected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue