Skip to content
This repository was archived by the owner on Jan 12, 2022. It is now read-only.

Commit 26a1e37

Browse files
authored
Merge pull request #9 from tbocek/master
2 parents 34f08db + 14dde87 commit 26a1e37

File tree

3 files changed

+44
-14
lines changed

3 files changed

+44
-14
lines changed

godotenv.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ func readFile(filename string, lookupFn LookupFn) (envMap map[string]string, err
231231
var exportRegex = regexp.MustCompile(`^\s*(?:export\s+)?(.*?)\s*$`)
232232

233233
func parseLine(line string, envMap map[string]string) (key string, value string, err error) {
234+
return parseLineWithLookup(line, envMap, nil)
235+
}
236+
func parseLineWithLookup(line string, envMap map[string]string, lookupFn LookupFn) (key string, value string, err error) {
234237
if len(line) == 0 {
235238
err = errors.New("zero length string")
236239
return
@@ -274,7 +277,7 @@ func parseLine(line string, envMap map[string]string) (key string, value string,
274277
key = exportRegex.ReplaceAllString(splitString[0], "$1")
275278

276279
// Parse the value
277-
value = parseValue(splitString[1], envMap)
280+
value = parseValue(splitString[1], envMap, lookupFn)
278281
return
279282
}
280283

@@ -285,7 +288,7 @@ var (
285288
unescapeCharsRegex = regexp.MustCompile(`\\([^$])`)
286289
)
287290

288-
func parseValue(value string, envMap map[string]string) string {
291+
func parseValue(value string, envMap map[string]string, lookupFn LookupFn) string {
289292

290293
// trim
291294
value = strings.Trim(value, " ")
@@ -319,7 +322,7 @@ func parseValue(value string, envMap map[string]string) string {
319322
}
320323

321324
if singleQuotes == nil {
322-
value = expandVariables(value, envMap)
325+
value = expandVariables(value, envMap, lookupFn)
323326
}
324327
}
325328

@@ -328,7 +331,7 @@ func parseValue(value string, envMap map[string]string) string {
328331

329332
var expandVarRegex = regexp.MustCompile(`(\\)?(\$)(\()?\{?([A-Z0-9_]+)?\}?`)
330333

331-
func expandVariables(v string, m map[string]string) string {
334+
func expandVariables(v string, envMap map[string]string, lookupFn LookupFn) string {
332335
return expandVarRegex.ReplaceAllStringFunc(v, func(s string) string {
333336
submatch := expandVarRegex.FindStringSubmatch(s)
334337

@@ -338,7 +341,20 @@ func expandVariables(v string, m map[string]string) string {
338341
if submatch[1] == "\\" || submatch[2] == "(" {
339342
return submatch[0][1:]
340343
} else if submatch[4] != "" {
341-
return m[submatch[4]]
344+
//first check if we have defined this already earlier
345+
if envMap[submatch[4]] != "" {
346+
return envMap[submatch[4]]
347+
}
348+
if lookupFn == nil {
349+
return ""
350+
}
351+
//if we have not defined it, check the lookup function provided
352+
//by the user
353+
s2, ok := lookupFn(submatch[4])
354+
if ok {
355+
return s2
356+
}
357+
return ""
342358
}
343359
return s
344360
})

godotenv_test.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -514,8 +514,8 @@ func TestInheritedEnvVariablSameSize(t *testing.T) {
514514
envFileName := "fixtures/inherited-multi-var.env"
515515
expectedValues := map[string]string{
516516
envKey: envVal,
517-
"foo": "bar",
518-
"bar": "baz",
517+
"foo": "bar",
518+
"bar": "baz",
519519
}
520520

521521
envMap, err := ReadWithLookup(os.LookupEnv, envFileName)
@@ -565,7 +565,7 @@ func TestInheritedEnvVariableNotFound(t *testing.T) {
565565

566566
func TestInheritedEnvVariableNotFoundWithLookup(t *testing.T) {
567567
notFoundMap := make(map[string]interface{})
568-
envMap, err := ReadWithLookup(func(v string)(string, bool){
568+
envMap, err := ReadWithLookup(func(v string) (string, bool) {
569569
envVar, ok := os.LookupEnv(v)
570570
if !ok {
571571
notFoundMap[v] = nil
@@ -579,4 +579,18 @@ func TestInheritedEnvVariableNotFoundWithLookup(t *testing.T) {
579579
if !ok {
580580
t.Errorf("Expected 'VARIABLE_NOT_FOUND' to be in the set of not found variables")
581581
}
582-
}
582+
}
583+
584+
func TestExpendingEnvironmentWithLookup(t *testing.T) {
585+
rawEnvLine := "TEST=$ME"
586+
expectedValue := "YES"
587+
key, value, _ := parseLineWithLookup(rawEnvLine, noopPresets, func(s string) (string, bool) {
588+
if s == "ME" {
589+
return expectedValue, true
590+
}
591+
return "NO", false
592+
})
593+
if value != "YES" {
594+
t.Errorf("Expected '%v' to parse as '%v' => '%v', got '%v' => '%v' instead", rawEnvLine, key, expectedValue, key, value)
595+
}
596+
}

parser.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func parseBytes(src []byte, out map[string]string, lookupFn LookupFn) error {
4646
}
4747
}
4848

49-
value, left, err := extractVarValue(left, out)
49+
value, left, err := extractVarValue(left, out, lookupFn)
5050
if err != nil {
5151
return err
5252
}
@@ -126,16 +126,16 @@ loop:
126126
}
127127

128128
// extractVarValue extracts variable value and returns rest of slice
129-
func extractVarValue(src []byte, vars map[string]string) (value string, rest []byte, err error) {
129+
func extractVarValue(src []byte, envMap map[string]string, lookupFn LookupFn) (value string, rest []byte, err error) {
130130
quote, hasPrefix := hasQuotePrefix(src)
131131
if !hasPrefix {
132132
// unquoted value - read until whitespace
133133
end := bytes.IndexFunc(src, unicode.IsSpace)
134134
if end == -1 {
135-
return expandVariables(string(src), vars), nil, nil
135+
return expandVariables(string(src), envMap, lookupFn), nil, nil
136136
}
137137

138-
return expandVariables(string(src[0:end]), vars), src[end:], nil
138+
return expandVariables(string(src[0:end]), envMap, lookupFn), src[end:], nil
139139
}
140140

141141
// lookup quoted string terminator
@@ -155,7 +155,7 @@ func extractVarValue(src []byte, vars map[string]string) (value string, rest []b
155155
if quote == prefixDoubleQuote {
156156
// unescape newlines for double quote (this is compat feature)
157157
// and expand environment variables
158-
value = expandVariables(expandEscapes(value), vars)
158+
value = expandVariables(expandEscapes(value), envMap, lookupFn)
159159
}
160160

161161
return value, src[i+1:], nil

0 commit comments

Comments
 (0)