bake: align compose path base with compose

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2026-07-21 11:25:55 +02:00
parent 1dc55abd89
commit bc32533b6e
6 changed files with 111 additions and 36 deletions
+4 -1
View File
@@ -376,10 +376,13 @@ func ParseFiles(files []File, defaults, vars map[string]string, opts ...ParseOpt
}
if len(composeFiles) > 0 {
cfg, cmperr := parseComposeFilesWithBase(composeFiles, vars, frel)
cfg, cmperr := ParseComposeFiles(composeFiles, vars)
if cmperr != nil {
return nil, nil, errors.Wrap(cmperr, "failed to parse compose file")
}
if frel {
setComposeContextBase(cfg, composeFiles)
}
c = mergeConfig(c, *cfg)
c = dedupeConfig(c)
}
+16 -29
View File
@@ -22,38 +22,19 @@ import (
)
func ParseComposeFiles(fs []File, envOverrides map[string]string, opts ...ParseOpt) (*Config, error) {
frel := fileRelativePaths(opts)
cfg, err := parseComposeFilesWithBase(fs, envOverrides, frel)
if err != nil {
return nil, err
}
if frel {
rebaseContextPaths(cfg)
}
return cfg, nil
}
func parseComposeFilesWithBase(fs []File, envOverrides map[string]string, withBase bool) (*Config, error) {
envs, err := composeEnv(envOverrides)
if err != nil {
return nil, err
}
if withBase && len(fs) > 0 {
var c Config
for _, f := range fs {
cfg, err := parseComposeFiles([]File{f}, envs)
if err != nil {
return nil, err
}
setComposeContextBase(cfg, f.Name)
c = mergeConfig(c, *cfg)
c = dedupeConfig(c)
}
return &c, nil
cfg, err := parseComposeFiles(fs, envs)
if err != nil {
return nil, err
}
return parseComposeFiles(fs, envs)
if fileRelativePaths(opts) {
setComposeContextBase(cfg, fs)
rebaseContextPaths(cfg)
}
return cfg, nil
}
func parseComposeFiles(fs []File, envs map[string]string) (*Config, error) {
@@ -67,8 +48,14 @@ func parseComposeFiles(fs []File, envs map[string]string) (*Config, error) {
return ParseCompose(cfgs, envs)
}
func setComposeContextBase(c *Config, name string) {
base, _ := localFileDir(name)
func setComposeContextBase(c *Config, files []File) {
if len(files) == 0 {
return
}
base, ok := localFileDir(files[0].Name)
if !ok {
return
}
for _, t := range c.Targets {
t.defaultContextBase = base
t.hasDefaultContextBase = true
+39
View File
@@ -174,6 +174,45 @@ services:
require.Equal(t, "webapp", *c.Targets[1].Target)
}
func TestComposeProjectBase(t *testing.T) {
fp := File{
Name: filepath.Join("project", "compose.yml"),
Data: []byte(`
services:
app:
build:
context: ./app
`),
}
fp2 := File{
Name: filepath.Join("overrides", "compose.yml"),
Data: []byte(`
services:
app:
build:
additional_contexts:
shared: ./shared
other:
build:
context: ./other
`),
}
c, err := ParseComposeFiles([]File{fp, fp2}, nil, ParseOpt{
FileRelativePaths: true,
})
require.NoError(t, err)
targets := map[string]*Target{}
for _, t := range c.Targets {
targets[t.Name] = t
}
require.Equal(t, filepath.ToSlash(filepath.Clean("project/app")), *targets["app"].Context)
require.Equal(t, filepath.ToSlash(filepath.Clean("project/shared")), targets["app"].Contexts["shared"])
require.Equal(t, filepath.ToSlash(filepath.Clean("project/other")), *targets["other"].Context)
}
func TestBuildArgEnvCompose(t *testing.T) {
dt := []byte(`
version: "3.8"
+4 -3
View File
@@ -417,9 +417,10 @@ target "app" {
This resolves to the current working directory (`"."`) by default.
Set `BUILDX_BAKE_FILE_RELATIVE_PATHS=1` to resolve local directory paths in
`target.context` and `target.contexts` relative to the Bake or Compose file
that defines each path. Use `cwd://` for paths that should remain relative to
the current working directory when this opt-in is enabled.
`target.context` and `target.contexts` relative to the Bake file that defines
each path. Compose files use the first Compose file directory as the base, which
matches Compose project directory semantics. Use `cwd://` for paths that should
remain relative to the current working directory when this opt-in is enabled.
```console
$ docker buildx bake --print -f - <<< 'target "default" {}'
+5 -3
View File
@@ -155,9 +155,11 @@ Multiple definitions can be specified by separating them with the system's path
By default, local directory build contexts in Bake files are resolved from the
current working directory. To opt in to resolving local directory build contexts
from the Bake or Compose file that defines each path, set
`BUILDX_BAKE_FILE_RELATIVE_PATHS=1`. Use the `cwd://` prefix for paths that
should remain relative to the current working directory.
from the Bake file that defines each path, set
`BUILDX_BAKE_FILE_RELATIVE_PATHS=1`. Compose files use the first Compose file
directory as the base, which matches Compose project directory semantics. Use
the `cwd://` prefix for paths that should remain relative to the current working
directory.
You can pass the names of the targets to build, to build only specific target(s).
The following example builds the `db` and `webapp-release` targets that are
+43
View File
@@ -715,6 +715,49 @@ services:
require.FileExists(t, filepath.Join(dirDest, "shared-marker"))
})
t.Run("compose project", func(t *testing.T) {
composefile := []byte(`
services:
app:
build:
context: ./app
dockerfile_inline: |
FROM scratch
COPY marker /marker
COPY --from=shared shared-marker /shared-marker
`)
overridefile := []byte(`
services:
app:
build:
additional_contexts:
shared: ./shared
`)
dir := tmpdir(
t,
fstest.CreateDir("project", 0700),
fstest.CreateDir("project/app", 0700),
fstest.CreateDir("project/shared", 0700),
fstest.CreateDir("overrides", 0700),
fstest.CreateFile("project/compose.yml", composefile, 0600),
fstest.CreateFile("project/app/marker", []byte("marker"), 0600),
fstest.CreateFile("project/shared/shared-marker", []byte("shared"), 0600),
fstest.CreateFile("overrides/compose.yml", overridefile, 0600),
)
dirDest := t.TempDir()
out, err := bakeCmd(
sb,
withDir(dir),
withArgs("--file", "project/compose.yml", "--file", "overrides/compose.yml", "--set", "app.output=type=local,dest="+dirDest),
withEnv("BUILDX_BAKE_FILE_RELATIVE_PATHS=1"),
)
require.NoError(t, err, out)
require.FileExists(t, filepath.Join(dirDest, "marker"))
require.FileExists(t, filepath.Join(dirDest, "shared-marker"))
})
t.Run("default context", func(t *testing.T) {
bakefile := []byte(`
target "default" {