add customizable UnknownCommandErrorFunc

This commit is contained in:
John Brunton 2020-06-25 14:33:15 +01:00
parent 04318720db
commit 3293599666
3 changed files with 47 additions and 1 deletions

View file

@ -19,7 +19,7 @@ func legacyArgs(cmd *Command, args []string) error {
// root command with subcommands, do subcommand checking.
if !cmd.HasParent() && len(args) > 0 {
return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
return cmd.UnknownCommandErrorFunc()(cmd, args[0])
}
return nil
}

View file

@ -192,6 +192,8 @@ type Command struct {
// flagErrorFunc is func defined by user and it's called when the parsing of
// flags returns an error.
flagErrorFunc func(*Command, error) error
// unknownCommandErrorFunc is func defined by user, called when the typed command cannot be found
unknownCommandErrorFunc func(*Command, string) error
// helpTemplate is help template defined by user.
helpTemplate string
// helpFunc is help func defined by user.
@ -264,6 +266,12 @@ func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
c.flagErrorFunc = f
}
// SetUnknownCommandErrorFunc sets a function to generate an error when flag parsing
// fails.
func (c *Command) SetUnknownCommandErrorFunc(f func(*Command, string) error) {
c.unknownCommandErrorFunc = f
}
// SetHelpFunc sets help function. Can be defined by Application.
func (c *Command) SetHelpFunc(f func(*Command, []string)) {
c.helpFunc = f
@ -435,6 +443,22 @@ func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
}
}
// UnknownCommandErrorFunc returns either the function set by SetUnknownCommandErrorFunc for this
// command or a parent, or it returns a function which returns the original
// error.
func (c *Command) UnknownCommandErrorFunc() (f func(*Command, string) error) {
if c.unknownCommandErrorFunc != nil {
return c.unknownCommandErrorFunc
}
if c.HasParent() {
return c.parent.unknownCommandErrorFunc
}
return func(c *Command, arg string) error {
return fmt.Errorf("unknown command %q for %q%s", arg, c.CommandPath(), c.findSuggestions(arg))
}
}
var minUsagePadding = 25
// UsagePadding return padding for the usage.

View file

@ -1653,6 +1653,28 @@ func TestFlagErrorFunc(t *testing.T) {
}
}
func TestUnknownCommandErrorFunc(t *testing.T) {
rootCmd := &Command{Use: "root", Run: emptyRun}
subCmd := &Command{
Use: "type",
Run: emptyRun,
}
rootCmd.AddCommand(subCmd)
expectedFmt := "unknown command: %v"
rootCmd.SetUnknownCommandErrorFunc(func(_ *Command, arg string) error {
return fmt.Errorf(expectedFmt, arg)
})
_, err := executeCommand(rootCmd, "typo")
got := err.Error()
expected := "unknown command: typo"
if got != expected {
t.Errorf("Expected %v, got %v", expected, got)
}
}
// TestSortedFlags checks,
// if cmd.LocalFlags() is unsorted when cmd.Flags().SortFlags set to false.
// Related to https://github.com/spf13/cobra/issues/404.