]>
Commit | Line | Data |
---|---|---|
9b12e4fe JC |
1 | package opts |
2 | ||
3 | import ( | |
4 | "bufio" | |
5 | "fmt" | |
6 | "os" | |
7 | "strings" | |
8 | ) | |
9 | ||
10 | // ParseEnvFile reads a file with environment variables enumerated by lines | |
11 | // | |
12 | // ``Environment variable names used by the utilities in the Shell and | |
13 | // Utilities volume of IEEE Std 1003.1-2001 consist solely of uppercase | |
14 | // letters, digits, and the '_' (underscore) from the characters defined in | |
15 | // Portable Character Set and do not begin with a digit. *But*, other | |
16 | // characters may be permitted by an implementation; applications shall | |
17 | // tolerate the presence of such names.'' | |
18 | // -- http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html | |
19 | // | |
20 | // As of #16585, it's up to application inside docker to validate or not | |
21 | // environment variables, that's why we just strip leading whitespace and | |
22 | // nothing more. | |
23 | func ParseEnvFile(filename string) ([]string, error) { | |
24 | fh, err := os.Open(filename) | |
25 | if err != nil { | |
26 | return []string{}, err | |
27 | } | |
28 | defer fh.Close() | |
29 | ||
30 | lines := []string{} | |
31 | scanner := bufio.NewScanner(fh) | |
32 | for scanner.Scan() { | |
33 | // trim the line from all leading whitespace first | |
34 | line := strings.TrimLeft(scanner.Text(), whiteSpaces) | |
35 | // line is not empty, and not starting with '#' | |
36 | if len(line) > 0 && !strings.HasPrefix(line, "#") { | |
37 | data := strings.SplitN(line, "=", 2) | |
38 | ||
39 | // trim the front of a variable, but nothing else | |
40 | variable := strings.TrimLeft(data[0], whiteSpaces) | |
41 | if strings.ContainsAny(variable, whiteSpaces) { | |
42 | return []string{}, ErrBadEnvVariable{fmt.Sprintf("variable '%s' has white spaces", variable)} | |
43 | } | |
44 | ||
45 | if len(data) > 1 { | |
46 | ||
47 | // pass the value through, no trimming | |
48 | lines = append(lines, fmt.Sprintf("%s=%s", variable, data[1])) | |
49 | } else { | |
50 | // if only a pass-through variable is given, clean it up. | |
51 | lines = append(lines, fmt.Sprintf("%s=%s", strings.TrimSpace(line), os.Getenv(line))) | |
52 | } | |
53 | } | |
54 | } | |
55 | return lines, scanner.Err() | |
56 | } | |
57 | ||
58 | var whiteSpaces = " \t" | |
59 | ||
60 | // ErrBadEnvVariable typed error for bad environment variable | |
61 | type ErrBadEnvVariable struct { | |
62 | msg string | |
63 | } | |
64 | ||
65 | func (e ErrBadEnvVariable) Error() string { | |
66 | return fmt.Sprintf("poorly formatted environment: %s", e.msg) | |
67 | } |