Skip to content

Commit cc56ae5

Browse files
authored
Merge pull request #280 from compose-spec/fix-env-vars
Fix lookup precedence
2 parents a317b17 + 748d531 commit cc56ae5

File tree

7 files changed

+73
-15
lines changed

7 files changed

+73
-15
lines changed

cli/options.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ func GetEnvFromFile(currentEnv map[string]string, workingDir string, filename st
242242
env, err := dotenv.ParseWithLookup(file, func(k string) (string, bool) {
243243
v, ok := currentEnv[k]
244244
if !ok {
245-
246245
return "", false
247246
}
248247
return v, true
@@ -251,9 +250,6 @@ func GetEnvFromFile(currentEnv map[string]string, workingDir string, filename st
251250
return envMap, err
252251
}
253252
for k, v := range env {
254-
if _, set := currentEnv[k]; set {
255-
continue
256-
}
257253
envMap[k] = v
258254
}
259255

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
OPTION_A=${OPTION_A:-1}
2+
OPTION_B=${OPTION_A}
3+
OPTION_C=$OPTION_B
4+
OPTION_D=${OPTION_A}_${OPTION_B}
5+
OPTION_E=${OPTION_NOT_DEFINED}

dotenv/fixtures/substitutions.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
OPTION_A=1
22
OPTION_B=${OPTION_A}
33
OPTION_C=$OPTION_B
4-
OPTION_D=${OPTION_A}${OPTION_B}
4+
OPTION_D=${OPTION_A}_${OPTION_B}
55
OPTION_E=${OPTION_NOT_DEFINED}

dotenv/godotenv_test.go

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ func TestSubstitutions(t *testing.T) {
218218
"OPTION_A": "1",
219219
"OPTION_B": "1",
220220
"OPTION_C": "1",
221-
"OPTION_D": "11",
221+
"OPTION_D": "1_1",
222222
"OPTION_E": "",
223223
}
224224

@@ -614,19 +614,77 @@ func TestExpendingEnvironmentWithLookup(t *testing.T) {
614614
}
615615
}
616616

617-
func TestSubstitutionsWithShellEnvPrecedence(t *testing.T) {
617+
func TestSubstitutionsWithEnvFilePrecedence(t *testing.T) {
618618
os.Clearenv()
619619
const envKey = "OPTION_A"
620620
const envVal = "5"
621621
os.Setenv(envKey, envVal)
622622
defer os.Unsetenv(envKey)
623623

624624
envFileName := "fixtures/substitutions.env"
625+
expectedValues := map[string]string{
626+
"OPTION_A": "1",
627+
"OPTION_B": "1",
628+
"OPTION_C": "1",
629+
"OPTION_D": "1_1",
630+
"OPTION_E": "",
631+
}
632+
633+
envMap, err := ReadWithLookup(os.LookupEnv, envFileName)
634+
if err != nil {
635+
t.Error("Error reading file")
636+
}
637+
if len(envMap) != len(expectedValues) {
638+
t.Error("Didn't get the right size map back")
639+
}
640+
641+
for key, value := range expectedValues {
642+
if envMap[key] != value {
643+
t.Errorf("Read got one of the keys wrong, [%q]->%q", key, envMap[key])
644+
}
645+
}
646+
}
647+
648+
func TestSubstitutionsWithEnvFileDefaultValuePrecedence(t *testing.T) {
649+
os.Clearenv()
650+
const envKey = "OPTION_A"
651+
const envVal = "5"
652+
os.Setenv(envKey, envVal)
653+
defer os.Unsetenv(envKey)
654+
655+
envFileName := "fixtures/substitutions-default.env"
625656
expectedValues := map[string]string{
626657
"OPTION_A": "5",
627658
"OPTION_B": "5",
628659
"OPTION_C": "5",
629-
"OPTION_D": "55",
660+
"OPTION_D": "5_5",
661+
"OPTION_E": "",
662+
}
663+
664+
envMap, err := ReadWithLookup(os.LookupEnv, envFileName)
665+
if err != nil {
666+
t.Error("Error reading file")
667+
}
668+
if len(envMap) != len(expectedValues) {
669+
t.Error("Didn't get the right size map back")
670+
}
671+
672+
for key, value := range expectedValues {
673+
if envMap[key] != value {
674+
t.Errorf("Read got one of the keys wrong, [%q]->%q", key, envMap[key])
675+
}
676+
}
677+
}
678+
679+
func TestSubstitutionsWithUnsetVarEnvFileDefaultValuePrecedence(t *testing.T) {
680+
os.Clearenv()
681+
682+
envFileName := "fixtures/substitutions-default.env"
683+
expectedValues := map[string]string{
684+
"OPTION_A": "1",
685+
"OPTION_B": "1",
686+
"OPTION_C": "1",
687+
"OPTION_D": "1_1",
630688
"OPTION_E": "",
631689
}
632690

dotenv/parser.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ func parseBytes(src []byte, out map[string]string, lookupFn LookupFn) error {
3737
}
3838

3939
if inherited {
40-
4140
value, ok := lookupFn(key)
4241
if ok {
4342
out[key] = value
@@ -50,9 +49,6 @@ func parseBytes(src []byte, out map[string]string, lookupFn LookupFn) error {
5049
if err != nil {
5150
return err
5251
}
53-
if lookUpValue, ok := lookupFn(key); ok {
54-
value = lookUpValue
55-
}
5652

5753
out[key] = value
5854
cutset = left

loader/full-struct_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ func services(workingDir, homeDir string) []types.ServiceConfig {
165165
Entrypoint: []string{"/code/entrypoint.sh", "-p", "3000"},
166166
Environment: map[string]*string{
167167
"FOO": strPtr("foo_from_env_file"),
168-
"BAR": strPtr("this is a secret"),
168+
"BAR": strPtr("bar_from_env_file_2"),
169169
"BAZ": strPtr("baz_from_service_def"),
170170
"QUX": strPtr("qux_from_environment"),
171171
"ENV.WITH.DOT": strPtr("ok"),
@@ -692,7 +692,7 @@ services:
692692
- -p
693693
- "3000"
694694
environment:
695-
BAR: this is a secret
695+
BAR: bar_from_env_file_2
696696
BAZ: baz_from_service_def
697697
ENV.WITH.DOT: ok
698698
ENV_WITH_UNDERSCORE: ok
@@ -1265,7 +1265,7 @@ func fullExampleJSON(workingDir, homeDir string) string {
12651265
"3000"
12661266
],
12671267
"environment": {
1268-
"BAR": "this is a secret",
1268+
"BAR": "bar_from_env_file_2",
12691269
"BAZ": "baz_from_service_def",
12701270
"ENV.WITH.DOT": "ok",
12711271
"ENV_WITH_UNDERSCORE": "ok",

loader/loader.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,9 @@ func resolveEnvironment(serviceConfig *types.ServiceConfig, workingDir string, l
624624
environment := types.MappingWithEquals{}
625625

626626
if len(serviceConfig.EnvFile) > 0 {
627+
if serviceConfig.Environment == nil {
628+
serviceConfig.Environment = types.MappingWithEquals{}
629+
}
627630
for _, envFile := range serviceConfig.EnvFile {
628631
filePath := absPath(workingDir, envFile)
629632
file, err := os.Open(filePath)

0 commit comments

Comments
 (0)