Skip to content

Commit

Permalink
Fix nested include with env files
Browse files Browse the repository at this point in the history
Signed-off-by: Vigilans <[email protected]>
  • Loading branch information
Vigilans committed Dec 19, 2024
1 parent 20738c5 commit 3107e23
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 12 deletions.
31 changes: 19 additions & 12 deletions loader/include.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,28 +109,35 @@ func ApplyInclude(ctx context.Context, workingDir string, environment types.Mapp
WorkingDir: r.ProjectDirectory,
})

envFile := r.EnvFile
if len(r.EnvFile) == 0 {
f := filepath.Join(r.ProjectDirectory, ".env")
if s, err := os.Stat(f); err == nil && !s.IsDir() {
r.EnvFile = types.StringList{f}
}
} else {
envFile := []string{}
for _, f := range r.EnvFile {
if !filepath.IsAbs(f) {
f = filepath.Join(workingDir, f)
s, err := os.Stat(f)
envFile = types.StringList{".env"}
}

resolvedEnvFile := []string{}
for _, f := range envFile {
for _, loader := range options.ResourceLoaders {
if loader.Accept(f) {
path, err := loader.Load(ctx, f)
if err != nil {
return err
}
s, err := os.Stat(path)
if os.IsNotExist(err) && len(r.EnvFile) == 0 {
break // Skip if default .env not found
}
if err != nil {
return err
}
if s.IsDir() {
return fmt.Errorf("%s is not a file", f)
}
resolvedEnvFile = append(resolvedEnvFile, path)
break
}
envFile = append(envFile, f)
}
r.EnvFile = envFile
}
r.EnvFile = resolvedEnvFile

envFromFile, err := dotenv.GetEnvFromFile(environment, r.EnvFile)
if err != nil {
Expand Down
79 changes: 79 additions & 0 deletions loader/include_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,85 @@ services:

}

func TestLoadWithIncludeEnvTripleTimes(t *testing.T) {
fileName := "compose.yml"
tmpdir := t.TempDir()
// file in root
yaml := `
include:
- path:
- ./module/compose.yml
env_file:
- ./custom.env
services:
a:
image: alpine
environment:
- VAR_NAME`
createFile(t, tmpdir, `VAR_NAME=value`, "custom.env")
path := createFile(t, tmpdir, yaml, fileName)
// file in /module
yaml = `
include:
- path:
- ./submodule/compose.yml
env_file:
- ../custom.env
services:
b:
image: alpine
environment:
- VAR_NAME`
createFileSubDir(t, tmpdir, "module", yaml, fileName)

yaml = `
include:
- path:
- ./subsubmodule/compose.yml
env_file:
- ../../custom.env
services:
c:
image: alpine
environment:
- VAR_NAME`
createFileSubDir(t, tmpdir, "module/submodule", yaml, fileName)

yaml = `
services:
d:
image: alpine
environment:
- VAR_NAME`
createFileSubDir(t, tmpdir, "module/submodule/subsubmodule", yaml, fileName)

p, err := Load(types.ConfigDetails{
WorkingDir: tmpdir,
ConfigFiles: []types.ConfigFile{{
Filename: path,
}},
Environment: nil,
}, func(options *Options) {
options.SkipNormalization = true
options.ResolvePaths = true
options.SetProjectName("project", true)
})
assert.NilError(t, err)
a := p.Services["a"]
// make sure VAR_NAME is only accessible in include context
assert.Check(t, a.Environment["VAR_NAME"] == nil, "VAR_NAME should not be defined in environment")
b := p.Services["b"]
assert.Check(t, b.Environment["VAR_NAME"] != nil, "VAR_NAME is not defined in environment")
assert.Equal(t, *b.Environment["VAR_NAME"], "value")
c := p.Services["c"]
assert.Check(t, c.Environment["VAR_NAME"] != nil, "VAR_NAME is not defined in environment")
assert.Equal(t, *c.Environment["VAR_NAME"], "value")
d := p.Services["d"]
assert.Check(t, d.Environment["VAR_NAME"] != nil, "VAR_NAME is not defined in environment")
assert.Equal(t, *d.Environment["VAR_NAME"], "value")

}

func TestIncludeWithProjectDirectory(t *testing.T) {
var envs map[string]string
if runtime.GOOS == "windows" {
Expand Down

0 comments on commit 3107e23

Please sign in to comment.