Skip to content

Commit

Permalink
Merge pull request #1635 from dearchap/issue_1215
Browse files Browse the repository at this point in the history
Feature:(issue_1215) Allow calling commands by shorthand
  • Loading branch information
dearchap authored Jan 9, 2023
2 parents c6fc998 + c243bd4 commit 2550242
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 4 deletions.
10 changes: 10 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ type App struct {
SkipFlagParsing bool
// Flag exclusion group
MutuallyExclusiveFlags []MutuallyExclusiveFlags
// Use longest prefix match for commands
PrefixMatchCommands bool
// Custom suggest command for matching
SuggestCommandFunc SuggestCommandFunc

didSetup bool

Expand Down Expand Up @@ -201,6 +205,11 @@ func (a *App) Setup() {
a.appendFlag(VersionFlag)
}

if a.PrefixMatchCommands {
if a.SuggestCommandFunc == nil {
a.SuggestCommandFunc = suggestCommand
}
}
if a.EnableShellCompletion {
if a.ShellCompletionCommandName != "" {
completionCommand.Name = a.ShellCompletionCommandName
Expand Down Expand Up @@ -258,6 +267,7 @@ func (a *App) newRootCommand() *Command {
SkipFlagParsing: a.SkipFlagParsing,
isRoot: true,
MutuallyExclusiveFlags: a.MutuallyExclusiveFlags,
PrefixMatchCommands: a.PrefixMatchCommands,
}
}

Expand Down
86 changes: 86 additions & 0 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3295,3 +3295,89 @@ func TestFlagDuplicates(t *testing.T) {
})
}
}

func TestShorthandCommand(t *testing.T) {

af := func(p *int) ActionFunc {
return func(ctx *Context) error {
*p = *p + 1
return nil
}
}

var cmd1, cmd2 int

a := &App{
PrefixMatchCommands: true,
Commands: []*Command{
{
Name: "cthdisd",
Aliases: []string{"cth"},
Action: af(&cmd1),
},
{
Name: "cthertoop",
Aliases: []string{"cer"},
Action: af(&cmd2),
},
},
}

err := a.Run([]string{"foo", "cth"})
if err != nil {
t.Error(err)
}

if cmd1 != 1 && cmd2 != 0 {
t.Errorf("Expected command1 to be trigerred once but didnt %d %d", cmd1, cmd2)
}

cmd1 = 0
cmd2 = 0

err = a.Run([]string{"foo", "cthd"})
if err != nil {
t.Error(err)
}

if cmd1 != 1 && cmd2 != 0 {
t.Errorf("Expected command1 to be trigerred once but didnt %d %d", cmd1, cmd2)
}

cmd1 = 0
cmd2 = 0

err = a.Run([]string{"foo", "cthe"})
if err != nil {
t.Error(err)
}

if cmd1 != 1 && cmd2 != 0 {
t.Errorf("Expected command1 to be trigerred once but didnt %d %d", cmd1, cmd2)
}

cmd1 = 0
cmd2 = 0

err = a.Run([]string{"foo", "cthert"})
if err != nil {
t.Error(err)
}

if cmd1 != 0 && cmd2 != 1 {
t.Errorf("Expected command1 to be trigerred once but didnt %d %d", cmd1, cmd2)
}

cmd1 = 0
cmd2 = 0

err = a.Run([]string{"foo", "cthet"})
if err != nil {
t.Error(err)
}

if cmd1 != 0 && cmd2 != 1 {
t.Errorf("Expected command1 to be trigerred once but didnt %d %d", cmd1, cmd2)
}

}
6 changes: 6 additions & 0 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ type Command struct {
// render custom help text by setting this variable.
CustomHelpTemplate string

// Use longest prefix match for commands
PrefixMatchCommands bool

// categories contains the categorized commands and is populated on app startup
categories CommandCategories

Expand Down Expand Up @@ -236,6 +239,9 @@ func (c *Command) Run(cCtx *Context, arguments ...string) (err error) {
args := cCtx.Args()
if args.Present() {
name := args.First()
if cCtx.App.SuggestCommandFunc != nil {
name = cCtx.App.SuggestCommandFunc(c.Commands, name)
}
cmd = c.Command(name)
if cmd == nil {
hasDefault := cCtx.App.DefaultCommand != ""
Expand Down
7 changes: 7 additions & 0 deletions godoc-current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ type App struct {
SkipFlagParsing bool
// Flag exclusion group
MutuallyExclusiveFlags []MutuallyExclusiveFlags
// Use longest prefix match for commands
PrefixMatchCommands bool
// Custom suggest command for matching
SuggestCommandFunc SuggestCommandFunc

// Has unexported fields.
}
Expand Down Expand Up @@ -475,6 +479,9 @@ type Command struct {
// render custom help text by setting this variable.
CustomHelpTemplate string

// Use longest prefix match for commands
PrefixMatchCommands bool

// Flag exclusion group
MutuallyExclusiveFlags []MutuallyExclusiveFlags
// Has unexported fields.
Expand Down
4 changes: 1 addition & 3 deletions suggestions.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package cli

import (
"fmt"

"github.com/xrash/smetrics"
)

Expand Down Expand Up @@ -68,5 +66,5 @@ func suggestCommand(commands []*Command, provided string) (suggestion string) {
}
}

return fmt.Sprintf(SuggestDidYouMeanTemplate, suggestion)
return suggestion
}
4 changes: 3 additions & 1 deletion suggestions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,15 @@ func TestSuggestCommand(t *testing.T) {
{"conf", "config"},
{"i", "i"},
{"information", "info"},
{"inf", "info"},
{"con", "config"},
{"not-existing", "info"},
} {
// When
res := suggestCommand(app.Commands, testCase.provided)

// Then
expect(t, res, fmt.Sprintf(SuggestDidYouMeanTemplate, testCase.expected))
expect(t, res, testCase.expected)
}
}

Expand Down
7 changes: 7 additions & 0 deletions testdata/godoc-v3.x.txt
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ type App struct {
SkipFlagParsing bool
// Flag exclusion group
MutuallyExclusiveFlags []MutuallyExclusiveFlags
// Use longest prefix match for commands
PrefixMatchCommands bool
// Custom suggest command for matching
SuggestCommandFunc SuggestCommandFunc

// Has unexported fields.
}
Expand Down Expand Up @@ -475,6 +479,9 @@ type Command struct {
// render custom help text by setting this variable.
CustomHelpTemplate string

// Use longest prefix match for commands
PrefixMatchCommands bool

// Flag exclusion group
MutuallyExclusiveFlags []MutuallyExclusiveFlags
// Has unexported fields.
Expand Down

0 comments on commit 2550242

Please sign in to comment.