diff --git a/arg_test.go b/arg_test.go index c7c0a61..3ee8893 100644 --- a/arg_test.go +++ b/arg_test.go @@ -161,3 +161,27 @@ func TestPositionalRequiredRestRangeEmptyFail(t *testing.T) { assertError(t, err, ErrRequired, "the required argument `Rest (zero arguments)` was not provided") } + +func TestPositionalWithSubcommand(t *testing.T) { + var opts = struct { + Command struct { + Positional struct { + Rest []string + } `positional-args:"yes"` + Subcommand struct { + Positional struct { + Rest []string + } `positional-args:"yes"` + } `command:"subcmd"` + } `command:"cmd" subcommands-optional:"true"` + }{} + + p := NewParser(&opts, None) + _, err := p.ParseArgs([]string{"cmd", "subcmd", "thing"}) + + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + assertStringArray(t, opts.Command.Subcommand.Positional.Rest, []string{"thing"}) + assertStringArray(t, opts.Command.Positional.Rest, []string{}) +} diff --git a/parser.go b/parser.go index a5347b0..e1fdda9 100644 --- a/parser.go +++ b/parser.go @@ -650,22 +650,19 @@ func (p *parseState) addArgs(args ...string) error { } func (p *Parser) parseNonOption(s *parseState) error { - if len(s.positional) > 0 { - return s.addArgs(s.arg) - } - if len(s.command.commands) > 0 && len(s.retargs) == 0 { if cmd := s.lookup.commands[s.arg]; cmd != nil { s.command.Active = cmd cmd.fillParseState(s) return nil + } else if len(s.positional) > 0 { + return s.addArgs(s.arg) } else if !s.command.SubcommandsOptional { s.addArgs(s.arg) return newErrorf(ErrUnknownCommand, "Unknown command `%s'", s.arg) } } - return s.addArgs(s.arg) }