mirror of
https://github.com/spf13/cobra
synced 2024-11-24 14:47:12 +00:00
args: add new UnknownCommandError
type
This commit makes unknown commands a proper error type so that the caller can check for this specific error type without having to do string comparisons. This is useful in the context of https://github.com/spf13/cobra/issues/823 Signed-off-by: Michael Vogt <mvogt@redhat.com> Signed-off-by: Michael Vogt <michael.vogt@gmail.com>
This commit is contained in:
parent
756ba6dad6
commit
a75c389fec
2 changed files with 27 additions and 3 deletions
15
args.go
15
args.go
|
@ -21,6 +21,17 @@ import (
|
||||||
|
|
||||||
type PositionalArgs func(cmd *Command, args []string) error
|
type PositionalArgs func(cmd *Command, args []string) error
|
||||||
|
|
||||||
|
// UnknownCommandError is returned for unknown command
|
||||||
|
type UnknownCommandError struct {
|
||||||
|
unknownCmd string
|
||||||
|
cmdPath string
|
||||||
|
suggestions string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e UnknownCommandError) Error() string {
|
||||||
|
return fmt.Sprintf("unknown command %q for %q%s", e.unknownCmd, e.cmdPath, e.suggestions)
|
||||||
|
}
|
||||||
|
|
||||||
// legacyArgs validation has the following behaviour:
|
// legacyArgs validation has the following behaviour:
|
||||||
// - root commands with no subcommands can take arbitrary arguments
|
// - root commands with no subcommands can take arbitrary arguments
|
||||||
// - root commands with subcommands will do subcommand validity checking
|
// - root commands with subcommands will do subcommand validity checking
|
||||||
|
@ -33,7 +44,7 @@ func legacyArgs(cmd *Command, args []string) error {
|
||||||
|
|
||||||
// root command with subcommands, do subcommand checking.
|
// root command with subcommands, do subcommand checking.
|
||||||
if !cmd.HasParent() && len(args) > 0 {
|
if !cmd.HasParent() && len(args) > 0 {
|
||||||
return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
|
return UnknownCommandError{args[0], cmd.CommandPath(), cmd.findSuggestions(args[0])}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -41,7 +52,7 @@ func legacyArgs(cmd *Command, args []string) error {
|
||||||
// NoArgs returns an error if any args are included.
|
// NoArgs returns an error if any args are included.
|
||||||
func NoArgs(cmd *Command, args []string) error {
|
func NoArgs(cmd *Command, args []string) error {
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())
|
return UnknownCommandError{args[0], cmd.CommandPath(), ""}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,10 @@ func TestRootExecuteUnknownCommand(t *testing.T) {
|
||||||
rootCmd := &Command{Use: "root", Run: emptyRun}
|
rootCmd := &Command{Use: "root", Run: emptyRun}
|
||||||
rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
|
rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
|
||||||
|
|
||||||
output, _ := executeCommand(rootCmd, "unknown")
|
output, err := executeCommand(rootCmd, "unknown")
|
||||||
|
if _, ok := err.(UnknownCommandError); !ok {
|
||||||
|
t.Errorf("Expected:\n %T\nGot:\n %T\n", err, UnknownCommandError{})
|
||||||
|
}
|
||||||
|
|
||||||
expected := "Error: unknown command \"unknown\" for \"root\"\nRun 'root --help' for usage.\n"
|
expected := "Error: unknown command \"unknown\" for \"root\"\nRun 'root --help' for usage.\n"
|
||||||
|
|
||||||
|
@ -156,6 +159,16 @@ func TestRootExecuteUnknownCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRootFindUnknownCommandErrorType(t *testing.T) {
|
||||||
|
rootCmd := &Command{Use: "root", Run: emptyRun}
|
||||||
|
rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
|
||||||
|
|
||||||
|
_, _, err := rootCmd.Find([]string{"unknown"})
|
||||||
|
if _, ok := err.(UnknownCommandError); !ok {
|
||||||
|
t.Errorf("Expected:\n %T\nGot:\n %T\n", err, UnknownCommandError{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSubcommandExecuteC(t *testing.T) {
|
func TestSubcommandExecuteC(t *testing.T) {
|
||||||
rootCmd := &Command{Use: "root", Run: emptyRun}
|
rootCmd := &Command{Use: "root", Run: emptyRun}
|
||||||
childCmd := &Command{Use: "child", Run: emptyRun}
|
childCmd := &Command{Use: "child", Run: emptyRun}
|
||||||
|
|
Loading…
Reference in a new issue