Skip to content

Commit 5097367

Browse files
committed
cli: use custom annotation for aliases
Cobra allows for aliases to be defined for a command, but only allows these to be defined at the same level (for example, `docker image ls` as alias for `docker image list`). Our CLI has some commands that are available both as a top-level shorthand as well as `docker <object> <verb>` subcommands. For example, `docker ps` is a shorthand for `docker container ps` / `docker container ls`. This patch introduces a custom "aliases" annotation that can be used to print all available aliases for a command. While this requires these aliases to be defined manually, in practice the list of aliases rarely changes, so maintenance should be minimal. As a convention, we could consider the first command in this list to be the canonical command, so that we can use this information to add redirects in our documentation in future. Before this patch: docker images --help Usage: docker images [OPTIONS] [REPOSITORY[:TAG]] List images Options: -a, --all Show all images (default hides intermediate images) ... With this patch: docker images --help Usage: docker images [OPTIONS] [REPOSITORY[:TAG]] List images Aliases: docker image ls, docker image list, docker images Options: -a, --all Show all images (default hides intermediate images) ... Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent 2d88c89 commit 5097367

72 files changed

Lines changed: 212 additions & 1 deletion

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cli/cobra.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func setupCommonRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *p
3131
opts.Common.InstallFlags(flags)
3232

3333
cobra.AddTemplateFunc("add", func(a, b int) int { return a + b })
34+
cobra.AddTemplateFunc("hasAliases", hasAliases)
3435
cobra.AddTemplateFunc("hasSubCommands", hasSubCommands)
3536
cobra.AddTemplateFunc("hasTopCommands", hasTopCommands)
3637
cobra.AddTemplateFunc("hasManagementSubCommands", hasManagementSubCommands)
@@ -239,6 +240,10 @@ func isPlugin(cmd *cobra.Command) bool {
239240
return cmd.Annotations[pluginmanager.CommandAnnotationPlugin] == "true"
240241
}
241242

243+
func hasAliases(cmd *cobra.Command) bool {
244+
return len(cmd.Aliases) > 0 || cmd.Annotations["aliases"] != ""
245+
}
246+
242247
func hasSubCommands(cmd *cobra.Command) bool {
243248
return len(operationSubCommands(cmd)) > 0
244249
}
@@ -263,6 +268,9 @@ func hasTopCommands(cmd *cobra.Command) bool {
263268
// formatted as the full command as they're called (contrary to the default
264269
// Aliases function, which only returns the subcommand).
265270
func commandAliases(cmd *cobra.Command) string {
271+
if cmd.Annotations["aliases"] != "" {
272+
return cmd.Annotations["aliases"]
273+
}
266274
var parentPath string
267275
if cmd.HasParent() {
268276
parentPath = cmd.Parent().CommandPath() + " "
@@ -411,7 +419,7 @@ EXPERIMENTAL:
411419
https://docs.docker.com/go/experimental/
412420
413421
{{- end}}
414-
{{- if gt .Aliases 0}}
422+
{{- if hasAliases . }}
415423
416424
Aliases:
417425
{{ commandAliases . }}

cli/cobra_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,18 @@ func TestInvalidPlugin(t *testing.T) {
8181
func TestCommandAliases(t *testing.T) {
8282
root := &cobra.Command{Use: "root"}
8383
sub := &cobra.Command{Use: "subcommand", Aliases: []string{"alias1", "alias2"}}
84+
sub2 := &cobra.Command{Use: "subcommand2", Annotations: map[string]string{"aliases": "root foo, root bar"}}
8485
root.AddCommand(sub)
86+
root.AddCommand(sub2)
8587

88+
assert.Equal(t, hasAliases(sub), true)
8689
assert.Equal(t, commandAliases(sub), "root subcommand, root alias1, root alias2")
90+
assert.Equal(t, hasAliases(sub2), true)
91+
assert.Equal(t, commandAliases(sub2), "root foo, root bar")
92+
93+
sub.Annotations = map[string]string{"aliases": "custom alias, custom alias 2"}
94+
assert.Equal(t, hasAliases(sub), true)
95+
assert.Equal(t, commandAliases(sub), "custom alias, custom alias 2")
8796
}
8897

8998
func TestDecoratedName(t *testing.T) {

cli/command/container/attach.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
5555
opts.container = args[0]
5656
return runAttach(dockerCli, &opts)
5757
},
58+
Annotations: map[string]string{
59+
"aliases": "docker container attach, docker attach",
60+
},
5861
ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(container types.Container) bool {
5962
return container.State != "paused"
6063
}),

cli/command/container/commit.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ func NewCommitCommand(dockerCli command.Cli) *cobra.Command {
3737
}
3838
return runCommit(dockerCli, &options)
3939
},
40+
Annotations: map[string]string{
41+
"aliases": "docker container commit, docker commit",
42+
},
4043
ValidArgsFunction: completion.ContainerNames(dockerCli, false),
4144
}
4245

cli/command/container/cp.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ func NewCopyCommand(dockerCli command.Cli) *cobra.Command {
101101
}
102102
return runCopy(dockerCli, opts)
103103
},
104+
Annotations: map[string]string{
105+
"aliases": "docker container cp, docker cp",
106+
},
104107
}
105108

106109
flags := cmd.Flags()

cli/command/container/create.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ func NewCreateCommand(dockerCli command.Cli) *cobra.Command {
5757
}
5858
return runCreate(dockerCli, cmd.Flags(), &opts, copts)
5959
},
60+
Annotations: map[string]string{
61+
"aliases": "docker container create, docker create",
62+
},
6063
ValidArgsFunction: completion.ImageNames(dockerCli),
6164
}
6265

cli/command/container/diff.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ func NewDiffCommand(dockerCli command.Cli) *cobra.Command {
2727
opts.container = args[0]
2828
return runDiff(dockerCli, &opts)
2929
},
30+
Annotations: map[string]string{
31+
"aliases": "docker container diff, docker diff",
32+
},
3033
ValidArgsFunction: completion.ContainerNames(dockerCli, false),
3134
}
3235
}

cli/command/container/exec.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command {
5959
}),
6060
Annotations: map[string]string{
6161
"category-top": "2",
62+
"aliases": "docker container exec, docker exec",
6263
},
6364
}
6465

cli/command/container/export.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ func NewExportCommand(dockerCli command.Cli) *cobra.Command {
2828
opts.container = args[0]
2929
return runExport(dockerCli, opts)
3030
},
31+
Annotations: map[string]string{
32+
"aliases": "docker container export, docker export",
33+
},
3134
ValidArgsFunction: completion.ContainerNames(dockerCli, true),
3235
}
3336

cli/command/container/kill.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ func NewKillCommand(dockerCli command.Cli) *cobra.Command {
3030
opts.containers = args
3131
return runKill(dockerCli, &opts)
3232
},
33+
Annotations: map[string]string{
34+
"aliases": "docker container kill, docker kill",
35+
},
3336
ValidArgsFunction: completion.ContainerNames(dockerCli, false),
3437
}
3538

0 commit comments

Comments
 (0)