@@ -12,7 +12,7 @@ import (
1212
1313const whiteSpaces = " \t "
1414
15- func parseKeyValueFile (filename string , emptyFn func (string ) (string , bool )) ([]string , error ) {
15+ func parseKeyValueFile (filename string , lookupFn func (string ) (string , bool )) ([]string , error ) {
1616 fh , err := os .Open (filename )
1717 if err != nil {
1818 return []string {}, err
@@ -21,45 +21,48 @@ func parseKeyValueFile(filename string, emptyFn func(string) (string, bool)) ([]
2121
2222 lines := []string {}
2323 scanner := bufio .NewScanner (fh )
24- currentLine := 0
2524 utf8bom := []byte {0xEF , 0xBB , 0xBF }
26- for scanner .Scan () {
25+ for currentLine := 1 ; scanner .Scan (); currentLine ++ {
2726 scannedBytes := scanner .Bytes ()
2827 if ! utf8 .Valid (scannedBytes ) {
29- return []string {}, fmt .Errorf ("env file %s contains invalid utf8 bytes at line %d: %v" , filename , currentLine + 1 , scannedBytes )
28+ return []string {}, fmt .Errorf ("env file %s contains invalid utf8 bytes at line %d: %v" , filename , currentLine , scannedBytes )
3029 }
3130 // We trim UTF8 BOM
32- if currentLine == 0 {
31+ if currentLine == 1 {
3332 scannedBytes = bytes .TrimPrefix (scannedBytes , utf8bom )
3433 }
35- // trim the line from all leading whitespace first
34+ // trim the line from all leading whitespace first. trailing whitespace
35+ // is part of the value, and is kept unmodified.
3636 line := strings .TrimLeftFunc (string (scannedBytes ), unicode .IsSpace )
37- currentLine ++
38- // line is not empty, and not starting with '#'
39- if len (line ) > 0 && ! strings .HasPrefix (line , "#" ) {
40- variable , value , hasValue := strings .Cut (line , "=" )
4137
42- // trim the front of a variable, but nothing else
43- variable = strings .TrimLeft (variable , whiteSpaces )
44- if strings .ContainsAny (variable , whiteSpaces ) {
45- return []string {}, fmt .Errorf ("variable '%s' contains whitespaces" , variable )
46- }
47- if len (variable ) == 0 {
48- return []string {}, fmt .Errorf ("no variable name on line '%s'" , line )
49- }
38+ if len (line ) == 0 || line [0 ] == '#' {
39+ // skip empty lines and comments (lines starting with '#')
40+ continue
41+ }
42+
43+ key , _ , hasValue := strings .Cut (line , "=" )
44+ if len (key ) == 0 {
45+ return []string {}, fmt .Errorf ("no variable name on line '%s'" , line )
46+ }
47+
48+ // leading whitespace was already removed from the line, but
49+ // variables are not allowed to contain whitespace or have
50+ // trailing whitespace.
51+ if strings .ContainsAny (key , whiteSpaces ) {
52+ return []string {}, fmt .Errorf ("variable '%s' contains whitespaces" , key )
53+ }
54+
55+ if hasValue {
56+ // key/value pair is valid and has a value; add the line as-is.
57+ lines = append (lines , line )
58+ continue
59+ }
5060
51- if hasValue {
52- // pass the value through, no trimming
53- lines = append (lines , variable + "=" + value )
54- } else {
55- var present bool
56- if emptyFn != nil {
57- value , present = emptyFn (line )
58- }
59- if present {
60- // if only a pass-through variable is given, clean it up.
61- lines = append (lines , strings .TrimSpace (variable )+ "=" + value )
62- }
61+ if lookupFn != nil {
62+ // No value given; try to look up the value. The value may be
63+ // empty but if no value is found, the key is omitted.
64+ if value , found := lookupFn (line ); found {
65+ lines = append (lines , key + "=" + value )
6366 }
6467 }
6568 }
0 commit comments