mirror of https://github.com/docker/compose.git
Fix dot env file to define COMPOSE_* variables
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
bf1bd3fc60
commit
10531f6302
|
@ -28,10 +28,8 @@ import (
|
|||
"syscall"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/cli"
|
||||
"github.com/compose-spec/compose-go/v2/dotenv"
|
||||
"github.com/compose-spec/compose-go/v2/loader"
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
composegoutils "github.com/compose-spec/compose-go/v2/utils"
|
||||
"github.com/docker/buildx/util/logutil"
|
||||
dockercli "github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli-plugins/manager"
|
||||
|
@ -329,11 +327,20 @@ func (o *ProjectOptions) toProjectOptions(po ...cli.ProjectOptionsFn) (*cli.Proj
|
|||
return cli.NewProjectOptions(o.ConfigPaths,
|
||||
append(po,
|
||||
cli.WithWorkingDirectory(o.ProjectDir),
|
||||
// First apply os.Environment, always win
|
||||
cli.WithOsEnv,
|
||||
// Load PWD/.env if present and no explicit --env-file has been set
|
||||
cli.WithEnvFiles(o.EnvFiles...),
|
||||
// read dot env file to populate project environment
|
||||
cli.WithDotEnv,
|
||||
// get compose file path set by COMPOSE_FILE
|
||||
cli.WithConfigFileEnv,
|
||||
// if none was selected, get default compose.yaml file from current dir or parent folder
|
||||
cli.WithDefaultConfigPath,
|
||||
// .. and then, a project directory != PWD maybe has been set so let's load .env file
|
||||
cli.WithEnvFiles(o.EnvFiles...),
|
||||
cli.WithDotEnv,
|
||||
// eventually COMPOSE_PROFILES should have been set
|
||||
cli.WithDefaultProfiles(o.Profiles...),
|
||||
cli.WithName(o.ProjectName))...)
|
||||
}
|
||||
|
@ -389,16 +396,8 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
|
|||
},
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
|
||||
// (1) process env vars
|
||||
err := setEnvWithLocalDotEnv(&opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parent := cmd.Root()
|
||||
|
||||
// (2) call parent pre-run
|
||||
// TODO(milas): this seems incorrect, remove or document
|
||||
if parent != nil {
|
||||
parentPrerun := parent.PersistentPreRunE
|
||||
if parentPrerun != nil {
|
||||
|
@ -409,7 +408,6 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
|
|||
}
|
||||
}
|
||||
|
||||
// (3) set up display/output
|
||||
if verbose {
|
||||
logrus.SetLevel(logrus.TraceLevel)
|
||||
}
|
||||
|
@ -469,7 +467,7 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
|
|||
}
|
||||
for i, file := range opts.EnvFiles {
|
||||
if !filepath.IsAbs(file) {
|
||||
file, err = filepath.Abs(file)
|
||||
file, err := filepath.Abs(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -500,8 +498,8 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
|
|||
backend.MaxConcurrency(parallel)
|
||||
}
|
||||
|
||||
// (5) dry run detection
|
||||
ctx, err = backend.DryRunMode(ctx, dryRun)
|
||||
// dry run detection
|
||||
ctx, err := backend.DryRunMode(ctx, dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -601,42 +599,6 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
|
|||
return c
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return compose.WrapComposeError(err)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
for k, v := range envFromFile {
|
||||
if _, ok := os.LookupEnv(k); !ok { // Precedence to OS Env
|
||||
if err := os.Setenv(k, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var printerModes = []string{
|
||||
ui.ModeAuto,
|
||||
ui.ModeTTY,
|
||||
|
|
5
go.mod
5
go.mod
|
@ -97,6 +97,7 @@ require (
|
|||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.0.0 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
|
@ -125,8 +126,6 @@ require (
|
|||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
|
@ -191,3 +190,5 @@ require (
|
|||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
tags.cncf.io/container-device-interface v0.7.2 // indirect
|
||||
)
|
||||
|
||||
replace github.com/compose-spec/compose-go/v2 => github.com/ndeloof/compose-go/v2 v2.0.1-0.20240606144025-9ba1fb10d14c
|
||||
|
|
10
go.sum
10
go.sum
|
@ -90,8 +90,6 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+g
|
|||
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
|
||||
github.com/compose-spec/compose-go/v2 v2.1.2-0.20240530052535-7dfa54c9658b h1:tjysHJZrxQVzGbklQsdYOjgZC9rVFa8Ersn82QP8H1M=
|
||||
github.com/compose-spec/compose-go/v2 v2.1.2-0.20240530052535-7dfa54c9658b/go.mod h1:bEPizBkIojlQ20pi2vNluBa58tevvj0Y18oUSHPyfdc=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
|
||||
|
@ -190,6 +188,8 @@ github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
|
|||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc=
|
||||
github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0=
|
||||
|
@ -320,15 +320,11 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex
|
|||
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
|
||||
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
|
||||
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/moby/buildkit v0.13.2 h1:nXNszM4qD9E7QtG7bFWPnDI1teUQFQglBzon/IU3SzI=
|
||||
github.com/moby/buildkit v0.13.2/go.mod h1:2cyVOv9NoHM7arphK9ZfHIWKn9YVZRFd1wXB8kKmEzY=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
|
@ -365,6 +361,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
|
|||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/ndeloof/compose-go/v2 v2.0.1-0.20240606144025-9ba1fb10d14c h1:VP4OJnRYZEwJFcxUCEKvn8cC855C7GiK8MmwdfP+m5I=
|
||||
github.com/ndeloof/compose-go/v2 v2.0.1-0.20240606144025-9ba1fb10d14c/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
|
||||
|
|
|
@ -318,18 +318,56 @@ func TestRemoveOrphaned(t *testing.T) {
|
|||
res.Assert(t, icmd.Expected{Out: fmt.Sprintf("%s-words-1", projectName)})
|
||||
}
|
||||
|
||||
func TestResolveDotEnv(t *testing.T) {
|
||||
func TestComposeFileSetByDotEnv(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
|
||||
cmd := c.NewDockerComposeCmd(t, "config")
|
||||
cmd.Dir = filepath.Join(".", "fixtures", "dotenv")
|
||||
res := icmd.RunCmd(cmd)
|
||||
res.Assert(t, icmd.Expected{
|
||||
ExitCode: 0,
|
||||
Out: "image: test:latest",
|
||||
})
|
||||
res.Assert(t, icmd.Expected{
|
||||
Out: "image: enabled:profile",
|
||||
})
|
||||
}
|
||||
|
||||
func TestComposeFileSetByProjectDirectory(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
|
||||
dir := filepath.Join(".", "fixtures", "dotenv", "development")
|
||||
cmd := c.NewDockerComposeCmd(t, "--project-directory", dir, "config")
|
||||
res := icmd.RunCmd(cmd)
|
||||
res.Assert(t, icmd.Expected{
|
||||
ExitCode: 0,
|
||||
Out: "image: backend:latest",
|
||||
})
|
||||
}
|
||||
|
||||
func TestComposeFileSetByEnvFile(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
|
||||
dotEnv, err := os.CreateTemp(t.TempDir(), ".env")
|
||||
assert.NilError(t, err)
|
||||
err = os.WriteFile(dotEnv.Name(), []byte(`
|
||||
COMPOSE_FILE=fixtures/dotenv/development/compose.yaml
|
||||
IMAGE_NAME=test
|
||||
IMAGE_TAG=latest
|
||||
COMPOSE_PROFILES=test
|
||||
`), 0o700)
|
||||
assert.NilError(t, err)
|
||||
|
||||
cmd := c.NewDockerComposeCmd(t, "--env-file", dotEnv.Name(), "config")
|
||||
res := icmd.RunCmd(cmd)
|
||||
res.Assert(t, icmd.Expected{
|
||||
Out: "image: test:latest",
|
||||
})
|
||||
res.Assert(t, icmd.Expected{
|
||||
Out: "image: enabled:profile",
|
||||
})
|
||||
}
|
||||
|
||||
func TestNestedDotEnv(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
COMPOSE_FILE="${COMPOSE_FILE:-development/compose.yaml}"
|
||||
COMPOSE_FILE="${COMPOSE_FILE:-development/compose.yaml}"
|
||||
IMAGE_NAME=test
|
||||
COMPOSE_PROFILES=test
|
|
@ -1,3 +1,7 @@
|
|||
services:
|
||||
backend:
|
||||
image: $IMAGE_NAME:$IMAGE_TAG
|
||||
test:
|
||||
profiles:
|
||||
- test
|
||||
image: enabled:profile
|
Loading…
Reference in New Issue