Skip to content

Commit b36ef2e

Browse files
committed
fix bug with envloader when there are empty overwrites
1 parent 15df20f commit b36ef2e

File tree

4 files changed

+51
-29
lines changed

4 files changed

+51
-29
lines changed

envloader/envloader.go

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,38 +28,51 @@ func LoadEnvs(folderPath string) error {
2828
customConfigPath := path.Join(folderPath, stage+".env")
2929
defaultConfigPath := path.Join(folderPath, DefaultEnvFile)
3030

31-
missingEnvs := []string{}
32-
combinedEnvMap, err := createCombinedEnvMap(customConfigPath, defaultConfigPath)
31+
err := checkForMissingEnvs(customConfigPath, defaultConfigPath)
3332
if err != nil {
3433
return err
3534
}
3635

37-
for envName, value := range combinedEnvMap {
38-
if value == "" && os.Getenv(envName) == "" {
39-
missingEnvs = append(missingEnvs, envName)
40-
}
41-
}
42-
if len(missingEnvs) > 0 {
43-
return fmt.Errorf("environment variables missing: %v", missingEnvs)
44-
}
4536
return godotenv.Load(customConfigPath, defaultConfigPath)
4637
}
4738

48-
func createCombinedEnvMap(customConfigPath string, defaultConfigPath string) (map[string]string, error) {
39+
// checkForMissingEnvs errors if an env was defined in the default but not set in
40+
// either the default file, custom config file or environment variables.
41+
// Returns nil otherwise.
42+
func checkForMissingEnvs(customConfigPath string, defaultConfigPath string) error {
4943
envMapCustom, err := godotenv.Read(customConfigPath)
5044
if err != nil {
51-
return nil, err
45+
return fmt.Errorf("error reading custom config file: %w", err)
5246
}
5347
envMapDefault, err := godotenv.Read(defaultConfigPath)
5448
if err != nil {
55-
return nil, err
49+
return fmt.Errorf("error reading default config file: %w", err)
50+
}
51+
52+
fmt.Println(envMapCustom)
53+
fmt.Println(envMapDefault)
54+
55+
envMapCombined := map[string]string{}
56+
for key, value := range envMapCustom {
57+
envMapCombined[key] = value
5658
}
5759

58-
envMapCombined := envMapCustom
5960
for key, value := range envMapDefault {
6061
if envMapCombined[key] == "" {
6162
envMapCombined[key] = value
6263
}
6364
}
64-
return envMapCombined, nil
65+
66+
missingEnvs := []string{}
67+
for envName, value := range envMapCombined {
68+
_, keyPresentInCustomEnvs := envMapCustom[envName]
69+
if value == "" && os.Getenv(envName) == "" && !keyPresentInCustomEnvs {
70+
missingEnvs = append(missingEnvs, envName)
71+
}
72+
}
73+
if len(missingEnvs) > 0 {
74+
return fmt.Errorf("environment variables missing: %v", missingEnvs)
75+
}
76+
77+
return nil
6578
}

envloader/envloader_test.go

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ import (
99
)
1010

1111
func TestLoadingDefaults(t *testing.T) {
12+
defer cleanup(t)
1213
err := LoadEnvs("testdata")
1314
if assert.NoError(t, err) {
1415
assert.Equal(t, "defaultValue1", os.Getenv("ENVLOADER_TESTKEY1"))
1516
assert.Equal(t, "defaultValue2", os.Getenv("ENVLOADER_TESTKEY2"))
1617
}
17-
assert.NoError(t, cleanup())
1818
}
1919

2020
func TestOverwritingDefaultsWithCustomsSuccess(t *testing.T) {
21+
defer cleanup(t)
2122
DefaultEnvFile = "production_missing.env"
2223
StageEnv = "ENVLOADER_APP_ENV"
2324
err := os.Setenv("ENVLOADER_APP_ENV", "teststage_success")
@@ -28,10 +29,10 @@ func TestOverwritingDefaultsWithCustomsSuccess(t *testing.T) {
2829
assert.Equal(t, "customValue2", os.Getenv("ENVLOADER_TESTKEY2"))
2930
assert.Equal(t, "customValue3", os.Getenv("ENVLOADER_TESTKEY3"))
3031
}
31-
assert.NoError(t, cleanup())
3232
}
3333

3434
func TestNotOverwritingExistingEnvs(t *testing.T) {
35+
defer cleanup(t)
3536
err := os.Setenv("ENVLOADER_TESTKEY1", "outerValue1")
3637
assert.NoError(t, err)
3738
err = os.Setenv("ENVLOADER_TESTKEY2", "outerValue2")
@@ -48,10 +49,10 @@ func TestNotOverwritingExistingEnvs(t *testing.T) {
4849
assert.Equal(t, "outerValue2", os.Getenv("ENVLOADER_TESTKEY2"))
4950
assert.Equal(t, "customValue3", os.Getenv("ENVLOADER_TESTKEY3"))
5051
}
51-
assert.NoError(t, cleanup())
5252
}
5353

5454
func TestOverwritingDefaultsWithCustomsFail(t *testing.T) {
55+
defer cleanup(t)
5556
DefaultEnvFile = "production_missing.env"
5657
StageEnv = "ENVLOADER_APP_ENV"
5758
err := os.Setenv("ENVLOADER_APP_ENV", "teststage_fail")
@@ -60,27 +61,35 @@ func TestOverwritingDefaultsWithCustomsFail(t *testing.T) {
6061
if assert.Error(t, err) {
6162
assert.Equal(t, "environment variables missing: [ENVLOADER_TESTKEY3]", err.Error())
6263
}
63-
assert.NoError(t, cleanup())
64+
}
65+
66+
func TestOverwriteEmptyDefaultWithEmptyValue(t *testing.T) {
67+
defer cleanup(t)
68+
DefaultEnvFile = "production_missing.env"
69+
StageEnv = "ENVLOADER_APP_ENV"
70+
err := os.Setenv("ENVLOADER_APP_ENV", "empty_overwrite")
71+
assert.NoError(t, err)
72+
err = LoadEnvs("testdata")
73+
assert.NoError(t, err)
74+
assert.Equal(t, "", os.Getenv("ENVLOADER_TESTKEY3"))
6475
}
6576

6677
func TestMissingEnvsAreDetected(t *testing.T) {
78+
defer cleanup(t)
79+
DefaultEnvFile = "production_missing.env"
6780
StageEnv = "ENVLOADER_APP_ENV"
6881
err := os.Setenv("ENVLOADER_APP_ENV", "missing")
6982
assert.NoError(t, err)
7083
err = LoadEnvs("testdata")
71-
assert.Equal(t, "environment variables missing: [ENVLOADER_TESTKEY4]", err.Error())
72-
assert.NoError(t, cleanup())
84+
assert.Error(t, err)
85+
assert.Equal(t, "environment variables missing: [ENVLOADER_TESTKEY3]", err.Error())
7386
}
7487

75-
func cleanup() error {
88+
func cleanup(t *testing.T) {
7689
for _, line := range os.Environ() {
7790
if strings.HasPrefix(line, "ENVLOADER") {
7891
pair := strings.Split(line, "=")
79-
err := os.Unsetenv(pair[0])
80-
if err != nil {
81-
return err
82-
}
92+
assert.NoError(t, os.Unsetenv(pair[0]))
8393
}
8494
}
85-
return nil
8695
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ENVLOADER_TESTKEY3=""

envloader/testdata/missing.env

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
ENVLOADER_TESTKEY4=
2-
ENVLOADER_TESTKEY3=customValue3
1+
ENVLOADER_TESTKEY4=customValue4

0 commit comments

Comments
 (0)