Skip to content

Commit

Permalink
Merge pull request #211 from hchargois/master
Browse files Browse the repository at this point in the history
Fix PassAfterNonOption not working with positional args
  • Loading branch information
jessevdk authored Sep 23, 2018
2 parents b820973 + 5e95b3a commit ebe2690
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 19 deletions.
98 changes: 98 additions & 0 deletions options_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package flags

import (
"strings"
"testing"
)

Expand Down Expand Up @@ -43,3 +44,100 @@ func TestPassAfterNonOption(t *testing.T) {

assertStringArray(t, ret, []string{"arg", "-v", "-g"})
}

func TestPassAfterNonOptionWithPositional(t *testing.T) {
var opts = struct {
Value bool `short:"v"`

Positional struct {
Rest []string `required:"yes"`
} `positional-args:"yes"`
}{}

p := NewParser(&opts, PassAfterNonOption)
ret, err := p.ParseArgs([]string{"-v", "arg", "-v", "-g"})

if err != nil {
t.Fatalf("Unexpected error: %v", err)
return
}

if !opts.Value {
t.Errorf("Expected Value to be true")
}

assertStringArray(t, ret, []string{})
assertStringArray(t, opts.Positional.Rest, []string{"arg", "-v", "-g"})
}

func TestPassAfterNonOptionWithPositionalIntPass(t *testing.T) {
var opts = struct {
Value bool `short:"v"`

Positional struct {
Rest []int `required:"yes"`
} `positional-args:"yes"`
}{}

p := NewParser(&opts, PassAfterNonOption)
ret, err := p.ParseArgs([]string{"-v", "1", "2", "3"})

if err != nil {
t.Fatalf("Unexpected error: %v", err)
return
}

if !opts.Value {
t.Errorf("Expected Value to be true")
}

assertStringArray(t, ret, []string{})
for i, rest := range opts.Positional.Rest {
if rest != i+1 {
assertErrorf(t, "Expected %v got %v", i+1, rest)
}
}
}

func TestPassAfterNonOptionWithPositionalIntFail(t *testing.T) {
var opts = struct {
Value bool `short:"v"`

Positional struct {
Rest []int `required:"yes"`
} `positional-args:"yes"`
}{}

tests := []struct {
opts []string
errContains string
ret []string
}{
{
[]string{"-v", "notint1", "notint2", "notint3"},
"notint1",
[]string{"notint1", "notint2", "notint3"},
},
{
[]string{"-v", "1", "notint2", "notint3"},
"notint2",
[]string{"1", "notint2", "notint3"},
},
}

for _, test := range tests {
p := NewParser(&opts, PassAfterNonOption)
ret, err := p.ParseArgs(test.opts)

if err == nil {
assertErrorf(t, "Expected error")
return
}

if !strings.Contains(err.Error(), test.errContains) {
assertErrorf(t, "Expected the first illegal argument in the error")
}

assertStringArray(t, ret, test.ret)
}
}
35 changes: 16 additions & 19 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ func (p *Parser) ParseArgs(args []string) ([]string, error) {
p.fillParseState(s)

for !s.eof() {
var err error
arg := s.pop()

// When PassDoubleDash is set and we encounter a --, then
Expand All @@ -251,6 +252,20 @@ func (p *Parser) ParseArgs(args []string) ([]string, error) {
}

if !argumentIsOption(arg) {
if (p.Options & PassAfterNonOption) != None {
// If PassAfterNonOption is set then all remaining arguments
// are considered positional
if err = s.addArgs(s.arg); err != nil {
break
}

if err = s.addArgs(s.args...); err != nil {
break
}

break
}

// Note: this also sets s.err, so we can just check for
// nil here and use s.err later
if p.parseNonOption(s) != nil {
Expand All @@ -260,8 +275,6 @@ func (p *Parser) ParseArgs(args []string) ([]string, error) {
continue
}

var err error

prefix, optname, islong := stripOptionPrefix(arg)
optname, _, argument := splitOption(prefix, optname, islong)

Expand Down Expand Up @@ -653,23 +666,7 @@ func (p *Parser) parseNonOption(s *parseState) error {
}
}

if (p.Options & PassAfterNonOption) != None {
// If PassAfterNonOption is set then all remaining arguments
// are considered positional
if err := s.addArgs(s.arg); err != nil {
return err
}

if err := s.addArgs(s.args...); err != nil {
return err
}

s.args = []string{}
} else {
return s.addArgs(s.arg)
}

return nil
return s.addArgs(s.arg)
}

func (p *Parser) showBuiltinHelp() error {
Expand Down

0 comments on commit ebe2690

Please sign in to comment.