From 467fcfe4bd7cdce792b60ecbe766d9f1ba7dc3ee Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 10 Sep 2025 10:14:30 +0200 Subject: [PATCH] cli/command/plugin: add completion for plugin subcommands Signed-off-by: Sebastiaan van Stijn --- cli/command/plugin/completion.go | 45 ++++++++++++++++++++++++++++++++ cli/command/plugin/create.go | 2 +- cli/command/plugin/disable.go | 1 + cli/command/plugin/enable.go | 1 + cli/command/plugin/inspect.go | 1 + cli/command/plugin/install.go | 1 + cli/command/plugin/push.go | 1 + cli/command/plugin/remove.go | 1 + cli/command/plugin/set.go | 1 + cli/command/plugin/upgrade.go | 1 + 10 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 cli/command/plugin/completion.go diff --git a/cli/command/plugin/completion.go b/cli/command/plugin/completion.go new file mode 100644 index 000000000..591c3b182 --- /dev/null +++ b/cli/command/plugin/completion.go @@ -0,0 +1,45 @@ +package plugin + +import ( + "github.com/docker/cli/cli/command/completion" + "github.com/moby/moby/api/types/filters" + "github.com/spf13/cobra" +) + +type pluginState string + +const ( + stateAny pluginState = "" + stateEnabled pluginState = "enabled" + stateDisabled pluginState = "disabled" +) + +// completeNames offers completion for plugin names in the given state. +// The state argument can be one of: +// +// - "all": all plugins +// - "enabled": all enabled plugins +// - "disabled": all disabled plugins +func completeNames(dockerCLI completion.APIClientProvider, state pluginState) cobra.CompletionFunc { + return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + f := filters.NewArgs() + switch state { + case stateEnabled: + f.Add("enabled", "true") + case stateDisabled: + f.Add("enabled", "false") + case stateAny: + // no filter + } + + list, err := dockerCLI.Client().PluginList(cmd.Context(), f) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var names []string + for _, v := range list { + names = append(names, v.Name) + } + return names, cobra.ShellCompDirectiveNoFileComp + } +} diff --git a/cli/command/plugin/create.go b/cli/command/plugin/create.go index 90ee99d31..ebcffced4 100644 --- a/cli/command/plugin/create.go +++ b/cli/command/plugin/create.go @@ -76,7 +76,7 @@ func newCreateCommand(dockerCLI command.Cli) *cobra.Command { options.context = args[1] return runCreate(cmd.Context(), dockerCLI, options) }, - ValidArgsFunction: cobra.NoFileCompletions, + ValidArgsFunction: cobra.NoFileCompletions, // TODO(thaJeztah): should provide "directory" completion for the second arg DisableFlagsInUseLine: true, } diff --git a/cli/command/plugin/disable.go b/cli/command/plugin/disable.go index b340c9217..7e7b5398c 100644 --- a/cli/command/plugin/disable.go +++ b/cli/command/plugin/disable.go @@ -24,6 +24,7 @@ func newDisableCommand(dockerCLI command.Cli) *cobra.Command { _, _ = fmt.Fprintln(dockerCLI.Out(), name) return nil }, + ValidArgsFunction: completeNames(dockerCLI, stateEnabled), DisableFlagsInUseLine: true, } diff --git a/cli/command/plugin/enable.go b/cli/command/plugin/enable.go index ac61ba2c8..19622d81e 100644 --- a/cli/command/plugin/enable.go +++ b/cli/command/plugin/enable.go @@ -25,6 +25,7 @@ func newEnableCommand(dockerCLI command.Cli) *cobra.Command { _, _ = fmt.Fprintln(dockerCLI.Out(), name) return nil }, + ValidArgsFunction: completeNames(dockerCLI, stateDisabled), DisableFlagsInUseLine: true, } diff --git a/cli/command/plugin/inspect.go b/cli/command/plugin/inspect.go index f93a3cdfc..9b166ac00 100644 --- a/cli/command/plugin/inspect.go +++ b/cli/command/plugin/inspect.go @@ -29,6 +29,7 @@ func newInspectCommand(dockerCLI command.Cli) *cobra.Command { opts.pluginNames = args return runInspect(cmd.Context(), dockerCLI, opts) }, + ValidArgsFunction: completeNames(dockerCLI, stateAny), DisableFlagsInUseLine: true, } diff --git a/cli/command/plugin/install.go b/cli/command/plugin/install.go index 21ed74782..926074e93 100644 --- a/cli/command/plugin/install.go +++ b/cli/command/plugin/install.go @@ -36,6 +36,7 @@ func newInstallCommand(dockerCLI command.Cli) *cobra.Command { } return runInstall(cmd.Context(), dockerCLI, options) }, + ValidArgsFunction: cobra.NoFileCompletions, DisableFlagsInUseLine: true, } diff --git a/cli/command/plugin/push.go b/cli/command/plugin/push.go index f990b9ecc..5f1349a90 100644 --- a/cli/command/plugin/push.go +++ b/cli/command/plugin/push.go @@ -20,6 +20,7 @@ func newPushCommand(dockerCLI command.Cli) *cobra.Command { name := args[0] return runPush(cmd.Context(), dockerCLI, name) }, + ValidArgsFunction: completeNames(dockerCLI, stateAny), DisableFlagsInUseLine: true, } diff --git a/cli/command/plugin/remove.go b/cli/command/plugin/remove.go index 610844f2b..bf91e6d83 100644 --- a/cli/command/plugin/remove.go +++ b/cli/command/plugin/remove.go @@ -29,6 +29,7 @@ func newRemoveCommand(dockerCLI command.Cli) *cobra.Command { opts.plugins = args return runRemove(cmd.Context(), dockerCLI, &opts) }, + ValidArgsFunction: completeNames(dockerCLI, stateAny), DisableFlagsInUseLine: true, } diff --git a/cli/command/plugin/set.go b/cli/command/plugin/set.go index 231da9a66..957e05f0a 100644 --- a/cli/command/plugin/set.go +++ b/cli/command/plugin/set.go @@ -14,6 +14,7 @@ func newSetCommand(dockerCLI command.Cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { return dockerCLI.Client().PluginSet(cmd.Context(), args[0], args[1:]) }, + ValidArgsFunction: completeNames(dockerCLI, stateAny), // TODO(thaJeztah): should only complete for the first arg DisableFlagsInUseLine: true, } } diff --git a/cli/command/plugin/upgrade.go b/cli/command/plugin/upgrade.go index 1fddf7913..2024dfb4f 100644 --- a/cli/command/plugin/upgrade.go +++ b/cli/command/plugin/upgrade.go @@ -27,6 +27,7 @@ func newUpgradeCommand(dockerCLI command.Cli) *cobra.Command { return runUpgrade(cmd.Context(), dockerCLI, options) }, Annotations: map[string]string{"version": "1.26"}, + ValidArgsFunction: completeNames(dockerCLI, stateAny), // TODO(thaJeztah): should only complete for the first arg DisableFlagsInUseLine: true, }