Răsfoiți Sursa

add support for raw env_file format

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 1 an în urmă
părinte
comite
15bd0b0c5f

+ 22 - 0
cmd/compose/compose.go

@@ -21,6 +21,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"io"
 	"os"
 	"os/signal"
 	"path/filepath"
@@ -37,6 +38,7 @@ import (
 	dockercli "github.com/docker/cli/cli"
 	"github.com/docker/cli/cli-plugins/manager"
 	"github.com/docker/cli/cli/command"
+	"github.com/docker/cli/pkg/kvfile"
 	"github.com/docker/compose/v2/cmd/formatter"
 	"github.com/docker/compose/v2/internal/desktop"
 	"github.com/docker/compose/v2/internal/experimental"
@@ -70,6 +72,26 @@ const (
 	ComposeMenu = "COMPOSE_MENU"
 )
 
+// rawEnv load a dot env file using docker/cli key=value parser, without attempt to interpolate or evaluate values
+func rawEnv(r io.Reader, filename string, lookup func(key string) (string, bool)) (map[string]string, error) {
+	lines, err := kvfile.ParseFromReader(r, lookup)
+	if err != nil {
+		return nil, fmt.Errorf("failed to parse env_file %s: %w", filename, err)
+	}
+	vars := types.Mapping{}
+	for _, line := range lines {
+		key, value, _ := strings.Cut(line, "=")
+		vars[key] = value
+	}
+	return vars, nil
+}
+
+func init() {
+	// compose evaluates env file values for interpolation
+	// `raw` format allows to load env_file with the same parser used by docker run --env-file
+	dotenv.RegisterFormat("raw", rawEnv)
+}
+
 type Backend interface {
 	api.Service
 

+ 3 - 3
cmd/formatter/colors.go

@@ -21,7 +21,7 @@ import (
 	"strconv"
 	"sync"
 
-	"github.com/docker/compose/v2/pkg/api"
+	"github.com/docker/cli/cli/command"
 )
 
 var names = []string{
@@ -59,7 +59,7 @@ const (
 )
 
 // SetANSIMode configure formatter for colored output on ANSI-compliant console
-func SetANSIMode(streams api.Streams, ansi string) {
+func SetANSIMode(streams command.Streams, ansi string) {
 	if !useAnsi(streams, ansi) {
 		nextColor = func() colorFunc {
 			return monochrome
@@ -68,7 +68,7 @@ func SetANSIMode(streams api.Streams, ansi string) {
 	}
 }
 
-func useAnsi(streams api.Streams, ansi string) bool {
+func useAnsi(streams command.Streams, ansi string) bool {
 	switch ansi {
 	case Always:
 		return true

+ 1 - 1
go.mod

@@ -13,7 +13,7 @@ require (
 	github.com/davecgh/go-spew v1.1.1
 	github.com/distribution/reference v0.6.0
 	github.com/docker/buildx v0.17.1
-	github.com/docker/cli v27.3.1+incompatible
+	github.com/docker/cli v27.3.2-0.20241008150905-cb3048fbebb1+incompatible
 	github.com/docker/cli-docs-tool v0.8.0
 	github.com/docker/docker v27.3.1+incompatible
 	github.com/docker/go-connections v0.5.0

+ 2 - 2
go.sum

@@ -128,8 +128,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
 github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
 github.com/docker/buildx v0.17.1 h1:9ob2jGp4+W9PxWw68GsoNFp+eYFc7eUoRL9VljLCSM4=
 github.com/docker/buildx v0.17.1/go.mod h1:kJOhOhS47LRvrLFRulFiO5SE6VJf54yYMn7DzjgO5W0=
-github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ=
-github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/cli v27.3.2-0.20241008150905-cb3048fbebb1+incompatible h1:fJ3SzYiebfWoas3qOJpmRsNrDL2w1XIpPFywSLFhhfk=
+github.com/docker/cli v27.3.2-0.20241008150905-cb3048fbebb1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 github.com/docker/cli-docs-tool v0.8.0 h1:YcDWl7rQJC3lJ7WVZRwSs3bc9nka97QLWfyJQli8yJU=
 github.com/docker/cli-docs-tool v0.8.0/go.mod h1:8TQQ3E7mOXoYUs811LiPdUnAhXrcVsBIrW21a5pUbdk=
 github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=

+ 31 - 0
pkg/e2e/env_file_test.go

@@ -0,0 +1,31 @@
+/*
+   Copyright 2020 Docker Compose CLI authors
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package e2e
+
+import (
+	"strings"
+	"testing"
+
+	"gotest.tools/v3/assert"
+)
+
+func TestRawEnvFile(t *testing.T) {
+	c := NewParallelCLI(t)
+
+	res := c.RunDockerComposeCmd(t, "-f", "./fixtures/dotenv/raw.yaml", "run", "test")
+	assert.Equal(t, strings.TrimSpace(res.Stdout()), "'{\"key\": \"value\"}'")
+}

+ 1 - 0
pkg/e2e/fixtures/dotenv/.env.raw

@@ -0,0 +1 @@
+TEST_VAR='{"key": "value"}'

+ 7 - 0
pkg/e2e/fixtures/dotenv/raw.yaml

@@ -0,0 +1,7 @@
+services:
+  test:
+    image: alpine
+    command: sh -c "echo $$TEST_VAR"
+    env_file:
+      - path: .env.raw
+        format: raw # parse without interpolation