diff --git a/bake/bake.go b/bake/bake.go index 8656e7ba..a9e79cd2 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -109,9 +109,9 @@ func (c Config) setOverrides(v []string) error { switch keys[1] { case "context": - t.Context = parts[1] + t.Context = &parts[1] case "dockerfile": - t.Dockerfile = parts[1] + t.Dockerfile = &parts[1] case "args": if len(keys) != 3 { return errors.Errorf("invalid key %s, args requires name", parts[0]) @@ -170,7 +170,19 @@ func (c Config) group(name string, visited map[string]struct{}) []string { } func (c Config) ResolveTarget(name string) (*Target, error) { - return c.target(name, map[string]struct{}{}) + t, err := c.target(name, map[string]struct{}{}) + if err != nil { + return nil, err + } + if t.Context == nil { + s := "." + t.Context = &s + } + if t.Dockerfile == nil { + s := "Dockerfile" + t.Dockerfile = &s + } + return t, nil } func (c Config) target(name string, visited map[string]struct{}) (*Target, error) { @@ -205,8 +217,8 @@ type Group struct { type Target struct { Inherits []string `json:"inherits,omitempty"` - Context string `json:"context,omitempty"` - Dockerfile string `json:"dockerfile,omitempty"` + Context *string `json:"context,omitempty"` + Dockerfile *string `json:"dockerfile,omitempty"` Args map[string]string `json:"args,omitempty"` Labels map[string]string `json:"labels,omitempty"` Tags []string `json:"tags,omitempty"` @@ -238,17 +250,26 @@ func TargetsToBuildOpt(m map[string]Target) (map[string]build.Options, error) { } func toBuildOpt(t Target) (*build.Options, error) { - if t.Context == "-" { + if v := t.Context; v != nil && *v == "-" { return nil, errors.Errorf("context from stdin not allowed in bake") } - if t.Dockerfile == "-" { + if v := t.Dockerfile; v != nil && *v == "-" { return nil, errors.Errorf("dockerfile from stdin not allowed in bake") } + contextPath := "." + if t.Context != nil { + contextPath = *t.Context + } + dockerfilePath := "Dockerfile" + if t.Dockerfile != nil { + dockerfilePath = *t.Dockerfile + } + bo := &build.Options{ Inputs: build.Inputs{ - ContextPath: t.Context, - DockerfilePath: t.Dockerfile, + ContextPath: contextPath, + DockerfilePath: dockerfilePath, }, Tags: t.Tags, BuildArgs: t.Args, @@ -295,17 +316,14 @@ func toBuildOpt(t Target) (*build.Options, error) { } func defaultTarget() Target { - return Target{ - Context: ".", - Dockerfile: "Dockerfile", - } + return Target{} } func merge(t1, t2 Target) Target { - if t2.Context != "" { + if t2.Context != nil { t1.Context = t2.Context } - if t2.Dockerfile != "" { + if t2.Dockerfile != nil { t1.Dockerfile = t2.Dockerfile } for k, v := range t2.Args { diff --git a/bake/bake_test.go b/bake/bake_test.go new file mode 100644 index 00000000..defc3f84 --- /dev/null +++ b/bake/bake_test.go @@ -0,0 +1,69 @@ +package bake + +import ( + "context" + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestReadTargets(t *testing.T) { + t.Parallel() + tmpdir, err := ioutil.TempDir("", "bake") + require.NoError(t, err) + defer os.RemoveAll(tmpdir) + + fp := filepath.Join(tmpdir, "config.hcl") + err = ioutil.WriteFile(fp, []byte(` +target "dep" { +} + +target "webapp" { + dockerfile = "Dockerfile.webapp" + inherits = ["dep"] +}`), 0600) + require.NoError(t, err) + + ctx := context.TODO() + + m, err := ReadTargets(ctx, []string{fp}, []string{"webapp"}, nil) + require.NoError(t, err) + + require.Equal(t, "Dockerfile.webapp", *m["webapp"].Dockerfile) + require.Equal(t, ".", *m["webapp"].Context) +} + +func TestReadTargetsCompose(t *testing.T) { + t.Parallel() + tmpdir, err := ioutil.TempDir("", "bake") + require.NoError(t, err) + defer os.RemoveAll(tmpdir) + + fp := filepath.Join(tmpdir, "docker-compose.yml") + err = ioutil.WriteFile(fp, []byte(` +version: "3" + +services: + db: + build: . + command: ./entrypoint.sh + image: docker.io/tonistiigi/db + webapp: + build: + dockerfile: Dockerfile.webapp + args: + buildno: 1 +`), 0600) + require.NoError(t, err) + + ctx := context.TODO() + + m, err := ReadTargets(ctx, []string{fp}, []string{"default"}, nil) + require.NoError(t, err) + + require.Equal(t, "Dockerfile.webapp", *m["webapp"].Dockerfile) + require.Equal(t, ".", *m["webapp"].Context) +} diff --git a/bake/compose.go b/bake/compose.go index ad6648dd..780ca76a 100644 --- a/bake/compose.go +++ b/bake/compose.go @@ -34,9 +34,19 @@ func ParseCompose(dt []byte) (*Config, error) { for _, s := range cfg.Services { g.Targets = append(g.Targets, s.Name) + var contextPathP *string + if s.Build.Context != "" { + contextPath := s.Build.Context + contextPathP = &contextPath + } + var dockerfilePathP *string + if s.Build.Dockerfile != "" { + dockerfilePath := s.Build.Dockerfile + dockerfilePathP = &dockerfilePath + } t := Target{ - Context: s.Build.Context, - Dockerfile: s.Build.Dockerfile, + Context: contextPathP, + Dockerfile: dockerfilePathP, Labels: s.Build.Labels, Args: toMap(s.Build.Args), CacheFrom: s.Build.CacheFrom, diff --git a/bake/compose_test.go b/bake/compose_test.go index d778774e..d0f46b29 100644 --- a/bake/compose_test.go +++ b/bake/compose_test.go @@ -32,10 +32,10 @@ services: require.Equal(t, []string{"db", "webapp"}, c.Group["default"].Targets) require.Equal(t, 2, len(c.Target)) - require.Equal(t, "./db", c.Target["db"].Context) + require.Equal(t, "./db", *c.Target["db"].Context) - require.Equal(t, "./dir", c.Target["webapp"].Context) - require.Equal(t, "Dockerfile-alternate", c.Target["webapp"].Dockerfile) + require.Equal(t, "./dir", *c.Target["webapp"].Context) + require.Equal(t, "Dockerfile-alternate", *c.Target["webapp"].Dockerfile) require.Equal(t, 1, len(c.Target["webapp"].Args)) require.Equal(t, "123", c.Target["webapp"].Args["buildno"]) } diff --git a/bake/hcl_test.go b/bake/hcl_test.go index 61333847..5e4fc001 100644 --- a/bake/hcl_test.go +++ b/bake/hcl_test.go @@ -47,7 +47,7 @@ func TestParseHCL(t *testing.T) { require.Equal(t, []string{"db", "webapp"}, c.Group["default"].Targets) require.Equal(t, 4, len(c.Target)) - require.Equal(t, "./db", c.Target["db"].Context) + require.Equal(t, "./db", *c.Target["db"].Context) require.Equal(t, 1, len(c.Target["webapp"].Args)) require.Equal(t, "123", c.Target["webapp"].Args["buildno"]) diff --git a/build/build.go b/build/build.go index f6745351..cdee48ec 100644 --- a/build/build.go +++ b/build/build.go @@ -420,7 +420,7 @@ func LoadInputs(inp Inputs, target *client.SolveOpt) (func(), error) { } func notSupported(d driver.Driver, f driver.Feature) error { - return errors.Errorf("%s feature is currently not supported for %s driver. Please switch to a different driver (eg. \"docker buildx create\")", f, d.Factory().Name()) + return errors.Errorf("%s feature is currently not supported for %s driver. Please switch to a different driver (eg. \"docker buildx create --use\")", f, d.Factory().Name()) } func newDockerLoader(ctx context.Context, d DockerAPI, name string, mw *progress.MultiWriter) (io.WriteCloser, func(), error) {