diff --git a/yaml/docker-compose-include-base.yml b/yaml/docker-compose-include-base.yml deleted file mode 100644 index 7a3f4b3e..00000000 --- a/yaml/docker-compose-include-base.yml +++ /dev/null @@ -1,3 +0,0 @@ -include: -{{ range .files }}- {{ . }} -{{ end }} diff --git a/yaml/generator.go b/yaml/generator.go index 50990822..2463fa50 100644 --- a/yaml/generator.go +++ b/yaml/generator.go @@ -18,9 +18,6 @@ import ( //go:embed docker-compose-docker-lgtm-template.yml var lgtmTemplate []byte -//go:embed docker-compose-include-base.yml -var lgtmTemplateIncludeBase []byte - func CreateDockerComposeFile(r *Runner) string { p := filepath.Join(r.testCase.OutputDir, "docker-compose.yml") content := getContent(r) @@ -85,22 +82,8 @@ func getContent(r *Runner) []byte { files = append(files, name) } - t = template.Must(template.New("docker-compose-base").Parse(string(lgtmTemplateIncludeBase))) - buf = bytes.NewBufferString("") - vars = map[string]any{} - vars["files"] = files - err = t.Execute(buf, vars) - gomega.Expect(err).ToNot(gomega.HaveOccurred()) - f, err := os.CreateTemp("", "docker-compose-base.yml") - gomega.Expect(err).ToNot(gomega.HaveOccurred()) - _, err = f.Write(buf.Bytes()) - gomega.Expect(err).ToNot(gomega.HaveOccurred()) - defer func(name string) { - _ = os.Remove(name) - }(f.Name()) - - // uses docker compose to merge templates - args := []string{"compose", "-f", f.Name(), "config"} + // uses docker compose to merge templates (multiple -f flags allow service overrides) + args := buildComposeArgs(files, compose.Files) cmd := exec.Command("docker", args...) cmd.Env = env cmd.Stderr = os.Stderr @@ -112,6 +95,21 @@ func getContent(r *Runner) []byte { return content } +// buildComposeArgs constructs the docker compose arguments for merging compose +// files. When user compose files are present, --project-directory is set to the +// directory of the first user file so that relative paths resolve correctly. +func buildComposeArgs(generatedFiles []string, userFiles []string) []string { + args := []string{"compose"} + if len(userFiles) > 0 { + args = append(args, "--project-directory", filepath.Dir(userFiles[0])) + } + for _, file := range generatedFiles { + args = append(args, "-f", file) + } + args = append(args, "config") + return args +} + func joinComposeFiles(template []byte, addition []byte) ([]byte, error) { base := map[string]any{} add := map[string]any{} diff --git a/yaml/generator_test.go b/yaml/generator_test.go index d2af3a1c..8f7f006a 100644 --- a/yaml/generator_test.go +++ b/yaml/generator_test.go @@ -6,6 +6,31 @@ import ( "testing" ) +func TestBuildComposeArgs(t *testing.T) { + t.Run("without user files", func(t *testing.T) { + got := buildComposeArgs([]string{"/tmp/base.yml"}, nil) + require.Equal(t, []string{ + "compose", + "-f", "/tmp/base.yml", + "config", + }, got) + }) + + t.Run("with user files", func(t *testing.T) { + got := buildComposeArgs( + []string{"/tmp/base.yml", "/home/user/project/docker-compose-generated.yml"}, + []string{"/home/user/project/docker-compose.yml"}, + ) + require.Equal(t, []string{ + "compose", + "--project-directory", "/home/user/project", + "-f", "/tmp/base.yml", + "-f", "/home/user/project/docker-compose-generated.yml", + "config", + }, got) + }) +} + func TestJoinDockerComposeFiles(t *testing.T) { template, err := os.ReadFile("testdata/docker-compose-template.yaml") require.NoError(t, err)