add support for raw env_file format

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2024-10-02 07:52:51 +02:00 коммит произвёл Nicolas De loof
Родитель 39d0f6477e
Коммит 15bd0b0c5f
7 изменённых файлов: 67 добавлений и 6 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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

2
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

4
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
pkg/e2e/env_file_test.go Normal file
Просмотреть файл

@ -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\"}'")
}

Просмотреть файл

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

Просмотреть файл

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