From 140c5d89f19c4ce88b06dde2d6c3780d86608da3 Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Thu, 2 Jun 2022 11:08:19 +0200 Subject: [PATCH 1/2] provide usefull errors when using invalid sub command --- command.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/command.go b/command.go index 6ff47dd5c..5c0db8b1d 100644 --- a/command.go +++ b/command.go @@ -766,7 +766,10 @@ func (c *Command) Traverse(args []string) (*Command, []string, error) { cmd := c.findNext(arg) if cmd == nil { - return c, args, nil + if c.Runnable() { + return c, args, nil + } + return c, args, legacyArgs(c, args) } if err := c.ParseFlags(flags); err != nil { From c236cde1e2bd4bc275fad8b6372b18283b8165b2 Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Sun, 7 Aug 2022 13:44:30 +0200 Subject: [PATCH 2/2] apply fix to subcommands, also --- args.go | 17 +++++++++++++++++ command.go | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/args.go b/args.go index 2c1f99e78..8b26269c8 100644 --- a/args.go +++ b/args.go @@ -38,6 +38,23 @@ func legacyArgs(cmd *Command, args []string) error { return nil } +// Legacy sub command arg validation has the following behaviour: +// - commands with no subcommands can take arbitrary arguments +// - commands with subcommands will do subcommand validity checking +// - subcommands will always accept arbitrary arguments +func legacySubCommandArgs(cmd *Command, args []string) error { + // no subcommand, always take args + if !cmd.HasSubCommands() { + return nil + } + + // command with subcommands, do subcommand checking. + if len(args) > 0 { + return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0])) + } + return nil +} + // NoArgs returns an error if any args are included. func NoArgs(cmd *Command, args []string) error { if len(args) > 0 { diff --git a/command.go b/command.go index 5c0db8b1d..b756593ec 100644 --- a/command.go +++ b/command.go @@ -769,7 +769,7 @@ func (c *Command) Traverse(args []string) (*Command, []string, error) { if c.Runnable() { return c, args, nil } - return c, args, legacyArgs(c, args) + return c, args, legacySubCommandArgs(c, args) } if err := c.ParseFlags(flags); err != nil {