diff --git a/bake/bake.go b/bake/bake.go index e10bb014..37d9ec4b 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -61,29 +61,29 @@ func ReadLocalFiles(names []string) ([]File, error) { return out, nil } -func ReadTargets(ctx context.Context, files []File, targets, overrides []string, defaults map[string]string) (map[string]*Target, error) { +func ReadTargets(ctx context.Context, files []File, targets, overrides []string, defaults map[string]string) (map[string]*Target, []*Group, error) { c, err := ParseFiles(files, defaults) if err != nil { - return nil, err + return nil, nil, err } o, err := c.newOverrides(overrides) if err != nil { - return nil, err + return nil, nil, err } m := map[string]*Target{} for _, n := range targets { for _, n := range c.ResolveGroup(n) { t, err := c.ResolveTarget(n, o) if err != nil { - return nil, err + return nil, nil, err } if t != nil { m[n] = t } } } - return m, nil + return m, c.Groups, nil } func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error) { diff --git a/bake/bake_test.go b/bake/bake_test.go index f68f1580..9542eecd 100644 --- a/bake/bake_test.go +++ b/bake/bake_test.go @@ -34,7 +34,7 @@ target "webapp" { ctx := context.TODO() t.Run("NoOverrides", func(t *testing.T) { - m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, nil, nil) + m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, nil, nil) require.NoError(t, err) require.Equal(t, 1, len(m)) @@ -46,7 +46,7 @@ target "webapp" { }) t.Run("InvalidTargetOverrides", func(t *testing.T) { - _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"nosuchtarget.context=foo"}, nil) + _, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"nosuchtarget.context=foo"}, nil) require.NotNil(t, err) require.Equal(t, err.Error(), "could not find any target matching 'nosuchtarget'") }) @@ -56,7 +56,7 @@ target "webapp" { os.Setenv("VAR_FROMENV"+t.Name(), "fromEnv") defer os.Unsetenv("VAR_FROM_ENV" + t.Name()) - m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{ + m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{ "webapp.args.VAR_UNSET", "webapp.args.VAR_EMPTY=", "webapp.args.VAR_SET=bananas", @@ -85,7 +85,7 @@ target "webapp" { // building leaf but overriding parent fields t.Run("parent", func(t *testing.T) { - m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{ + m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{ "webDEP.args.VAR_INHERITED=override", "webDEP.args.VAR_BOTH=override", }, nil) @@ -96,23 +96,23 @@ target "webapp" { }) t.Run("ContextOverride", func(t *testing.T) { - _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.context"}, nil) + _, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.context"}, nil) require.NotNil(t, err) - m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.context=foo"}, nil) + m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.context=foo"}, nil) require.NoError(t, err) require.Equal(t, "foo", *m["webapp"].Context) }) t.Run("NoCacheOverride", func(t *testing.T) { - m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.no-cache=false"}, nil) + m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.no-cache=false"}, nil) require.NoError(t, err) require.Equal(t, false, *m["webapp"].NoCache) }) t.Run("PullOverride", func(t *testing.T) { - m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.pull=false"}, nil) + m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.pull=false"}, nil) require.NoError(t, err) require.Equal(t, false, *m["webapp"].Pull) }) @@ -172,7 +172,7 @@ target "webapp" { } for _, test := range cases { t.Run(test.name, func(t *testing.T) { - m, err := ReadTargets(ctx, []File{fp}, test.targets, test.overrides, nil) + m, _, err := ReadTargets(ctx, []File{fp}, test.targets, test.overrides, nil) test.check(t, m, err) }) } @@ -215,7 +215,7 @@ services: ctx := context.TODO() - m, err := ReadTargets(ctx, []File{fp, fp2}, []string{"default"}, nil, nil) + m, _, err := ReadTargets(ctx, []File{fp, fp2}, []string{"default"}, nil, nil) require.NoError(t, err) require.Equal(t, 3, len(m)) @@ -238,7 +238,7 @@ func TestHCLCwdPrefix(t *testing.T) { }`), } ctx := context.TODO() - m, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil) + m, _, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil) require.NoError(t, err) require.Equal(t, 1, len(m)) diff --git a/commands/bake.go b/commands/bake.go index 3318a401..4a2e168b 100644 --- a/commands/bake.go +++ b/commands/bake.go @@ -36,6 +36,7 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) (err error }() var url string + var noTarget bool cmdContext := "cwd://" if len(targets) > 0 { @@ -54,6 +55,7 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) (err error if len(targets) == 0 { targets = []string{"default"} + noTarget = true } overrides := in.overrides @@ -103,7 +105,7 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) (err error return err } - m, err := bake.ReadTargets(ctx, files, targets, overrides, map[string]string{ + t, g, err := bake.ReadTargets(ctx, files, targets, overrides, map[string]string{ "BAKE_CMD_CONTEXT": cmdContext, }) if err != nil { @@ -111,13 +113,32 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) (err error } // this function can update target context string from the input so call before printOnly check - bo, err := bake.TargetsToBuildOpt(m, inp) + bo, err := bake.TargetsToBuildOpt(t, inp) if err != nil { return err } if in.printOnly { - dt, err := json.MarshalIndent(map[string]map[string]*bake.Target{"target": m}, "", " ") + defGroup := map[string][]string{ + "default": targets, + } + if noTarget { + for _, group := range g { + if group.Name != "default" { + continue + } + defGroup = map[string][]string{ + "default": group.Targets, + } + } + } + dt, err := json.MarshalIndent(struct { + Group map[string][]string `json:"group,omitempty"` + Target map[string]*bake.Target `json:"target"` + }{ + defGroup, + t, + }, "", " ") if err != nil { return err } diff --git a/docs/reference/buildx_bake.md b/docs/reference/buildx_bake.md index c89fe028..3121f9bf 100644 --- a/docs/reference/buildx_bake.md +++ b/docs/reference/buildx_bake.md @@ -100,6 +100,11 @@ $ docker buildx bake "git://github.com/docker/cli#master" --print #1 0.686 2776a6d694f988c0c1df61cad4bfac0f54e481c8 refs/heads/master #1 CACHED { + "group": { + "default": [ + "binary" + ] + }, "target": { "binary": { "context": "git://github.com/docker/cli#master", @@ -144,6 +149,11 @@ EOT ```console $ docker buildx bake "git://github.com/tonistiigi/buildx#remote-test" --print { + "group": { + "default": [ + "default" + ] + }, "target": { "default": { "context": ".", @@ -171,6 +181,11 @@ $ docker buildx bake "git://github.com/tonistiigi/buildx#remote-test" "git://git #1 0.401 577303add004dd7efeb13434d69ea030d35f7888 refs/heads/remote-test #1 CACHED { + "group": { + "default": [ + "default" + ] + }, "target": { "default": { "context": "git://github.com/docker/cli#master", @@ -209,6 +224,11 @@ format, without starting a build. ```console $ docker buildx bake -f docker-bake.hcl --print db { + "group": { + "default": [ + "db" + ] + }, "target": { "db": { "context": "./", @@ -347,6 +367,11 @@ You can use this file directly: ```console $ docker buildx bake --print app { + "group": { + "default": [ + "app" + ] + }, "target": { "app": { "context": ".", @@ -372,6 +397,11 @@ And invoke bake together with both of the files: ```console $ docker buildx bake -f docker-bake.hcl -f env.hcl --print app { + "group": { + "default": [ + "app" + ] + }, "target": { "app": { "context": ".", @@ -419,6 +449,11 @@ target "webapp" { ```console $ docker buildx bake --print webapp { + "group": { + "default": [ + "webapp" + ] + }, "target": { "webapp": { "context": ".", @@ -434,6 +469,11 @@ $ docker buildx bake --print webapp ```console $ TAG=$(git rev-parse --short HEAD) docker buildx bake --print webapp { + "group": { + "default": [ + "webapp" + ] + }, "target": { "webapp": { "context": ".", @@ -471,6 +511,11 @@ target "webapp" { ```console $ docker buildx bake --print webapp { + "group": { + "default": [ + "webapp" + ] + }, "target": { "webapp": { "context": ".", @@ -509,6 +554,11 @@ target "webapp" { ```console $ docker buildx bake --print webapp { + "group": { + "default": [ + "webapp" + ] + }, "target": { "webapp": { "context": ".", @@ -549,6 +599,11 @@ target "webapp" { ```console $ docker buildx bake --print webapp { + "group": { + "default": [ + "webapp" + ] + }, "target": { "webapp": { "context": ".", @@ -585,6 +640,11 @@ target "webapp" { ```console $ docker buildx bake --print webapp { + "group": { + "default": [ + "webapp" + ] + }, "target": { "webapp": { "context": ".", @@ -635,6 +695,11 @@ target "app" { ```console $ docker buildx bake -f docker-bake1.hcl -f docker-bake2.hcl --print app { + "group": { + "default": [ + "app" + ] + }, "target": { "app": { "context": ".", @@ -674,6 +739,11 @@ target "app" { ```console $ docker buildx bake --print app { + "group": { + "default": [ + "app" + ] + }, "target": { "app": { "context": ".",