Skip to content

Commit

Permalink
Add bad argument list to user error when possible
Browse files Browse the repository at this point in the history
Addresses docopt#37

This allows Parse callers to emit the list of unexpected arguments in some
common cases, e.g., extra arguments, out-of-order arguments.
  • Loading branch information
benfleis committed Sep 23, 2016
1 parent 784ddc5 commit 0eeb802
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
36 changes: 27 additions & 9 deletions docopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,22 @@ func parse(doc string, argv []string, help bool, version string, optionsFirst bo
return
}
matched, left, collected := pat.match(&patternArgv, nil)
if matched && len(*left) == 0 {
patFlat, err = pat.flat(patternDefault)
if err != nil {
output = handleError(err, usage)
return
if !matched || len(*left) > 0 {
badArgs := left.ArgumentsString()
if len(badArgs) > 0 {
err = newUserError("unexpected arguments: " + badArgs)
} else {
err = newUserError("")
}
args = append(patFlat, *collected...).dictionary()
output = handleError(err, usage)
return
}

err = newUserError("")
output = handleError(err, usage)
patFlat, err = pat.flat(patternDefault)
if err != nil {
output = handleError(err, usage)
return
}
args = append(patFlat, *collected...).dictionary()
return
}

Expand Down Expand Up @@ -1215,6 +1219,20 @@ func (pl patternList) dictionary() map[string]interface{} {
return dict
}

// ArgumentsString converts patternList into a space separated string of
// arguments; it ignores any patterns that are not arguments, and does not walk
// children.
func (pl patternList) ArgumentsString() string {
args := []string{}
for _, arg := range pl {
argStr, ok := arg.value.(string)
if ok && (arg.t&patternArgument) != 0 {
args = append(args, argStr)
}
}
return strings.Join(args, " ")
}

func stringPartition(s, sep string) (string, string, string) {
sepPos := strings.Index(s, sep)
if sepPos == -1 { // no seperator found
Expand Down
14 changes: 13 additions & 1 deletion docopt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,21 @@ func TestCommands(t *testing.T) {
t.Error(err)
}
_, err := Parse("Usage: prog a b", []string{"b", "a"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
userErr, ok := err.(*UserError)
if !ok {
t.Error(err)
}
if !strings.HasSuffix(userErr.Error(), ": b a") {
t.Error("expected invalid arguments")
}
_, err = Parse("Usage: prog a", []string{"a", "b", "c"}, true, "", false, false)
userErr, ok = err.(*UserError)
if !ok {
t.Error(err)
}
if !strings.HasSuffix(userErr.Error(), ": b c") {
t.Error("expected invalid arguments")
}
return
}

Expand Down

0 comments on commit 0eeb802

Please sign in to comment.