Skip to content

Commit 0f196f5

Browse files
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.
1 parent 133c649 commit 0f196f5

File tree

3 files changed

+33
-19
lines changed

3 files changed

+33
-19
lines changed

cobra.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ var EnableTraverseRunHooks = defaultTraverseRunHooks
6868

6969
// EnableErrorOnUnknownSubcommand controls the behavior of subcommand handling.
7070
// When the flag is set true the behavior of Command.Execute() will change:
71-
// If a sub-subcommand is not found ErrUnknownSubcommand will be returned on calling
71+
// If a sub-subcommand is not found an error will be returned on calling
7272
// Command.Exec() instead of the old behavior where a nil error was sent.
7373
// If the flag is false (default) the old behavior is performed.
7474
// For this behavior the child subcommand must be nil.

command.go

+7-11
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ type Group struct {
4444
Title string
4545
}
4646

47-
// ErrUnknownSubcommand is returned by Command.Execute() when the subcommand was not found.
48-
// Hereto, the ErrorOnUnknownSubcommand flag must be set true.
49-
var ErrUnknownSubcommand = errors.New("subcommand is unknown")
50-
5147
// Command is just that, a command for your application.
5248
// E.g. 'go run ...' - 'run' is the command. Cobra requires
5349
// you to define the usage and description as part of your command
@@ -926,9 +922,14 @@ func (c *Command) execute(a []string) (err error) {
926922
}
927923
}
928924

925+
argWoFlags := c.Flags().Args()
926+
if c.DisableFlagParsing {
927+
argWoFlags = a
928+
}
929+
929930
if !c.Runnable() {
930-
if EnableErrorOnUnknownSubcommand {
931-
return ErrUnknownSubcommand
931+
if EnableErrorOnUnknownSubcommand && len(argWoFlags) > 0 {
932+
return fmt.Errorf("unknown command %q for %q%s", argWoFlags[0], c.CommandPath(), c.findSuggestions(argWoFlags[0]))
932933
} else {
933934
return flag.ErrHelp
934935
}
@@ -937,11 +938,6 @@ func (c *Command) execute(a []string) (err error) {
937938

938939
defer c.postRun()
939940

940-
argWoFlags := c.Flags().Args()
941-
if c.DisableFlagParsing {
942-
argWoFlags = a
943-
}
944-
945941
if err := c.ValidateArgs(argWoFlags); err != nil {
946942
return err
947943
}

command_test.go

+25-7
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package cobra
1717
import (
1818
"bytes"
1919
"context"
20-
"errors"
2120
"fmt"
2221
"io"
2322
"os"
@@ -224,7 +223,8 @@ func TestSubcommandExecuteMissingSubcommand(t *testing.T) {
224223
}
225224

226225
func TestSubcommandExecuteMissingSubcommandWithErrorOnUnknownSubcommand(t *testing.T) {
227-
rootCmd := &Command{Use: "root", Run: emptyRun}
226+
const rootName = "root"
227+
rootCmd := &Command{Use: rootName, Run: emptyRun}
228228
const childName = "child"
229229
const grandchildName = "grandchild"
230230
EnableErrorOnUnknownSubcommand = true
@@ -236,10 +236,10 @@ func TestSubcommandExecuteMissingSubcommandWithErrorOnUnknownSubcommand(t *testi
236236

237237
// test existing command
238238
c, output, err := executeCommandC(rootCmd, childName)
239-
if !strings.HasPrefix(output, "Error:") {
239+
if strings.HasPrefix(output, "Error:") {
240240
t.Errorf("Unexpected output: %v", output)
241241
}
242-
if !errors.Is(err, ErrUnknownSubcommand) {
242+
if err != nil {
243243
t.Errorf("Unexpected error: %v", err)
244244
}
245245
if c.Name() != childName {
@@ -258,12 +258,30 @@ func TestSubcommandExecuteMissingSubcommandWithErrorOnUnknownSubcommand(t *testi
258258
t.Errorf(`invalid command returned from ExecuteC: expected "child"', got: %q`, c.Name())
259259
}
260260

261-
// now test a command which does not exist, we expect an error because of the ErrorOnUnknownSubcommand flag
262-
c, output, err = executeCommandC(rootCmd, childName, "unknownChild")
261+
// test a child command which does not exist, we expect an error because of the ErrorOnUnknownSubcommand flag
262+
c, output, err = executeCommandC(rootCmd, "unknownChild")
263+
if !strings.HasPrefix(output, "Error:") {
264+
t.Errorf("Unexpected output: %v", output)
265+
}
266+
if err == nil {
267+
t.Error("Expected error")
268+
}
269+
if err != nil && !strings.HasPrefix(err.Error(), "unknown command") {
270+
t.Errorf("Unexpected error: %v", err)
271+
}
272+
if c.Name() != rootName {
273+
t.Errorf(`invalid command returned from ExecuteC: expected "child"', got: %q`, c.Name())
274+
}
275+
276+
// test a grandchild command which does not exist, we expect an error because of the ErrorOnUnknownSubcommand flag
277+
c, output, err = executeCommandC(rootCmd, childName, "unknownGrandChild")
263278
if !strings.HasPrefix(output, "Error:") {
264279
t.Errorf("Unexpected output: %v", output)
265280
}
266-
if !errors.Is(err, ErrUnknownSubcommand) {
281+
if err == nil {
282+
t.Error("Expected error")
283+
}
284+
if err != nil && !strings.HasPrefix(err.Error(), "unknown command") {
267285
t.Errorf("Unexpected error: %v", err)
268286
}
269287
if c.Name() != childName {

0 commit comments

Comments
 (0)