Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit 02a383c

Browse files
committed
Use render to load docker-compose.yml with defaults
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent d72712d commit 02a383c

File tree

3 files changed

+51
-153
lines changed

3 files changed

+51
-153
lines changed

internal/commands/build/build.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/docker/buildx/util/progress"
2323
"github.com/docker/cli/cli"
2424
"github.com/docker/cli/cli/command"
25+
compose "github.com/docker/cli/cli/compose/types"
2526
"github.com/docker/cnab-to-oci/remotes"
2627
"github.com/docker/distribution/reference"
2728
"github.com/moby/buildkit/client"
@@ -194,17 +195,17 @@ func buildImageUsingBuildx(app *types.App, contextPath string, opt buildOptions,
194195
return bundle, nil
195196
}
196197

197-
func fixServiceImageReferences(ctx context.Context, dockerCli command.Cli, bundle *bundle.Bundle, pulledServices []ServiceConfig) error {
198+
func fixServiceImageReferences(ctx context.Context, dockerCli command.Cli, bundle *bundle.Bundle, pulledServices []compose.ServiceConfig) error {
198199
insecureRegistries, err := internal.InsecureRegistriesFromEngine(dockerCli)
199200
if err != nil {
200201
return errors.Wrapf(err, "could not retrieve insecure registries")
201202
}
202203
resolver := remotes.CreateResolver(dockerCli.ConfigFile(), insecureRegistries...)
203204
for _, service := range pulledServices {
204205
image := bundle.Images[service.Name]
205-
ref, err := reference.ParseDockerRef(*service.Image)
206+
ref, err := reference.ParseDockerRef(service.Image)
206207
if err != nil {
207-
return errors.Wrapf(err, "could not resolve image %s", *service.Image)
208+
return errors.Wrapf(err, "could not resolve image %s", service.Image)
208209
}
209210
_, desc, err := resolver.Resolve(ctx, ref.String())
210211
if err != nil {

internal/commands/build/compose.go

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,43 @@ package build
33
import (
44
"fmt"
55
"path"
6+
"path/filepath"
7+
"strings"
8+
9+
"github.com/docker/app/render"
610

711
"github.com/docker/app/types"
812
"github.com/docker/buildx/build"
9-
"github.com/docker/cli/cli/compose/loader"
1013
compose "github.com/docker/cli/cli/compose/types"
1114
)
1215

1316
// parseCompose do parse app compose file and extract buildx Options
1417
// We don't rely on bake's ReadTargets + TargetsToBuildOpt here as we have to skip environment variable interpolation
15-
func parseCompose(app *types.App, contextPath string, options buildOptions) (map[string]build.Options, []ServiceConfig, error) {
16-
parsed, err := loader.ParseYAML(app.Composes()[0])
18+
func parseCompose(app *types.App, contextPath string, options buildOptions) (map[string]build.Options, []compose.ServiceConfig, error) {
19+
comp, err := render.Render(app, nil, nil)
1720
if err != nil {
1821
return nil, nil, err
1922
}
2023

21-
services, err := load(parsed, options.args)
22-
if err != nil {
23-
return nil, nil, fmt.Errorf("Failed to parse compose file: %s", err)
24-
}
24+
buildArgs := buildArgsToMap(options.args)
2525

26-
pulledServices := []ServiceConfig{}
26+
pulledServices := []compose.ServiceConfig{}
2727
opts := map[string]build.Options{}
28-
for _, service := range services {
29-
if service.Build == nil {
28+
for _, service := range comp.Services {
29+
// Sanity check
30+
for _, vol := range service.Volumes {
31+
if vol.Type == "bind" && !filepath.IsAbs(vol.Source) {
32+
return nil, nil, fmt.Errorf("invalid service %q: can't use relative path as volume source", service.Name)
33+
}
34+
}
35+
36+
if service.Build.Context == "" {
3037
pulledServices = append(pulledServices, service)
3138
continue
3239
}
3340
var tags []string
34-
if service.Image != nil {
35-
tags = append(tags, *service.Image)
41+
if service.Image != "" {
42+
tags = append(tags, service.Image)
3643
}
3744

3845
if service.Build.Dockerfile == "" {
@@ -43,7 +50,7 @@ func parseCompose(app *types.App, contextPath string, options buildOptions) (map
4350
ContextPath: path.Join(contextPath, service.Build.Context),
4451
DockerfilePath: path.Join(contextPath, service.Build.Context, service.Build.Dockerfile),
4552
},
46-
BuildArgs: flatten(service.Build.Args),
53+
BuildArgs: flatten(mergeArgs(service.Build.Args, buildArgs)),
4754
NoCache: options.noCache,
4855
Pull: options.pull,
4956
Tags: tags,
@@ -52,6 +59,33 @@ func parseCompose(app *types.App, contextPath string, options buildOptions) (map
5259
return opts, pulledServices, nil
5360
}
5461

62+
func buildArgsToMap(array []string) map[string]string {
63+
result := make(map[string]string)
64+
for _, value := range array {
65+
parts := strings.SplitN(value, "=", 2)
66+
key := parts[0]
67+
if len(parts) == 1 {
68+
result[key] = ""
69+
} else {
70+
result[key] = parts[1]
71+
}
72+
}
73+
return result
74+
}
75+
76+
func mergeArgs(src compose.MappingWithEquals, values map[string]string) compose.MappingWithEquals {
77+
for key := range src {
78+
if val, ok := values[key]; ok {
79+
if val == "" {
80+
src[key] = nil
81+
} else {
82+
src[key] = &val
83+
}
84+
}
85+
}
86+
return src
87+
}
88+
5589
func flatten(in compose.MappingWithEquals) map[string]string {
5690
if len(in) == 0 {
5791
return nil

internal/commands/build/types.go

Lines changed: 0 additions & 137 deletions
This file was deleted.

0 commit comments

Comments
 (0)