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 + } +}