-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
closes #2130 new command flag ErrorOnUnknownSubcommand #2167
base: main
Are you sure you want to change the base?
closes #2130 new command flag ErrorOnUnknownSubcommand #2167
Conversation
command.go
Outdated
@@ -923,9 +938,12 @@ func (c *Command) execute(a []string) (err error) { | |||
} | |||
|
|||
if !c.Runnable() { | |||
return flag.ErrHelp | |||
if c.ErrorOnUnknownSubcommand { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c
is the current command here. Therefore I would need to set this new flag for every command throughout my program to get the new behaviour globally.
Do you feel this feature should be enabled per command or globally?
If globally, then you can add a global variable in cobra.go
instead of in the command structure. Then the program can enable this feature in a single location.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there! You are right. I think the global behavior is more what I (and probably others) want! I will change that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @marckhouzam. Did you have a chance to review my changes? Would the behavior be so ok?
fd99350
to
3974349
Compare
@andremueller Sorry for the delay but I had to find time to look into the many issues and PRs that tried to address this issue in the hopes of not missing anything. Looking at #1056 and its PR #1068 there is a case we need to handle which is the additional help topics. We need to handle this case properly when After giving it some thought I think we can handle everything in the same fashion, as long as we don't return an error when there are no arguments. I'll put comments in-line to clarify. Here is a very small program that creates a program with commands and with help topics like so, to help you see what I mean:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please run make lint
to find the linter error.
command.go
Outdated
@@ -44,6 +44,10 @@ type Group struct { | |||
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") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's format this command message like the one in legacyArgs()
to have a consistent behaviour.
fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
command.go
Outdated
@@ -923,9 +927,12 @@ func (c *Command) execute(a []string) (err error) { | |||
} | |||
|
|||
if !c.Runnable() { | |||
return flag.ErrHelp | |||
if EnableErrorOnUnknownSubcommand { | |||
return ErrUnknownSubcommand |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's only return the error if there is at least one arg.
This will allow to get the usage printed without an error when running a valid command that doesn't have a Run. This is something users do a lot. For example running helm repo
should print the usage without showing an error.
You should be able to move up the following lines to get the number of args:
argWoFlags := c.Flags().Args()
if c.DisableFlagParsing {
argWoFlags = a
}
childCmd.AddCommand(child2Cmd) | ||
|
||
// test existing command | ||
c, output, err := executeCommandC(rootCmd, childName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case should not show an error but should print the usage like before.
Thank you @andremueller for working on this PR. We, from the Argo CD team, are also interested in this feature. |
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.
0f196f5
to
0d550c1
Compare
Hey @marckhouzam. I tried to include your proposals in the code. Actually one linting issue fixed which was not mine. However, I removed the common error "class" ErrUnknownSubcommand. Would it be a good idea to refactor all Hint: ErrUnknownCommand would be thrown in both cases: unknown command and unknown subcommand. |
Yes, there is no sane way to handle Maybe cobra needs a mechanism for handling unknown commands? this can be used to implement plugins. |
Proposed a backward compatible solution to #2130
Hereto a new flag
ErrorOnUnknownSubcommand
was added to theCommand
struct. Unit tests were added accordingly (TestSubcommandExecuteMissingSubcommand and TestSubcommandExecuteMissingSubcommandWithErrorOnUnknownSubcommand.Fixes #1156 #2130