Skip to content

Commit

Permalink
cli: print full command as aliases in usage output
Browse files Browse the repository at this point in the history
The default output for Cobra aliases only shows the subcommand as alias, which
is not very intuitive. This patch changes the output to print the full command
as it would be called by the user.

Note that there's still some improvements to be made; due to how aliases must be
set-up in Cobra, aliases at different "levels" are still not shown. So for example,
`docker ps --help` will not show `docker container ps` as alias, and vice-versa.
This will require additional changes, and can possibly be resolved using custom
metadata/annotations.

Before this patch:

    docker container ls --help

    Usage:  docker container ls [OPTIONS]

    List containers

    Aliases:
      ls, ps, list

After this patch:

    docker container ls --help

    Usage:  docker container ls [OPTIONS]

    List containers

    Aliases:
      docker container ls, docker container ps, docker container list

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
  • Loading branch information
thaJeztah committed Jun 28, 2022
1 parent b496125 commit 2d88c89
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
18 changes: 17 additions & 1 deletion cli/cobra.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func setupCommonRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *p
cobra.AddTemplateFunc("hasSwarmSubCommands", hasSwarmSubCommands)
cobra.AddTemplateFunc("hasInvalidPlugins", hasInvalidPlugins)
cobra.AddTemplateFunc("topCommands", topCommands)
cobra.AddTemplateFunc("commandAliases", commandAliases)
cobra.AddTemplateFunc("operationSubCommands", operationSubCommands)
cobra.AddTemplateFunc("managementSubCommands", managementSubCommands)
cobra.AddTemplateFunc("orchestratorSubCommands", orchestratorSubCommands)
Expand Down Expand Up @@ -258,6 +259,21 @@ func hasTopCommands(cmd *cobra.Command) bool {
return len(topCommands(cmd)) > 0
}

// commandAliases is a templating function to return aliases for the command,
// formatted as the full command as they're called (contrary to the default
// Aliases function, which only returns the subcommand).
func commandAliases(cmd *cobra.Command) string {
var parentPath string
if cmd.HasParent() {
parentPath = cmd.Parent().CommandPath() + " "
}
aliases := cmd.CommandPath()
for _, alias := range cmd.Aliases {
aliases += ", " + parentPath + alias
}
return aliases
}

func topCommands(cmd *cobra.Command) []*cobra.Command {
cmds := []*cobra.Command{}
if cmd.Parent() != nil {
Expand Down Expand Up @@ -398,7 +414,7 @@ EXPERIMENTAL:
{{- if gt .Aliases 0}}
Aliases:
{{.NameAndAliases}}
{{ commandAliases . }}
{{- end}}
{{- if .HasExample}}
Expand Down
8 changes: 8 additions & 0 deletions cli/cobra_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ func TestInvalidPlugin(t *testing.T) {
assert.DeepEqual(t, invalidPlugins(root), []*cobra.Command{sub1}, cmpopts.IgnoreUnexported(cobra.Command{}))
}

func TestCommandAliases(t *testing.T) {
root := &cobra.Command{Use: "root"}
sub := &cobra.Command{Use: "subcommand", Aliases: []string{"alias1", "alias2"}}
root.AddCommand(sub)

assert.Equal(t, commandAliases(sub), "root subcommand, root alias1, root alias2")
}

func TestDecoratedName(t *testing.T) {
root := &cobra.Command{Use: "root"}
topLevelCommand := &cobra.Command{Use: "pluginTopLevelCommand"}
Expand Down
2 changes: 1 addition & 1 deletion e2e/stack/testdata/stack-deploy-help.golden
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Usage: docker stack deploy [OPTIONS] STACK
Deploy a new stack or update an existing stack

Aliases:
deploy, up
docker stack deploy, docker stack up

Options:
-c, --compose-file strings Path to a Compose file, or "-" to read
Expand Down

0 comments on commit 2d88c89

Please sign in to comment.