Skip to content

Commit

Permalink
Merge pull request #857 from crazy-max/bake-json
Browse files Browse the repository at this point in the history
bake: fix print output
  • Loading branch information
tonistiigi authored Nov 24, 2021
2 parents 5c2b9bb + 316ca97 commit ab73275
Show file tree
Hide file tree
Showing 4 changed files with 319 additions and 90 deletions.
15 changes: 14 additions & 1 deletion bake/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,20 @@ func ReadTargets(ctx context.Context, files []File, targets, overrides []string,
}
}
}
return m, c.Groups, nil

var g []*Group
if len(targets) == 0 || (len(targets) == 1 && targets[0] == "default") {
for _, group := range c.Groups {
if group.Name != "default" {
continue
}
g = []*Group{{Targets: group.Targets}}
}
} else {
g = []*Group{{Targets: targets}}
}

return m, g, nil
}

func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error) {
Expand Down
232 changes: 217 additions & 15 deletions bake/bake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package bake
import (
"context"
"os"
"sort"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -34,7 +35,7 @@ target "webapp" {
ctx := context.TODO()

t.Run("NoOverrides", func(t *testing.T) {
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, nil, nil)
m, g, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(m))

Expand All @@ -43,6 +44,9 @@ target "webapp" {
require.Equal(t, "webDEP", m["webapp"].Args["VAR_INHERITED"])
require.Equal(t, true, *m["webapp"].NoCache)
require.Nil(t, m["webapp"].Pull)

require.Equal(t, 1, len(g))
require.Equal(t, []string{"webapp"}, g[0].Targets)
})

t.Run("InvalidTargetOverrides", func(t *testing.T) {
Expand All @@ -56,7 +60,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, g, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{
"webapp.args.VAR_UNSET",
"webapp.args.VAR_EMPTY=",
"webapp.args.VAR_SET=bananas",
Expand All @@ -81,58 +85,72 @@ target "webapp" {

require.Equal(t, m["webapp"].Args["VAR_BOTH"], "webapp")
require.Equal(t, m["webapp"].Args["VAR_INHERITED"], "override")

require.Equal(t, 1, len(g))
require.Equal(t, []string{"webapp"}, g[0].Targets)
})

// building leaf but overriding parent fields
t.Run("parent", func(t *testing.T) {
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{
m, g, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{
"webDEP.args.VAR_INHERITED=override",
"webDEP.args.VAR_BOTH=override",
}, nil)

require.NoError(t, err)
require.Equal(t, m["webapp"].Args["VAR_INHERITED"], "override")
require.Equal(t, m["webapp"].Args["VAR_BOTH"], "webapp")
require.Equal(t, 1, len(g))
require.Equal(t, []string{"webapp"}, g[0].Targets)
})
})

t.Run("ContextOverride", func(t *testing.T) {
_, _, 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, g, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.context=foo"}, nil)
require.NoError(t, err)

require.Equal(t, "foo", *m["webapp"].Context)
require.Equal(t, 1, len(g))
require.Equal(t, []string{"webapp"}, g[0].Targets)
})

t.Run("NoCacheOverride", func(t *testing.T) {
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.no-cache=false"}, nil)
m, g, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.no-cache=false"}, nil)
require.NoError(t, err)
require.Equal(t, false, *m["webapp"].NoCache)
require.Equal(t, 1, len(g))
require.Equal(t, []string{"webapp"}, g[0].Targets)
})

t.Run("PullOverride", func(t *testing.T) {
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.pull=false"}, nil)
m, g, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.pull=false"}, nil)
require.NoError(t, err)
require.Equal(t, false, *m["webapp"].Pull)
require.Equal(t, 1, len(g))
require.Equal(t, []string{"webapp"}, g[0].Targets)
})

t.Run("PatternOverride", func(t *testing.T) {
// same check for two cases
multiTargetCheck := func(t *testing.T, m map[string]*Target, err error) {
multiTargetCheck := func(t *testing.T, m map[string]*Target, g []*Group, err error) {
require.NoError(t, err)
require.Equal(t, 2, len(m))
require.Equal(t, "foo", *m["webapp"].Dockerfile)
require.Equal(t, "webDEP", m["webapp"].Args["VAR_INHERITED"])
require.Equal(t, "foo", *m["webDEP"].Dockerfile)
require.Equal(t, "webDEP", m["webDEP"].Args["VAR_INHERITED"])
require.Equal(t, 1, len(g))
sort.Strings(g[0].Targets)
require.Equal(t, []string{"webDEP", "webapp"}, g[0].Targets)
}

cases := []struct {
name string
targets []string
overrides []string
check func(*testing.T, map[string]*Target, error)
check func(*testing.T, map[string]*Target, []*Group, error)
}{
{
name: "multi target single pattern",
Expand All @@ -150,18 +168,20 @@ target "webapp" {
name: "single target",
targets: []string{"webapp"},
overrides: []string{"web*.dockerfile=foo"},
check: func(t *testing.T, m map[string]*Target, err error) {
check: func(t *testing.T, m map[string]*Target, g []*Group, err error) {
require.NoError(t, err)
require.Equal(t, 1, len(m))
require.Equal(t, "foo", *m["webapp"].Dockerfile)
require.Equal(t, "webDEP", m["webapp"].Args["VAR_INHERITED"])
require.Equal(t, 1, len(g))
require.Equal(t, []string{"webapp"}, g[0].Targets)
},
},
{
name: "nomatch",
targets: []string{"webapp"},
overrides: []string{"nomatch*.dockerfile=foo"},
check: func(t *testing.T, m map[string]*Target, err error) {
check: func(t *testing.T, m map[string]*Target, g []*Group, err error) {
// NOTE: I am unsure whether failing to match should always error out
// instead of simply skipping that override.
// Let's enforce the error and we can relax it later if users complain.
Expand All @@ -172,8 +192,8 @@ 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)
test.check(t, m, err)
m, g, err := ReadTargets(ctx, []File{fp}, test.targets, test.overrides, nil)
test.check(t, m, g, err)
})
}
})
Expand Down Expand Up @@ -260,16 +280,21 @@ services:

ctx := context.TODO()

m, _, err := ReadTargets(ctx, []File{fp, fp2}, []string{"default"}, nil, nil)
m, g, err := ReadTargets(ctx, []File{fp, fp2}, []string{"default"}, nil, nil)
require.NoError(t, err)

require.Equal(t, 3, len(m))
_, ok := m["newservice"]

require.True(t, ok)
require.Equal(t, "Dockerfile.webapp", *m["webapp"].Dockerfile)
require.Equal(t, ".", *m["webapp"].Context)
require.Equal(t, "1", m["webapp"].Args["buildno"])
require.Equal(t, "12", m["webapp"].Args["buildno2"])

require.Equal(t, 1, len(g))
sort.Strings(g[0].Targets)
require.Equal(t, []string{"db", "newservice", "webapp"}, g[0].Targets)
}

func TestHCLCwdPrefix(t *testing.T) {
Expand All @@ -282,7 +307,7 @@ func TestHCLCwdPrefix(t *testing.T) {
}`),
}
ctx := context.TODO()
m, _, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil)
m, g, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil)
require.NoError(t, err)

require.Equal(t, 1, len(m))
Expand All @@ -294,6 +319,9 @@ func TestHCLCwdPrefix(t *testing.T) {

require.Equal(t, "test", *m["app"].Dockerfile)
require.Equal(t, "foo", *m["app"].Context)

require.Equal(t, 1, len(g))
require.Equal(t, []string{"app"}, g[0].Targets)
}

func TestOverrideMerge(t *testing.T) {
Expand Down Expand Up @@ -324,3 +352,177 @@ func TestOverrideMerge(t *testing.T) {
require.Equal(t, 1, len(m["app"].Outputs))
require.Equal(t, "type=registry", m["app"].Outputs[0])
}

func TestReadTargetsMixed(t *testing.T) {
t.Parallel()

fTargetDefault := File{
Name: "docker-bake2.hcl",
Data: []byte(`
target "default" {
dockerfile = "test"
}`)}

fTargetImage := File{
Name: "docker-bake3.hcl",
Data: []byte(`
target "image" {
dockerfile = "test"
}`)}

fpHCL := File{
Name: "docker-bake.hcl",
Data: []byte(`
group "default" {
targets = ["image"]
}
target "nocache" {
no-cache = true
}
group "release" {
targets = ["image-release"]
}
target "image" {
inherits = ["nocache"]
output = ["type=docker"]
}
target "image-release" {
inherits = ["image"]
output = ["type=image,push=true"]
tags = ["user/app:latest"]
}`)}

fpYML := File{
Name: "docker-compose.yml",
Data: []byte(`
services:
addon:
build:
context: .
dockerfile: ./Dockerfile
args:
CT_ECR: foo
CT_TAG: bar
image: ct-addon:bar
environment:
- NODE_ENV=test
- AWS_ACCESS_KEY_ID=dummy
- AWS_SECRET_ACCESS_KEY=dummy
aws:
build:
dockerfile: ./aws.Dockerfile
args:
CT_ECR: foo
CT_TAG: bar
image: ct-fake-aws:bar`)}

fpJSON := File{
Name: "docker-bake.json",
Data: []byte(`{
"group": {
"default": {
"targets": [
"image"
]
}
},
"target": {
"image": {
"context": ".",
"dockerfile": "Dockerfile",
"output": [
"type=docker"
]
}
}
}`)}

ctx := context.TODO()

m, g, err := ReadTargets(ctx, []File{fTargetDefault}, []string{"default"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 0, len(g))
require.Equal(t, 1, len(m))
require.Equal(t, "test", *m["default"].Dockerfile)

_, _, err = ReadTargets(ctx, []File{fTargetImage}, []string{"default"}, nil, nil)
require.Error(t, err)

m, g, err = ReadTargets(ctx, []File{fTargetImage}, []string{"image"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(g))
require.Equal(t, []string{"image"}, g[0].Targets)
require.Equal(t, 1, len(m))
require.Equal(t, "test", *m["image"].Dockerfile)

m, g, err = ReadTargets(ctx, []File{fTargetImage}, []string{"image"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(g))
require.Equal(t, []string{"image"}, g[0].Targets)
require.Equal(t, 1, len(m))
require.Equal(t, "test", *m["image"].Dockerfile)

m, g, err = ReadTargets(ctx, []File{fpHCL}, []string{"image-release"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(g))
require.Equal(t, []string{"image-release"}, g[0].Targets)
require.Equal(t, 1, len(m))
require.Equal(t, 1, len(m["image-release"].Outputs))
require.Equal(t, "type=image,push=true", m["image-release"].Outputs[0])

m, g, err = ReadTargets(ctx, []File{fpHCL}, []string{"image", "image-release"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(g))
require.Equal(t, []string{"image", "image-release"}, g[0].Targets)
require.Equal(t, 2, len(m))
require.Equal(t, ".", *m["image"].Context)
require.Equal(t, 1, len(m["image-release"].Outputs))
require.Equal(t, "type=image,push=true", m["image-release"].Outputs[0])

m, g, err = ReadTargets(ctx, []File{fpYML, fpHCL}, []string{"default"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(g))
require.Equal(t, []string{"image"}, g[0].Targets)
require.Equal(t, 1, len(m))
require.Equal(t, ".", *m["image"].Context)

m, g, err = ReadTargets(ctx, []File{fpJSON}, []string{"default"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(g))
require.Equal(t, []string{"image"}, g[0].Targets)
require.Equal(t, 1, len(m))
require.Equal(t, ".", *m["image"].Context)

m, g, err = ReadTargets(ctx, []File{fpYML}, []string{"default"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(g))
sort.Strings(g[0].Targets)
require.Equal(t, []string{"addon", "aws"}, g[0].Targets)
require.Equal(t, 2, len(m))
require.Equal(t, "./Dockerfile", *m["addon"].Dockerfile)
require.Equal(t, "./aws.Dockerfile", *m["aws"].Dockerfile)

m, g, err = ReadTargets(ctx, []File{fpYML, fpHCL}, []string{"addon", "aws"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(g))
sort.Strings(g[0].Targets)
require.Equal(t, []string{"addon", "aws"}, g[0].Targets)
require.Equal(t, 2, len(m))
require.Equal(t, "./Dockerfile", *m["addon"].Dockerfile)
require.Equal(t, "./aws.Dockerfile", *m["aws"].Dockerfile)

m, g, err = ReadTargets(ctx, []File{fpYML, fpHCL}, []string{"addon", "aws", "image"}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(g))
sort.Strings(g[0].Targets)
require.Equal(t, []string{"addon", "aws", "image"}, g[0].Targets)
require.Equal(t, 3, len(m))
require.Equal(t, ".", *m["image"].Context)
require.Equal(t, "./Dockerfile", *m["addon"].Dockerfile)
require.Equal(t, "./aws.Dockerfile", *m["aws"].Dockerfile)
}
Loading

0 comments on commit ab73275

Please sign in to comment.