mirror of
https://github.com/spf13/cobra
synced 2024-11-24 14:47:12 +00:00
Backward compatibility
An error is only thrown if there are arguments to a valid command. Without any arguments the help is printed as before. An invalid subcommand will return an error.
This commit is contained in:
parent
ae6c026135
commit
41b8340b2b
3 changed files with 33 additions and 19 deletions
2
cobra.go
2
cobra.go
|
@ -68,7 +68,7 @@ var EnableTraverseRunHooks = defaultTraverseRunHooks
|
||||||
|
|
||||||
// EnableErrorOnUnknownSubcommand controls the behavior of subcommand handling.
|
// EnableErrorOnUnknownSubcommand controls the behavior of subcommand handling.
|
||||||
// When the flag is set true the behavior of Command.Execute() will change:
|
// When the flag is set true the behavior of Command.Execute() will change:
|
||||||
// If a sub-subcommand is not found ErrUnknownSubcommand will be returned on calling
|
// If a sub-subcommand is not found an error will be returned on calling
|
||||||
// Command.Exec() instead of the old behavior where a nil error was sent.
|
// Command.Exec() instead of the old behavior where a nil error was sent.
|
||||||
// If the flag is false (default) the old behavior is performed.
|
// If the flag is false (default) the old behavior is performed.
|
||||||
// For this behavior the child subcommand must be nil.
|
// For this behavior the child subcommand must be nil.
|
||||||
|
|
18
command.go
18
command.go
|
@ -44,10 +44,6 @@ type Group struct {
|
||||||
Title string
|
Title string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrUnknownSubcommand is returned by Command.Execute() when the subcommand was not found.
|
|
||||||
// Hereto, the ErrorOnUnknownSubcommand flag must be set true.
|
|
||||||
var ErrUnknownSubcommand = errors.New("subcommand is unknown")
|
|
||||||
|
|
||||||
// Command is just that, a command for your application.
|
// Command is just that, a command for your application.
|
||||||
// E.g. 'go run ...' - 'run' is the command. Cobra requires
|
// E.g. 'go run ...' - 'run' is the command. Cobra requires
|
||||||
// you to define the usage and description as part of your command
|
// you to define the usage and description as part of your command
|
||||||
|
@ -927,9 +923,14 @@ func (c *Command) execute(a []string) (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argWoFlags := c.Flags().Args()
|
||||||
|
if c.DisableFlagParsing {
|
||||||
|
argWoFlags = a
|
||||||
|
}
|
||||||
|
|
||||||
if !c.Runnable() {
|
if !c.Runnable() {
|
||||||
if EnableErrorOnUnknownSubcommand {
|
if EnableErrorOnUnknownSubcommand && len(argWoFlags) > 0 {
|
||||||
return ErrUnknownSubcommand
|
return fmt.Errorf("unknown command %q for %q%s", argWoFlags[0], c.CommandPath(), c.findSuggestions(argWoFlags[0]))
|
||||||
} else {
|
} else {
|
||||||
return flag.ErrHelp
|
return flag.ErrHelp
|
||||||
}
|
}
|
||||||
|
@ -938,11 +939,6 @@ func (c *Command) execute(a []string) (err error) {
|
||||||
|
|
||||||
defer c.postRun()
|
defer c.postRun()
|
||||||
|
|
||||||
argWoFlags := c.Flags().Args()
|
|
||||||
if c.DisableFlagParsing {
|
|
||||||
argWoFlags = a
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.ValidateArgs(argWoFlags); err != nil {
|
if err := c.ValidateArgs(argWoFlags); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ package cobra
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -224,7 +223,8 @@ func TestSubcommandExecuteMissingSubcommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSubcommandExecuteMissingSubcommandWithErrorOnUnknownSubcommand(t *testing.T) {
|
func TestSubcommandExecuteMissingSubcommandWithErrorOnUnknownSubcommand(t *testing.T) {
|
||||||
rootCmd := &Command{Use: "root", Run: emptyRun}
|
const rootName = "root"
|
||||||
|
rootCmd := &Command{Use: rootName, Run: emptyRun}
|
||||||
const childName = "child"
|
const childName = "child"
|
||||||
const grandchildName = "grandchild"
|
const grandchildName = "grandchild"
|
||||||
EnableErrorOnUnknownSubcommand = true
|
EnableErrorOnUnknownSubcommand = true
|
||||||
|
@ -236,10 +236,10 @@ func TestSubcommandExecuteMissingSubcommandWithErrorOnUnknownSubcommand(t *testi
|
||||||
|
|
||||||
// test existing command
|
// test existing command
|
||||||
c, output, err := executeCommandC(rootCmd, childName)
|
c, output, err := executeCommandC(rootCmd, childName)
|
||||||
if !strings.HasPrefix(output, "Error:") {
|
if strings.HasPrefix(output, "Error:") {
|
||||||
t.Errorf("Unexpected output: %v", output)
|
t.Errorf("Unexpected output: %v", output)
|
||||||
}
|
}
|
||||||
if !errors.Is(err, ErrUnknownSubcommand) {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if c.Name() != childName {
|
if c.Name() != childName {
|
||||||
|
@ -258,12 +258,30 @@ func TestSubcommandExecuteMissingSubcommandWithErrorOnUnknownSubcommand(t *testi
|
||||||
t.Errorf(`invalid command returned from ExecuteC: expected "child"', got: %q`, c.Name())
|
t.Errorf(`invalid command returned from ExecuteC: expected "child"', got: %q`, c.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
// now test a command which does not exist, we expect an error because of the ErrorOnUnknownSubcommand flag
|
// test a child command which does not exist, we expect an error because of the ErrorOnUnknownSubcommand flag
|
||||||
c, output, err = executeCommandC(rootCmd, childName, "unknownChild")
|
c, output, err = executeCommandC(rootCmd, "unknownChild")
|
||||||
if !strings.HasPrefix(output, "Error:") {
|
if !strings.HasPrefix(output, "Error:") {
|
||||||
t.Errorf("Unexpected output: %v", output)
|
t.Errorf("Unexpected output: %v", output)
|
||||||
}
|
}
|
||||||
if !errors.Is(err, ErrUnknownSubcommand) {
|
if err == nil {
|
||||||
|
t.Error("Expected error")
|
||||||
|
}
|
||||||
|
if err != nil && !strings.HasPrefix(err.Error(), "unknown command") {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if c.Name() != rootName {
|
||||||
|
t.Errorf(`invalid command returned from ExecuteC: expected "child"', got: %q`, c.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
// test a grandchild command which does not exist, we expect an error because of the ErrorOnUnknownSubcommand flag
|
||||||
|
c, output, err = executeCommandC(rootCmd, childName, "unknownGrandChild")
|
||||||
|
if !strings.HasPrefix(output, "Error:") {
|
||||||
|
t.Errorf("Unexpected output: %v", output)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Expected error")
|
||||||
|
}
|
||||||
|
if err != nil && !strings.HasPrefix(err.Error(), "unknown command") {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if c.Name() != childName {
|
if c.Name() != childName {
|
||||||
|
|
Loading…
Reference in a new issue