Skip to content

Commit

Permalink
local environment to override included .env
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <[email protected]>
  • Loading branch information
ndeloof committed Aug 25, 2023
1 parent ae43465 commit 15210d9
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 12 deletions.
8 changes: 2 additions & 6 deletions cli/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type ProjectOptions struct {
// NOTE: For security, the loader does not automatically expose any
// process environment variables. For convenience, WithOsEnv can be
// used if appropriate.
Environment map[string]string
Environment types.Mapping

// EnvFiles are file paths to ".env" files with additional environment
// variable data.
Expand Down Expand Up @@ -256,11 +256,7 @@ func WithDotEnv(o *ProjectOptions) error {
if err != nil {
return err
}
for k, v := range envMap {
if _, set := o.Environment[k]; !set {
o.Environment[k] = v
}
}
o.Environment.Merge(envMap)
return nil
}

Expand Down
7 changes: 4 additions & 3 deletions cli/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"path/filepath"
"testing"

"github.com/compose-spec/compose-go/types"
"gotest.tools/v3/assert"

"github.com/compose-spec/compose-go/consts"
Expand Down Expand Up @@ -314,13 +315,13 @@ func TestEnvVariablePrecedence(t *testing.T) {
name string
dotEnv string
osEnv []string
expected map[string]string
expected types.Mapping
}{
{
"no value set in environment",
"FOO=foo\nBAR=${FOO}",
nil,
map[string]string{
types.Mapping{
"FOO": "foo",
"BAR": "foo",
},
Expand All @@ -329,7 +330,7 @@ func TestEnvVariablePrecedence(t *testing.T) {
"conflict with value set in environment",
"FOO=foo\nBAR=${FOO}",
[]string{"FOO=zot"},
map[string]string{
types.Mapping{
"FOO": "zot",
"BAR": "zot",
},
Expand Down
4 changes: 2 additions & 2 deletions loader/include.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ func loadInclude(ctx context.Context, filename string, configDetails types.Confi
loadOptions.SkipNormalization = true
loadOptions.SkipConsistencyCheck = true

env, err := dotenv.GetEnvFromFile(configDetails.Environment, r.ProjectDirectory, r.EnvFile)
envFromFile, err := dotenv.GetEnvFromFile(configDetails.Environment, r.ProjectDirectory, r.EnvFile)
if err != nil {
return nil, nil, err
}

config := types.ConfigDetails{
WorkingDir: r.ProjectDirectory,
ConfigFiles: types.ToConfigFiles(r.Path),
Environment: env,
Environment: configDetails.Environment.Clone().Merge(envFromFile),
}
loadOptions.Interpolate = &interp.Options{
Substitute: options.Interpolate.Substitute,
Expand Down
19 changes: 19 additions & 0 deletions loader/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2555,6 +2555,25 @@ services:
},
})
assert.NilError(t, err)

p, err = Load(buildConfigDetails(`
name: 'test-include'
include:
- path: ./testdata/subdir/compose-test-extends-imported.yaml
env_file: ./testdata/subdir/extra.env
services:
foo:
image: busybox
depends_on:
- imported
`, map[string]string{"SOURCE": "override"}), func(options *Options) {
options.SkipNormalization = true
options.ResolvePaths = true
})
assert.NilError(t, err)
assert.Equal(t, p.Services[1].ContainerName, "override")
}

func TestLoadWithIncludeCycle(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type ConfigDetails struct {
Version string
WorkingDir string
ConfigFiles []ConfigFile
Environment map[string]string
Environment Mapping
}

// LookupEnv provides a lookup function for environment variables
Expand Down
18 changes: 18 additions & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,24 @@ func (m Mapping) Resolve(s string) (string, bool) {
return v, ok
}

func (m Mapping) Clone() Mapping {
clone := Mapping{}
for k, v := range m {
clone[k] = v
}
return clone
}

// Merge adds all values from second mapping which are not already defined
func (m Mapping) Merge(o Mapping) Mapping {
for k, v := range o {
if _, set := m[k]; !set {
m[k] = v
}
}
return m
}

// Labels is a mapping type for labels
type Labels map[string]string

Expand Down

0 comments on commit 15210d9

Please sign in to comment.