From 16622fc3ed9cb8b0db4147e596c94f8bfd5ca221 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Thu, 16 May 2024 09:40:07 +0200 Subject: [PATCH] allow a local .env file to override compose.yaml sibling .env Signed-off-by: Nicolas De Loof --- cmd/compose/compose.go | 26 ++++++++++++++++++-------- pkg/e2e/compose_test.go | 21 +++++++++++++++++++++ pkg/e2e/fixtures/nested/.env | 2 ++ pkg/e2e/fixtures/nested/compose.yaml | 4 ++++ pkg/e2e/fixtures/nested/sub/.env | 2 ++ 5 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 pkg/e2e/fixtures/nested/.env create mode 100644 pkg/e2e/fixtures/nested/compose.yaml create mode 100644 pkg/e2e/fixtures/nested/sub/.env diff --git a/cmd/compose/compose.go b/cmd/compose/compose.go index 51f69f3da1..2a3c839fe1 100644 --- a/cmd/compose/compose.go +++ b/cmd/compose/compose.go @@ -384,7 +384,7 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli ctx := cmd.Context() // (1) process env vars - err := setEnvWithDotEnv(&opts) + err := setEnvWithLocalDotEnv(&opts) if err != nil { return err } @@ -594,18 +594,28 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli return c } -func setEnvWithDotEnv(prjOpts *ProjectOptions) error { - if len(prjOpts.EnvFiles) == 0 { - if envFiles := os.Getenv(ComposeEnvFiles); envFiles != "" { - prjOpts.EnvFiles = strings.Split(envFiles, ",") - } +// If user has a local .env file, load it as os.environment so it can be used to set COMPOSE_ variables +// This also allows to override values set by the default .env in a compose project when ran from a distinct folder +func setEnvWithLocalDotEnv(prjOpts *ProjectOptions) error { + if len(prjOpts.EnvFiles) > 0 { + return nil } - options, err := prjOpts.toProjectOptions() + wd, err := os.Getwd() if err != nil { return compose.WrapComposeError(err) } - envFromFile, err := dotenv.GetEnvFromFile(composegoutils.GetAsEqualsMap(os.Environ()), options.EnvFiles) + defaultDotEnv := filepath.Join(wd, ".env") + + s, err := os.Stat(defaultDotEnv) + if os.IsNotExist(err) || s.IsDir() { + return nil + } + if err != nil { + return err + } + + envFromFile, err := dotenv.GetEnvFromFile(composegoutils.GetAsEqualsMap(os.Environ()), []string{defaultDotEnv}) if err != nil { return err } diff --git a/pkg/e2e/compose_test.go b/pkg/e2e/compose_test.go index 75d546f730..e34156e808 100644 --- a/pkg/e2e/compose_test.go +++ b/pkg/e2e/compose_test.go @@ -329,3 +329,24 @@ func TestResolveDotEnv(t *testing.T) { Out: "image: backend:latest", }) } + +func TestNestedDotEnv(t *testing.T) { + c := NewCLI(t) + + cmd := c.NewDockerComposeCmd(t, "run", "echo") + cmd.Dir = filepath.Join(".", "fixtures", "nested") + res := icmd.RunCmd(cmd) + res.Assert(t, icmd.Expected{ + ExitCode: 0, + Out: "root win=root", + }) + + cmd = c.NewDockerComposeCmd(t, "run", "echo") + cmd.Dir = filepath.Join(".", "fixtures", "nested", "sub") + res = icmd.RunCmd(cmd) + res.Assert(t, icmd.Expected{ + ExitCode: 0, + Out: "root sub win=sub", + }) + +} diff --git a/pkg/e2e/fixtures/nested/.env b/pkg/e2e/fixtures/nested/.env new file mode 100644 index 0000000000..df2676a374 --- /dev/null +++ b/pkg/e2e/fixtures/nested/.env @@ -0,0 +1,2 @@ +ROOT=root +WIN=root \ No newline at end of file diff --git a/pkg/e2e/fixtures/nested/compose.yaml b/pkg/e2e/fixtures/nested/compose.yaml new file mode 100644 index 0000000000..d449f943f1 --- /dev/null +++ b/pkg/e2e/fixtures/nested/compose.yaml @@ -0,0 +1,4 @@ +services: + echo: + image: alpine + command: echo $ROOT $SUB win=$WIN diff --git a/pkg/e2e/fixtures/nested/sub/.env b/pkg/e2e/fixtures/nested/sub/.env new file mode 100644 index 0000000000..b930a81915 --- /dev/null +++ b/pkg/e2e/fixtures/nested/sub/.env @@ -0,0 +1,2 @@ +SUB=sub +WIN=sub