From d8e244d161149199512250e12ab5b493b89cd889 Mon Sep 17 00:00:00 2001 From: Brian Fitzgerald Date: Fri, 6 Apr 2018 12:44:58 -0700 Subject: [PATCH] Updates NoArgs to also report invalid argument NoArgs currently reports "unknown command" in all cases, which can be is a little misleading to the user if there are no subcommands. Change it as follows - if subcommands and one extra arg, say "unknown command" - otherwise, say "invalid argument(s)" and show all extra args This should produce more meaningful error messages to users, and works for both the root and sub-commands. --- args.go | 13 +++++++++++-- args_test.go | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/args.go b/args.go index a5d8a927..dddeca3d 100644 --- a/args.go +++ b/args.go @@ -2,6 +2,7 @@ package cobra import ( "fmt" + "strings" ) type PositionalArgs func(cmd *Command, args []string) error @@ -25,10 +26,18 @@ func legacyArgs(cmd *Command, args []string) error { // NoArgs returns an error if any args are included. func NoArgs(cmd *Command, args []string) error { - if len(args) > 0 { + if len(args) == 0 { + return nil + } + + // If we have exactly one argument and we have sub-commands, then assume the user + // made a typo on a subcommand, or typed the wrong subcommand + if len(args) == 1 && len(cmd.commands) > 0 { return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath()) } - return nil + + // Otherwise, assume that this is one or more invalid arguments + return fmt.Errorf("invalid argument(s) %q for %q", strings.Join(args, " "), cmd.CommandPath()) } // OnlyValidArgs returns an error if any args are not in the list of ValidArgs. diff --git a/args_test.go b/args_test.go index d797b6f5..594141cd 100644 --- a/args_test.go +++ b/args_test.go @@ -26,7 +26,7 @@ func TestNoArgsWithArgs(t *testing.T) { } got := err.Error() - expected := `unknown command "illegal" for "c"` + expected := `invalid argument(s) "illegal" for "c"` if got != expected { t.Errorf("Expected: %q, got: %q", expected, got) } @@ -223,7 +223,7 @@ func TestChildTakesNoArgs(t *testing.T) { } got := err.Error() - expected := `unknown command "illegal" for "root child"` + expected := `invalid argument(s) "illegal args" for "root child"` if !strings.Contains(got, expected) { t.Errorf("expected %q, got %q", expected, got) }