cli: print full command as aliases in usage output

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>
This commit is contained in:
Sebastiaan van Stijn 2022-06-28 10:17:50 +02:00
parent b496125aa7
commit 2d88c896bc
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
3 changed files with 26 additions and 2 deletions

View File

@ -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)
@ -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 {
@ -398,7 +414,7 @@ EXPERIMENTAL:
{{- if gt .Aliases 0}}
Aliases:
{{.NameAndAliases}}
{{ commandAliases . }}
{{- end}}
{{- if .HasExample}}

View File

@ -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"}

View File

@ -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