Skip to content

Commit 4ed1339

Browse files
committed
Merge pull request #13 from jmervine/master
Add Overload methods.
2 parents 443e926 + 008304c commit 4ed1339

File tree

2 files changed

+81
-9
lines changed

2 files changed

+81
-9
lines changed

godotenv.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,30 @@ func Load(filenames ...string) (err error) {
3636
filenames = filenamesOrDefault(filenames)
3737

3838
for _, filename := range filenames {
39-
err = loadFile(filename)
39+
err = loadFile(filename, false)
40+
if err != nil {
41+
return // return early on a spazout
42+
}
43+
}
44+
return
45+
}
46+
47+
// Overload will read your env file(s) and load them into ENV for this process.
48+
//
49+
// Call this function as close as possible to the start of your program (ideally in main)
50+
//
51+
// If you call Overload without any args it will default to loading .env in the current path
52+
//
53+
// You can otherwise tell it which files to load (there can be more than one) like
54+
//
55+
// godotenv.Overload("fileone", "filetwo")
56+
//
57+
// It's important to note this WILL OVERRIDE an env variable that already exists - consider the .env file to forcefilly set all vars.
58+
func Overload(filenames ...string) (err error) {
59+
filenames = filenamesOrDefault(filenames)
60+
61+
for _, filename := range filenames {
62+
err = loadFile(filename, true)
4063
if err != nil {
4164
return // return early on a spazout
4265
}
@@ -90,14 +113,14 @@ func filenamesOrDefault(filenames []string) []string {
90113
return filenames
91114
}
92115

93-
func loadFile(filename string) error {
116+
func loadFile(filename string, overload bool) error {
94117
envMap, err := readFile(filename)
95118
if err != nil {
96119
return err
97120
}
98121

99122
for key, value := range envMap {
100-
if os.Getenv(key) == "" {
123+
if os.Getenv(key) == "" || overload {
101124
os.Setenv(key, value)
102125
}
103126
}

godotenv_test.go

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,24 @@ import (
55
"testing"
66
)
77

8+
var noopPresets = make(map[string]string)
9+
810
func parseAndCompare(t *testing.T, rawEnvLine string, expectedKey string, expectedValue string) {
911
key, value, _ := parseLine(rawEnvLine)
1012
if key != expectedKey || value != expectedValue {
1113
t.Errorf("Expected '%v' to parse as '%v' => '%v', got '%v' => '%v' instead", rawEnvLine, expectedKey, expectedValue, key, value)
1214
}
1315
}
1416

15-
func loadEnvAndCompareValues(t *testing.T, envFileName string, expectedValues map[string]string) {
17+
func loadEnvAndCompareValues(t *testing.T, loader func(files ...string) error, envFileName string, expectedValues map[string]string, presets map[string]string) {
1618
// first up, clear the env
1719
os.Clearenv()
1820

19-
err := Load(envFileName)
21+
for k, v := range presets {
22+
os.Setenv(k, v)
23+
}
24+
25+
err := loader(envFileName)
2026
if err != nil {
2127
t.Fatalf("Error loading %v", envFileName)
2228
}
@@ -38,13 +44,28 @@ func TestLoadWithNoArgsLoadsDotEnv(t *testing.T) {
3844
}
3945
}
4046

47+
func TestOverloadWithNoArgsOverloadsDotEnv(t *testing.T) {
48+
err := Overload()
49+
pathError := err.(*os.PathError)
50+
if pathError == nil || pathError.Op != "open" || pathError.Path != ".env" {
51+
t.Errorf("Didn't try and open .env by default")
52+
}
53+
}
54+
4155
func TestLoadFileNotFound(t *testing.T) {
4256
err := Load("somefilethatwillneverexistever.env")
4357
if err == nil {
4458
t.Error("File wasn't found but Load didn't return an error")
4559
}
4660
}
4761

62+
func TestOverloadFileNotFound(t *testing.T) {
63+
err := Overload("somefilethatwillneverexistever.env")
64+
if err == nil {
65+
t.Error("File wasn't found but Overload didn't return an error")
66+
}
67+
}
68+
4869
func TestReadPlainEnv(t *testing.T) {
4970
envFileName := "fixtures/plain.env"
5071
expectedValues := map[string]string{
@@ -71,6 +92,34 @@ func TestReadPlainEnv(t *testing.T) {
7192
}
7293
}
7394

95+
func TestLoadDoesNotOverride(t *testing.T) {
96+
envFileName := "fixtures/plain.env"
97+
98+
// ensure NO overload
99+
presets := map[string]string{
100+
"OPTION_A": "do_not_override",
101+
}
102+
103+
expectedValues := map[string]string{
104+
"OPTION_A": "do_not_override",
105+
}
106+
loadEnvAndCompareValues(t, Load, envFileName, expectedValues, presets)
107+
}
108+
109+
func TestOveroadDoesOverride(t *testing.T) {
110+
envFileName := "fixtures/plain.env"
111+
112+
// ensure NO overload
113+
presets := map[string]string{
114+
"OPTION_A": "do_not_override",
115+
}
116+
117+
expectedValues := map[string]string{
118+
"OPTION_A": "1",
119+
}
120+
loadEnvAndCompareValues(t, Overload, envFileName, expectedValues, presets)
121+
}
122+
74123
func TestLoadPlainEnv(t *testing.T) {
75124
envFileName := "fixtures/plain.env"
76125
expectedValues := map[string]string{
@@ -81,7 +130,7 @@ func TestLoadPlainEnv(t *testing.T) {
81130
"OPTION_E": "5",
82131
}
83132

84-
loadEnvAndCompareValues(t, envFileName, expectedValues)
133+
loadEnvAndCompareValues(t, Load, envFileName, expectedValues, noopPresets)
85134
}
86135

87136
func TestLoadExportedEnv(t *testing.T) {
@@ -91,7 +140,7 @@ func TestLoadExportedEnv(t *testing.T) {
91140
"OPTION_B": "\n",
92141
}
93142

94-
loadEnvAndCompareValues(t, envFileName, expectedValues)
143+
loadEnvAndCompareValues(t, Load, envFileName, expectedValues, noopPresets)
95144
}
96145

97146
func TestLoadEqualsEnv(t *testing.T) {
@@ -100,7 +149,7 @@ func TestLoadEqualsEnv(t *testing.T) {
100149
"OPTION_A": "postgres://localhost:5432/database?sslmode=disable",
101150
}
102151

103-
loadEnvAndCompareValues(t, envFileName, expectedValues)
152+
loadEnvAndCompareValues(t, Load, envFileName, expectedValues, noopPresets)
104153
}
105154

106155
func TestLoadQuotedEnv(t *testing.T) {
@@ -116,7 +165,7 @@ func TestLoadQuotedEnv(t *testing.T) {
116165
"OPTION_H": "\n",
117166
}
118167

119-
loadEnvAndCompareValues(t, envFileName, expectedValues)
168+
loadEnvAndCompareValues(t, Load, envFileName, expectedValues, noopPresets)
120169
}
121170

122171
func TestActualEnvVarsAreLeftAlone(t *testing.T) {

0 commit comments

Comments
 (0)