diff --git a/commands/inspect.go b/commands/inspect.go index 88cc0343..5d222237 100644 --- a/commands/inspect.go +++ b/commands/inspect.go @@ -113,7 +113,7 @@ func inspectCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runInspect(dockerCli, options) }, - ValidArgsFunction: completion.Disable, + ValidArgsFunction: completion.BuilderNames(dockerCli), } flags := cmd.Flags() diff --git a/commands/rm.go b/commands/rm.go index be19785b..9f30d6b5 100644 --- a/commands/rm.go +++ b/commands/rm.go @@ -93,7 +93,7 @@ func rmCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runRm(dockerCli, options) }, - ValidArgsFunction: completion.Disable, + ValidArgsFunction: completion.BuilderNames(dockerCli), } flags := cmd.Flags() diff --git a/commands/root.go b/commands/root.go index a84a9330..6ea1147d 100644 --- a/commands/root.go +++ b/commands/root.go @@ -5,6 +5,7 @@ import ( imagetoolscmd "github.com/docker/buildx/commands/imagetools" "github.com/docker/buildx/controller/remote" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/util/logutil" "github.com/docker/cli-docs-tool/annotation" "github.com/docker/cli/cli" @@ -93,6 +94,11 @@ func addCommands(cmd *cobra.Command, dockerCli command.Cli) { if isExperimental() { remote.AddControllerCommands(cmd, dockerCli) } + + cmd.RegisterFlagCompletionFunc( //nolint:errcheck + "builder", + completion.BuilderNames(dockerCli), + ) } func rootFlags(options *rootOptions, flags *pflag.FlagSet) { diff --git a/commands/stop.go b/commands/stop.go index 4dc1783b..2af78c89 100644 --- a/commands/stop.go +++ b/commands/stop.go @@ -47,7 +47,7 @@ func stopCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runStop(dockerCli, options) }, - ValidArgsFunction: completion.Disable, + ValidArgsFunction: completion.BuilderNames(dockerCli), } return cmd diff --git a/commands/use.go b/commands/use.go index 320db678..cc5cfe0e 100644 --- a/commands/use.go +++ b/commands/use.go @@ -79,7 +79,7 @@ func useCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runUse(dockerCli, options) }, - ValidArgsFunction: completion.Disable, + ValidArgsFunction: completion.BuilderNames(dockerCli), } flags := cmd.Flags() diff --git a/util/cobrautil/completion/completion.go b/util/cobrautil/completion/completion.go index bd8c81aa..928be174 100644 --- a/util/cobrautil/completion/completion.go +++ b/util/cobrautil/completion/completion.go @@ -4,6 +4,9 @@ import ( "strings" "github.com/docker/buildx/bake" + "github.com/docker/buildx/builder" + "github.com/docker/buildx/store/storeutil" + "github.com/docker/cli/cli/command" "github.com/spf13/cobra" ) @@ -36,3 +39,24 @@ func BakeTargets(files []string) ValidArgsFn { return filtered, cobra.ShellCompDirectiveNoFileComp } } + +func BuilderNames(dockerCli command.Cli) ValidArgsFn { + return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + txn, release, err := storeutil.GetStore(dockerCli) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + defer release() + builders, err := builder.GetBuilders(dockerCli, txn) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var filtered []string + for _, b := range builders { + if toComplete == "" || strings.HasPrefix(b.Name, toComplete) { + filtered = append(filtered, b.Name) + } + } + return filtered, cobra.ShellCompDirectiveNoFileComp + } +}