From a9329d3744ecb47911b8b71e95872a9ced760d9e Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sat, 11 Mar 2023 23:58:12 +0100 Subject: [PATCH 1/2] bake: add completion to list targets Signed-off-by: CrazyMax --- bake/bake.go | 15 ++++++++++++++ commands/bake.go | 2 ++ commands/build.go | 2 ++ commands/create.go | 1 + 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 | 3 ++- commands/ls.go | 1 + commands/prune.go | 2 ++ commands/rm.go | 2 ++ commands/root.go | 3 +++ commands/stop.go | 2 ++ commands/uninstall.go | 3 ++- commands/use.go | 2 ++ commands/version.go | 1 + util/cobrautil/completion.go | 38 ++++++++++++++++++++++++++++++++++ 19 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 util/cobrautil/completion.go diff --git a/bake/bake.go b/bake/bake.go index 1abf5f1bd45..aab1b076faa 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -84,6 +84,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 c7f1461e7ab..334fcf00bd4 100644 --- a/commands/bake.go +++ b/commands/bake.go @@ -12,6 +12,7 @@ import ( "github.com/docker/buildx/builder" controllerapi "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/util/buildflags" + "github.com/docker/buildx/util/cobrautil" "github.com/docker/buildx/util/confutil" "github.com/docker/buildx/util/dockerutil" "github.com/docker/buildx/util/progress" @@ -214,6 +215,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: cobrautil.CompleteBakeTargets(options.files), } flags := cmd.Flags() diff --git a/commands/build.go b/commands/build.go index d3fd4990a6d..aef01800b2e 100644 --- a/commands/build.go +++ b/commands/build.go @@ -22,6 +22,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" "github.com/docker/buildx/util/ioset" "github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/tracing" @@ -235,6 +236,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runBuild(dockerCli, options) }, + ValidArgsFunction: cobrautil.NoCompletion, } var platformsDefault []string diff --git a/commands/create.go b/commands/create.go index 35f7ba5d0eb..1aeaaa14225 100644 --- a/commands/create.go +++ b/commands/create.go @@ -309,6 +309,7 @@ func createCmd(dockerCli command.Cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { return runCreate(dockerCli, options, args) }, + ValidArgsFunction: cobrautil.NoCompletion, } flags := cmd.Flags() diff --git a/commands/diskusage.go b/commands/diskusage.go index d4bd7ddad71..e0cea96683e 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" "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: cobrautil.NoCompletion, } flags := cmd.Flags() diff --git a/commands/imagetools/create.go b/commands/imagetools/create.go index 84c07aaf75f..de975616ddf 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" "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: cobrautil.NoCompletion, } flags := cmd.Flags() diff --git a/commands/imagetools/inspect.go b/commands/imagetools/inspect.go index 68fed6676e3..702e2eda2af 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" "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: cobrautil.NoCompletion, } flags := cmd.Flags() diff --git a/commands/imagetools/root.go b/commands/imagetools/root.go index 6c6ede2f52c..770c484c606 100644 --- a/commands/imagetools/root.go +++ b/commands/imagetools/root.go @@ -1,6 +1,7 @@ package commands import ( + "github.com/docker/buildx/util/cobrautil" "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: cobrautil.NoCompletion, } cmd.AddCommand( diff --git a/commands/inspect.go b/commands/inspect.go index fc4530b70d2..7016bfaa698 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" "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: cobrautil.NoCompletion, } flags := cmd.Flags() diff --git a/commands/install.go b/commands/install.go index e760a7491db..91b6ff3597e 100644 --- a/commands/install.go +++ b/commands/install.go @@ -46,7 +46,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: cobrautil.NoCompletion, } // hide builder persistent flag for this command diff --git a/commands/ls.go b/commands/ls.go index 428de1b6238..cd8fd614b71 100644 --- a/commands/ls.go +++ b/commands/ls.go @@ -126,6 +126,7 @@ func lsCmd(dockerCli command.Cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { return runLs(dockerCli, options) }, + ValidArgsFunction: cobrautil.NoCompletion, } // hide builder persistent flag for this command diff --git a/commands/prune.go b/commands/prune.go index 653ffd84ea7..a4f0be85ca5 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" "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: cobrautil.NoCompletion, } flags := cmd.Flags() diff --git a/commands/rm.go b/commands/rm.go index fcd4b5e976a..24869926b86 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" "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: cobrautil.NoCompletion, } flags := cmd.Flags() diff --git a/commands/root.go b/commands/root.go index eda2c1e52d1..a84a9330d9d 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 cebf1c2a081..4bb1cf64bc1 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" "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: cobrautil.NoCompletion, } return cmd diff --git a/commands/uninstall.go b/commands/uninstall.go index f5b000ebde3..c0f45657587 100644 --- a/commands/uninstall.go +++ b/commands/uninstall.go @@ -52,7 +52,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: cobrautil.NoCompletion, } // hide builder persistent flag for this command diff --git a/commands/use.go b/commands/use.go index 7e52ce85c82..1241cf1f8e5 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" "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: cobrautil.NoCompletion, } flags := cmd.Flags() diff --git a/commands/version.go b/commands/version.go index 91cfe136808..7e9b64a6568 100644 --- a/commands/version.go +++ b/commands/version.go @@ -23,6 +23,7 @@ func versionCmd(dockerCli command.Cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { return runVersion(dockerCli) }, + ValidArgsFunction: cobrautil.NoCompletion, } // hide builder persistent flag for this command diff --git a/util/cobrautil/completion.go b/util/cobrautil/completion.go new file mode 100644 index 00000000000..9f439fc6b84 --- /dev/null +++ b/util/cobrautil/completion.go @@ -0,0 +1,38 @@ +package cobrautil + +import ( + "strings" + + "github.com/docker/buildx/bake" + "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 NoCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return nil, cobra.ShellCompDirectiveNoFileComp +} + +func CompleteBakeTargets(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 10dc9594eb812a0bc6dedc1a31105846e618fca0 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 12 Mar 2023 00:31:37 +0100 Subject: [PATCH 2/2] 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 aef01800b2e..b02aa2215ac 100644 --- a/commands/build.go +++ b/commands/build.go @@ -22,7 +22,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" "github.com/docker/buildx/util/ioset" "github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/tracing" @@ -236,7 +235,9 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { } return runBuild(dockerCli, options) }, - ValidArgsFunction: cobrautil.NoCompletion, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return nil, cobra.ShellCompDirectiveFilterDirs + }, } var platformsDefault []string