From 8a02cf87170522e43cf4218814bf449e2d36cc49 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 9 Apr 2023 21:20:18 +0200 Subject: [PATCH 1/4] cli: set default completion Signed-off-by: CrazyMax --- commands/build.go | 2 ++ commands/create.go | 2 ++ commands/diskusage.go | 2 ++ commands/imagetools/create.go | 2 ++ commands/imagetools/inspect.go | 2 ++ commands/imagetools/root.go | 6 ++++-- commands/inspect.go | 2 ++ commands/install.go | 4 +++- commands/ls.go | 2 ++ commands/prune.go | 2 ++ commands/rm.go | 2 ++ commands/root.go | 3 +++ commands/stop.go | 2 ++ commands/uninstall.go | 4 +++- commands/use.go | 2 ++ commands/version.go | 2 ++ util/cobrautil/completion/completion.go | 12 ++++++++++++ 17 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 util/cobrautil/completion/completion.go diff --git a/commands/build.go b/commands/build.go index 64545cfd..1f46582b 100644 --- a/commands/build.go +++ b/commands/build.go @@ -23,6 +23,7 @@ import ( "github.com/docker/buildx/store" "github.com/docker/buildx/store/storeutil" "github.com/docker/buildx/util/buildflags" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/util/ioset" "github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/tracing" @@ -253,6 +254,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runBuild(dockerCli, options) }, + ValidArgsFunction: completion.Disable, } var platformsDefault []string diff --git a/commands/create.go b/commands/create.go index 1870e39d..d9e33038 100644 --- a/commands/create.go +++ b/commands/create.go @@ -17,6 +17,7 @@ import ( "github.com/docker/buildx/store" "github.com/docker/buildx/store/storeutil" "github.com/docker/buildx/util/cobrautil" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/util/confutil" "github.com/docker/buildx/util/dockerutil" "github.com/docker/cli/cli" @@ -319,6 +320,7 @@ func createCmd(dockerCli command.Cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { return runCreate(dockerCli, options, args) }, + ValidArgsFunction: completion.Disable, } flags := cmd.Flags() diff --git a/commands/diskusage.go b/commands/diskusage.go index d4bd7dda..87ad8f8d 100644 --- a/commands/diskusage.go +++ b/commands/diskusage.go @@ -9,6 +9,7 @@ import ( "time" "github.com/docker/buildx/builder" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/opts" @@ -115,6 +116,7 @@ func duCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { options.builder = rootOpts.builder return runDiskUsage(dockerCli, options) }, + ValidArgsFunction: completion.Disable, } flags := cmd.Flags() diff --git a/commands/imagetools/create.go b/commands/imagetools/create.go index 84c07aaf..15ecd889 100644 --- a/commands/imagetools/create.go +++ b/commands/imagetools/create.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/docker/buildx/builder" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/util/imagetools" "github.com/docker/buildx/util/progress" "github.com/docker/cli/cli/command" @@ -273,6 +274,7 @@ func createCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command { options.builder = *opts.Builder return runCreate(dockerCli, options, args) }, + ValidArgsFunction: completion.Disable, } flags := cmd.Flags() diff --git a/commands/imagetools/inspect.go b/commands/imagetools/inspect.go index 68fed667..ad1e6438 100644 --- a/commands/imagetools/inspect.go +++ b/commands/imagetools/inspect.go @@ -2,6 +2,7 @@ package commands import ( "github.com/docker/buildx/builder" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/util/imagetools" "github.com/docker/cli-docs-tool/annotation" "github.com/docker/cli/cli" @@ -52,6 +53,7 @@ func inspectCmd(dockerCli command.Cli, rootOpts RootOptions) *cobra.Command { options.builder = *rootOpts.Builder return runInspect(dockerCli, options, args[0]) }, + ValidArgsFunction: completion.Disable, } flags := cmd.Flags() diff --git a/commands/imagetools/root.go b/commands/imagetools/root.go index 6c6ede2f..f5ec0160 100644 --- a/commands/imagetools/root.go +++ b/commands/imagetools/root.go @@ -1,6 +1,7 @@ package commands import ( + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" ) @@ -11,8 +12,9 @@ type RootOptions struct { func RootCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command { cmd := &cobra.Command{ - Use: "imagetools", - Short: "Commands to work on images in registry", + Use: "imagetools", + Short: "Commands to work on images in registry", + ValidArgsFunction: completion.Disable, } cmd.AddCommand( diff --git a/commands/inspect.go b/commands/inspect.go index fc4530b7..88cc0343 100644 --- a/commands/inspect.go +++ b/commands/inspect.go @@ -9,6 +9,7 @@ import ( "time" "github.com/docker/buildx/builder" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/util/platformutil" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -112,6 +113,7 @@ func inspectCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runInspect(dockerCli, options) }, + ValidArgsFunction: completion.Disable, } flags := cmd.Flags() diff --git a/commands/install.go b/commands/install.go index e760a749..9c400dfe 100644 --- a/commands/install.go +++ b/commands/install.go @@ -4,6 +4,7 @@ import ( "os" "github.com/docker/buildx/util/cobrautil" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/config" @@ -46,7 +47,8 @@ func installCmd(dockerCli command.Cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { return runInstall(dockerCli, options) }, - Hidden: true, + Hidden: true, + ValidArgsFunction: completion.Disable, } // hide builder persistent flag for this command diff --git a/commands/ls.go b/commands/ls.go index 428de1b6..66eae51e 100644 --- a/commands/ls.go +++ b/commands/ls.go @@ -11,6 +11,7 @@ import ( "github.com/docker/buildx/builder" "github.com/docker/buildx/store/storeutil" "github.com/docker/buildx/util/cobrautil" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/util/platformutil" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -126,6 +127,7 @@ func lsCmd(dockerCli command.Cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { return runLs(dockerCli, options) }, + ValidArgsFunction: completion.Disable, } // hide builder persistent flag for this command diff --git a/commands/prune.go b/commands/prune.go index 653ffd84..67df4b2a 100644 --- a/commands/prune.go +++ b/commands/prune.go @@ -8,6 +8,7 @@ import ( "time" "github.com/docker/buildx/builder" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/opts" @@ -139,6 +140,7 @@ func pruneCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { options.builder = rootOpts.builder return runPrune(dockerCli, options) }, + ValidArgsFunction: completion.Disable, } flags := cmd.Flags() diff --git a/commands/rm.go b/commands/rm.go index fcd4b5e9..be19785b 100644 --- a/commands/rm.go +++ b/commands/rm.go @@ -8,6 +8,7 @@ import ( "github.com/docker/buildx/builder" "github.com/docker/buildx/store" "github.com/docker/buildx/store/storeutil" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/moby/buildkit/util/appcontext" @@ -92,6 +93,7 @@ func rmCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runRm(dockerCli, options) }, + ValidArgsFunction: completion.Disable, } flags := cmd.Flags() diff --git a/commands/root.go b/commands/root.go index eda2c1e5..a84a9330 100644 --- a/commands/root.go +++ b/commands/root.go @@ -23,6 +23,9 @@ func NewRootCmd(name string, isPlugin bool, dockerCli command.Cli) *cobra.Comman Annotations: map[string]string{ annotation.CodeDelimiter: `"`, }, + CompletionOptions: cobra.CompletionOptions{ + HiddenDefaultCmd: true, + }, } if isPlugin { cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { diff --git a/commands/stop.go b/commands/stop.go index cebf1c2a..4dc1783b 100644 --- a/commands/stop.go +++ b/commands/stop.go @@ -4,6 +4,7 @@ import ( "context" "github.com/docker/buildx/builder" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/moby/buildkit/util/appcontext" @@ -46,6 +47,7 @@ func stopCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runStop(dockerCli, options) }, + ValidArgsFunction: completion.Disable, } return cmd diff --git a/commands/uninstall.go b/commands/uninstall.go index f5b000eb..6bc6bf33 100644 --- a/commands/uninstall.go +++ b/commands/uninstall.go @@ -4,6 +4,7 @@ import ( "os" "github.com/docker/buildx/util/cobrautil" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/config" @@ -52,7 +53,8 @@ func uninstallCmd(dockerCli command.Cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { return runUninstall(dockerCli, options) }, - Hidden: true, + Hidden: true, + ValidArgsFunction: completion.Disable, } // hide builder persistent flag for this command diff --git a/commands/use.go b/commands/use.go index 7e52ce85..320db678 100644 --- a/commands/use.go +++ b/commands/use.go @@ -4,6 +4,7 @@ import ( "os" "github.com/docker/buildx/store/storeutil" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/util/dockerutil" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -78,6 +79,7 @@ func useCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runUse(dockerCli, options) }, + ValidArgsFunction: completion.Disable, } flags := cmd.Flags() diff --git a/commands/version.go b/commands/version.go index 91cfe136..b65cc4db 100644 --- a/commands/version.go +++ b/commands/version.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/docker/buildx/util/cobrautil" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/version" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -23,6 +24,7 @@ func versionCmd(dockerCli command.Cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { return runVersion(dockerCli) }, + ValidArgsFunction: completion.Disable, } // hide builder persistent flag for this command diff --git a/util/cobrautil/completion/completion.go b/util/cobrautil/completion/completion.go new file mode 100644 index 00000000..0a5c4dae --- /dev/null +++ b/util/cobrautil/completion/completion.go @@ -0,0 +1,12 @@ +package completion + +import ( + "github.com/spf13/cobra" +) + +// ValidArgsFn defines a completion func to be returned to fetch completion options +type ValidArgsFn func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) + +func Disable(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return nil, cobra.ShellCompDirectiveNoSpace +} From af011d6ca30534c0751617f70b980694f7fa7770 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Tue, 11 Apr 2023 11:34:40 +0200 Subject: [PATCH 2/4] bake: add completion to list targets Signed-off-by: CrazyMax --- bake/bake.go | 15 ++++++++++++++ commands/bake.go | 2 ++ util/cobrautil/completion/completion.go | 26 +++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/bake/bake.go b/bake/bake.go index e8073202..4b0a76a2 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -85,6 +85,21 @@ func ReadLocalFiles(names []string) ([]File, error) { return out, nil } +func ListTargets(files []File) ([]string, error) { + c, err := ParseFiles(files, nil) + if err != nil { + return nil, err + } + var targets []string + for _, g := range c.Groups { + targets = append(targets, g.Name) + } + for _, t := range c.Targets { + targets = append(targets, t.Name) + } + return dedupSlice(targets), nil +} + func ReadTargets(ctx context.Context, files []File, targets, overrides []string, defaults map[string]string) (map[string]*Target, map[string]*Group, error) { c, err := ParseFiles(files, defaults) if err != nil { diff --git a/commands/bake.go b/commands/bake.go index 4a33cd6e..94c8098f 100644 --- a/commands/bake.go +++ b/commands/bake.go @@ -11,6 +11,7 @@ import ( "github.com/docker/buildx/build" "github.com/docker/buildx/builder" "github.com/docker/buildx/util/buildflags" + "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/util/confutil" "github.com/docker/buildx/util/dockerutil" "github.com/docker/buildx/util/progress" @@ -230,6 +231,7 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { // Other common flags (noCache, pull and progress) are processed in runBake function. return runBake(dockerCli, args, options, cFlags) }, + ValidArgsFunction: completion.BakeTargets(options.files), } flags := cmd.Flags() diff --git a/util/cobrautil/completion/completion.go b/util/cobrautil/completion/completion.go index 0a5c4dae..bd8c81aa 100644 --- a/util/cobrautil/completion/completion.go +++ b/util/cobrautil/completion/completion.go @@ -1,6 +1,9 @@ package completion import ( + "strings" + + "github.com/docker/buildx/bake" "github.com/spf13/cobra" ) @@ -10,3 +13,26 @@ type ValidArgsFn func(cmd *cobra.Command, args []string, toComplete string) ([]s func Disable(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return nil, cobra.ShellCompDirectiveNoSpace } + +func BakeTargets(files []string) ValidArgsFn { + return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + f, err := bake.ReadLocalFiles(files) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + tgts, err := bake.ListTargets(f) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var filtered []string + if toComplete == "" { + return tgts, cobra.ShellCompDirectiveNoFileComp + } + for _, tgt := range tgts { + if strings.HasPrefix(tgt, toComplete) { + filtered = append(filtered, tgt) + } + } + return filtered, cobra.ShellCompDirectiveNoFileComp + } +} From 14b66817fbea4f9c9ef12f46a918617f42716de9 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Tue, 11 Apr 2023 11:35:50 +0200 Subject: [PATCH 3/4] build: add completion to list context folders Signed-off-by: CrazyMax --- commands/build.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/commands/build.go b/commands/build.go index 1f46582b..99723559 100644 --- a/commands/build.go +++ b/commands/build.go @@ -23,7 +23,6 @@ import ( "github.com/docker/buildx/store" "github.com/docker/buildx/store/storeutil" "github.com/docker/buildx/util/buildflags" - "github.com/docker/buildx/util/cobrautil/completion" "github.com/docker/buildx/util/ioset" "github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/tracing" @@ -254,7 +253,9 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runBuild(dockerCli, options) }, - ValidArgsFunction: completion.Disable, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return nil, cobra.ShellCompDirectiveFilterDirs + }, } var platformsDefault []string From a597266a52c078f83f5f8e434a56e8f6caa07f87 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Tue, 11 Apr 2023 11:45:59 +0200 Subject: [PATCH 4/4] cli: add completion to list builder names Signed-off-by: CrazyMax --- commands/inspect.go | 2 +- commands/rm.go | 2 +- commands/root.go | 6 ++++++ commands/stop.go | 2 +- commands/use.go | 2 +- util/cobrautil/completion/completion.go | 24 ++++++++++++++++++++++++ 6 files changed, 34 insertions(+), 4 deletions(-) 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 + } +}