mirror of
https://github.com/spf13/cobra
synced 2025-01-30 23:46:45 +00:00
Make command suggestion messages configurable.
This commit is contained in:
parent
01ffff4eca
commit
e4d96b75c1
3 changed files with 62 additions and 2 deletions
4
args.go
4
args.go
|
@ -33,7 +33,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 fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.SuggestFunc()(args[0]))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ func OnlyValidArgs(cmd *Command, args []string) error {
|
||||||
}
|
}
|
||||||
for _, v := range args {
|
for _, v := range args {
|
||||||
if !stringInSlice(v, validArgs) {
|
if !stringInSlice(v, validArgs) {
|
||||||
return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
|
return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.SuggestFunc()(args[0]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
command.go
18
command.go
|
@ -180,6 +180,8 @@ type Command struct {
|
||||||
helpCommand *Command
|
helpCommand *Command
|
||||||
// helpCommandGroupID is the group id for the helpCommand
|
// helpCommandGroupID is the group id for the helpCommand
|
||||||
helpCommandGroupID string
|
helpCommandGroupID string
|
||||||
|
// suggestFunc is suggest func defined by the user.
|
||||||
|
suggestFunc func(string) string
|
||||||
|
|
||||||
// completionCommandGroupID is the group id for the completion command
|
// completionCommandGroupID is the group id for the completion command
|
||||||
completionCommandGroupID string
|
completionCommandGroupID string
|
||||||
|
@ -340,6 +342,10 @@ func (c *Command) SetHelpCommandGroupID(groupID string) {
|
||||||
c.helpCommandGroupID = groupID
|
c.helpCommandGroupID = groupID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Command) SetSuggestFunc(f func(string) string) {
|
||||||
|
c.suggestFunc = f
|
||||||
|
}
|
||||||
|
|
||||||
// SetCompletionCommandGroupID sets the group id of the completion command.
|
// SetCompletionCommandGroupID sets the group id of the completion command.
|
||||||
func (c *Command) SetCompletionCommandGroupID(groupID string) {
|
func (c *Command) SetCompletionCommandGroupID(groupID string) {
|
||||||
// completionCommandGroupID is used if no completion command is defined by the user
|
// completionCommandGroupID is used if no completion command is defined by the user
|
||||||
|
@ -477,6 +483,18 @@ func (c *Command) Help() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SuggestFunc returns either the function set by SetSuggestFunc for this command
|
||||||
|
// or a parent, or it returns a function with default suggestion behavior.
|
||||||
|
func (c *Command) SuggestFunc() func(string) string {
|
||||||
|
if c.suggestFunc != nil && !c.DisableSuggestions {
|
||||||
|
return c.suggestFunc
|
||||||
|
}
|
||||||
|
if c.HasParent() {
|
||||||
|
return c.Parent().SuggestFunc()
|
||||||
|
}
|
||||||
|
return c.findSuggestions
|
||||||
|
}
|
||||||
|
|
||||||
// UsageString returns usage string.
|
// UsageString returns usage string.
|
||||||
func (c *Command) UsageString() string {
|
func (c *Command) UsageString() string {
|
||||||
// Storing normal writers
|
// Storing normal writers
|
||||||
|
|
|
@ -1393,6 +1393,48 @@ func TestSuggestions(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCustomSuggestions(t *testing.T) {
|
||||||
|
templateWithCustomSuggestions := "Error: unknown command \"%s\" for \"root\"\nSome custom suggestion.\n\nRun 'root --help' for usage.\n"
|
||||||
|
templateWithDefaultSuggestions := "Error: unknown command \"%s\" for \"root\"\n\nDid you mean this?\n\t%s\n\nRun 'root --help' for usage.\n"
|
||||||
|
templateWithoutSuggestions := "Error: unknown command \"%s\" for \"root\"\nRun 'root --help' for usage.\n"
|
||||||
|
|
||||||
|
for typo, suggestion := range map[string]string{"time": "times", "timse": "times"} {
|
||||||
|
for _, suggestionsDisabled := range []bool{true, false} {
|
||||||
|
for _, setCustomSuggest := range []bool{true, false} {
|
||||||
|
rootCmd := &Command{Use: "root", Run: emptyRun}
|
||||||
|
timesCmd := &Command{
|
||||||
|
Use: "times",
|
||||||
|
Run: emptyRun,
|
||||||
|
}
|
||||||
|
rootCmd.AddCommand(timesCmd)
|
||||||
|
|
||||||
|
rootCmd.DisableSuggestions = suggestionsDisabled
|
||||||
|
|
||||||
|
if setCustomSuggest {
|
||||||
|
rootCmd.SetSuggestFunc(func(a string) string {
|
||||||
|
return "\nSome custom suggestion.\n"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var expected string
|
||||||
|
if suggestionsDisabled {
|
||||||
|
expected = fmt.Sprintf(templateWithoutSuggestions, typo)
|
||||||
|
} else if setCustomSuggest {
|
||||||
|
expected = fmt.Sprintf(templateWithCustomSuggestions, typo)
|
||||||
|
} else {
|
||||||
|
expected = fmt.Sprintf(templateWithDefaultSuggestions, typo, suggestion)
|
||||||
|
}
|
||||||
|
|
||||||
|
output, _ := executeCommand(rootCmd, typo)
|
||||||
|
|
||||||
|
if output != expected {
|
||||||
|
t.Errorf("Unexpected response.\nExpected:\n %q\nGot:\n %q\n", expected, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCaseInsensitive(t *testing.T) {
|
func TestCaseInsensitive(t *testing.T) {
|
||||||
rootCmd := &Command{Use: "root", Run: emptyRun}
|
rootCmd := &Command{Use: "root", Run: emptyRun}
|
||||||
childCmd := &Command{Use: "child", Run: emptyRun, Aliases: []string{"alternative"}}
|
childCmd := &Command{Use: "child", Run: emptyRun, Aliases: []string{"alternative"}}
|
||||||
|
|
Loading…
Reference in a new issue