diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index 30e718a3a3..a17105f08e 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -32,6 +32,14 @@ type Options struct { SkipInterpolation bool // Interpolation options Interpolate *interp.Options + // Discard 'env_file' entries after resolving to 'environment' section + discardEnvFiles bool +} + +// WithDiscardEnvFiles sets the Options to discard the `env_file` section after resolving to +// the `environment` section +func WithDiscardEnvFiles(opts *Options) { + opts.discardEnvFiles = true } // ParseYAML reads the bytes from a file, parses the bytes into a mapping @@ -105,6 +113,11 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types. return nil, err } cfg.Filename = file.Filename + if opts.discardEnvFiles { + for i := range cfg.Services { + cfg.Services[i].EnvFile = nil + } + } configs = append(configs, cfg) } diff --git a/cli/compose/loader/loader_test.go b/cli/compose/loader/loader_test.go index 2d3cce4bc4..d956fb9f5f 100644 --- a/cli/compose/loader/loader_test.go +++ b/cli/compose/loader/loader_test.go @@ -759,6 +759,38 @@ services: assert.Check(t, is.DeepEqual([]string{"build", "links", "pid"}, unsupported)) } +func TestDiscardEnvFileOption(t *testing.T) { + dict, err := ParseYAML([]byte(`version: "3" +services: + web: + image: nginx + env_file: + - example1.env + - example2.env +`)) + expectedEnvironmentMap := types.MappingWithEquals{ + "FOO": strPtr("foo_from_env_file"), + "BAZ": strPtr("baz_from_env_file"), + "BAR": strPtr("bar_from_env_file_2"), // Original value is overwritten by example2.env + "QUX": strPtr("quz_from_env_file_2"), + } + assert.NilError(t, err) + configDetails := buildConfigDetails(dict, nil) + + // Default behavior keeps the `env_file` entries + configWithEnvFiles, err := Load(configDetails) + assert.NilError(t, err) + assert.DeepEqual(t, configWithEnvFiles.Services[0].EnvFile, types.StringList{"example1.env", + "example2.env"}) + assert.DeepEqual(t, configWithEnvFiles.Services[0].Environment, expectedEnvironmentMap) + + // Custom behavior removes the `env_file` entries + configWithoutEnvFiles, err := Load(configDetails, WithDiscardEnvFiles) + assert.NilError(t, err) + assert.DeepEqual(t, configWithoutEnvFiles.Services[0].EnvFile, types.StringList(nil)) + assert.DeepEqual(t, configWithoutEnvFiles.Services[0].Environment, expectedEnvironmentMap) +} + func TestBuildProperties(t *testing.T) { dict, err := ParseYAML([]byte(` version: "3"