Skip to content

Commit 1d02486

Browse files
committed
cli/command/container: add shell completion for docker rm --link
When linking containers through legacy links, a container can get multiple names; its own name, and a name for each link it's providing: # create two containers with links between them docker run -d --name one nginx:alpine docker run -d --name two --link one:link1 --link one:link2 --link one:link3 nginx:alpine docker rm --link <tab> two/link1 two/link2 two/link3 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent 7886b31 commit 1d02486

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

cli/command/container/completion.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,35 @@ func completeLink(dockerCLI completion.APIClientProvider) cobra.CompletionFunc {
182182
}
183183
}
184184

185+
// completeLinks implements shell completion for the `--link` option of `rm --link`.
186+
//
187+
// It contacts the API to get names of legacy links on containers.
188+
// In case of an error, an empty list is returned.
189+
func completeLinks(dockerCLI completion.APIClientProvider) cobra.CompletionFunc {
190+
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
191+
res, err := dockerCLI.Client().ContainerList(cmd.Context(), client.ContainerListOptions{
192+
All: true,
193+
})
194+
if err != nil {
195+
return nil, cobra.ShellCompDirectiveError
196+
}
197+
var names []string
198+
for _, ctr := range res.Items {
199+
if len(ctr.Names) <= 1 {
200+
// Container has no links names.
201+
continue
202+
}
203+
for _, n := range ctr.Names {
204+
// Skip legacy link names: "/linked-container/link-name"
205+
if len(n) > 1 && strings.IndexByte(n[1:], '/') != -1 {
206+
names = append(names, strings.TrimPrefix(n, "/"))
207+
}
208+
}
209+
}
210+
return names, cobra.ShellCompDirectiveNoFileComp
211+
}
212+
}
213+
185214
// completeLogDriver implements shell completion for the `--log-driver` option of `run` and `create`.
186215
// The log drivers are collected from a call to the Info endpoint with a fallback to a hard-coded list
187216
// of the build-in log drivers.

cli/command/container/rm.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ type rmOptions struct {
2727
func newRmCommand(dockerCLI command.Cli) *cobra.Command {
2828
var opts rmOptions
2929

30+
completeLinkNames := completeLinks(dockerCLI)
31+
completeNames := completion.ContainerNames(dockerCLI, true, func(ctr container.Summary) bool {
32+
return opts.force || ctr.State == container.StateExited || ctr.State == container.StateCreated
33+
})
34+
3035
cmd := &cobra.Command{
3136
Use: "rm [OPTIONS] CONTAINER [CONTAINER...]",
3237
Short: "Remove one or more containers",
@@ -38,9 +43,13 @@ func newRmCommand(dockerCLI command.Cli) *cobra.Command {
3843
Annotations: map[string]string{
3944
"aliases": "docker container rm, docker container remove, docker rm",
4045
},
41-
ValidArgsFunction: completion.ContainerNames(dockerCLI, true, func(ctr container.Summary) bool {
42-
return opts.force || ctr.State == container.StateExited || ctr.State == container.StateCreated
43-
}),
46+
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
47+
if opts.rmLink {
48+
// "--link" (remove link) is set; provide link names instead of container (primary) names.
49+
return completeLinkNames(cmd, args, toComplete)
50+
}
51+
return completeNames(cmd, args, toComplete)
52+
},
4453
DisableFlagsInUseLine: true,
4554
}
4655

0 commit comments

Comments
 (0)