mirror of
https://github.com/spf13/cobra
synced 2024-12-26 22:37:08 +00:00
Command: Add new field ErrorOnShadowedFlags and error on shadowed flag in ExecuteC
This commit is contained in:
parent
da49908486
commit
185510de5f
2 changed files with 111 additions and 0 deletions
14
command.go
14
command.go
|
@ -244,6 +244,9 @@ type Command struct {
|
|||
// SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
|
||||
// Must be > 0.
|
||||
SuggestionsMinimumDistance int
|
||||
|
||||
// ErrorOnShadowedFlags will check for any shadowed flags when calling Execute and returns and error
|
||||
ErrorOnShadowedFlags bool
|
||||
}
|
||||
|
||||
// Context returns underlying command context. If command was executed
|
||||
|
@ -1065,6 +1068,17 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
|||
cmd.ctx = c.ctx
|
||||
}
|
||||
|
||||
if c.ErrorOnShadowedFlags {
|
||||
clashingFlags := cmd.getClashingFlagnames()
|
||||
if len(clashingFlags) != 0 {
|
||||
errorString := "Error: The following flags would shadow each other:\n"
|
||||
for _, clashingFlag := range clashingFlags {
|
||||
errorString += fmt.Sprintf(" - Flag '%s' with usage '%s'\n", clashingFlag.Name, clashingFlag.Usage)
|
||||
}
|
||||
return cmd, fmt.Errorf(errorString)
|
||||
}
|
||||
}
|
||||
|
||||
err = cmd.execute(flags)
|
||||
if err != nil {
|
||||
// Always show help if requested, even if SilenceErrors is in
|
||||
|
|
|
@ -898,6 +898,103 @@ func TestHelpCommandExecutedOnChild(t *testing.T) {
|
|||
checkStringContains(t, output, childCmd.Long)
|
||||
}
|
||||
|
||||
func TestErrorOnShadowedFlagsOnShadowedFlag(t *testing.T) {
|
||||
parent := &Command{Use: "parent", Run: emptyRun, ErrorOnShadowedFlags: true}
|
||||
child := &Command{Use: "child", Run: emptyRun}
|
||||
parent.AddCommand(child)
|
||||
|
||||
parent.PersistentFlags().Bool("foo", false, "parent foo usage")
|
||||
parent.PersistentFlags().Bool("bar", false, "parent bar usage")
|
||||
child.Flags().Bool("foo", false, "child foo usage") // This shadows parent's foo flag
|
||||
child.Flags().Bool("baz", false, "child baz usage")
|
||||
|
||||
_, err := executeCommand(parent, "child")
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error")
|
||||
return
|
||||
}
|
||||
|
||||
expectedErrorStrings := []string{
|
||||
" - Flag 'foo' with usage 'parent foo usage'",
|
||||
" - Flag 'foo' with usage 'child foo usage'",
|
||||
}
|
||||
|
||||
errorString := err.Error()
|
||||
for _, expectedErrorString := range expectedErrorStrings {
|
||||
if !strings.Contains(errorString, expectedErrorString) {
|
||||
t.Errorf("Expected the string \"%s\" in the error", expectedErrorString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorOnShadowedFlagsOnSelfShadowedFlag(t *testing.T) {
|
||||
parent := &Command{Use: "parent", Run: emptyRun, ErrorOnShadowedFlags: true}
|
||||
|
||||
parent.PersistentFlags().Bool("foo", false, "parent persistent foo usage")
|
||||
parent.Flags().Bool("foo", false, "parent foo usage")
|
||||
|
||||
_, err := executeCommand(parent, "parent")
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error")
|
||||
return
|
||||
}
|
||||
|
||||
expectedErrorStrings := []string{
|
||||
" - Flag 'foo' with usage 'parent persistent foo usage'",
|
||||
" - Flag 'foo' with usage 'parent foo usage'",
|
||||
}
|
||||
|
||||
errorString := err.Error()
|
||||
for _, expectedErrorString := range expectedErrorStrings {
|
||||
if !strings.Contains(errorString, expectedErrorString) {
|
||||
t.Errorf("String %q is not present in error: %q", expectedErrorString, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorOnShadowedFlagsOnNoShadowedFlag(t *testing.T) {
|
||||
parent := &Command{Use: "parent", Run: emptyRun, ErrorOnShadowedFlags: true}
|
||||
|
||||
parent.PersistentFlags().Bool("foo", false, "parent persistent foo usage")
|
||||
parent.Flags().Bool("bar", false, "parent bar usage")
|
||||
|
||||
_, err := executeCommand(parent, "child")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorOnShadowedOnShadowedFlagParentAndChild(t *testing.T) {
|
||||
parent := &Command{Use: "parent", Run: emptyRun, ErrorOnShadowedFlags: true}
|
||||
child := &Command{Use: "child", Run: emptyRun}
|
||||
grandchild := &Command{Use: "grandchild", Run: emptyRun}
|
||||
parent.AddCommand(child)
|
||||
child.AddCommand(grandchild)
|
||||
|
||||
parent.PersistentFlags().Bool("foo", false, "parent foo usage")
|
||||
parent.PersistentFlags().Bool("bar", false, "parent bar usage")
|
||||
child.PersistentFlags().Bool("bar", false, "child bar usage")
|
||||
grandchild.Flags().Bool("baz", false, "grandchild baz usage")
|
||||
|
||||
_, err := executeCommand(parent, "child", "grandchild")
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error")
|
||||
return
|
||||
}
|
||||
|
||||
expectedErrorStrings := []string{
|
||||
" - Flag 'bar' with usage 'parent bar usage'",
|
||||
" - Flag 'bar' with usage 'child bar usage'",
|
||||
}
|
||||
|
||||
errorString := err.Error()
|
||||
for _, expectedErrorString := range expectedErrorStrings {
|
||||
if !strings.Contains(errorString, expectedErrorString) {
|
||||
t.Errorf("Expected the string \"%s\" in the error", expectedErrorString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelpCommandExecutedOnChildWithFlagThatShadowsParentFlag(t *testing.T) {
|
||||
parent := &Command{Use: "parent", Run: emptyRun}
|
||||
child := &Command{Use: "child", Run: emptyRun}
|
||||
|
|
Loading…
Reference in a new issue