Skip to content

Commit 9dee12f

Browse files
authored
Merge pull request #5496 from thaJeztah/parseKeyValueFile_refactor
opts: parseKeyValueFile: cleanup and remove redundant trimming
2 parents dac7319 + 76196db commit 9dee12f

1 file changed

Lines changed: 33 additions & 30 deletions

File tree

opts/file.go

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212

1313
const 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

Comments
 (0)