diff --git a/opts/envfile.go b/opts/envfile.go index 10054c896c..69d3ca6f60 100644 --- a/opts/envfile.go +++ b/opts/envfile.go @@ -18,5 +18,5 @@ import ( // environment variables, that's why we just strip leading whitespace and // nothing more. func ParseEnvFile(filename string) ([]string, error) { - return parseKeyValueFile(filename, os.Getenv) + return parseKeyValueFile(filename, os.LookupEnv) } diff --git a/opts/envfile_test.go b/opts/envfile_test.go index 6302263848..bda9dcb6e7 100644 --- a/opts/envfile_test.go +++ b/opts/envfile_test.go @@ -139,3 +139,40 @@ another invalid line` t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error()) } } + +// ParseEnvFile with environment variable import definitions +func TestParseEnvVariableDefinitionsFile(t *testing.T) { + content := `# comment= +UNDEFINED_VAR +HOME +` + tmpFile := tmpFileWithContent(content, t) + defer os.Remove(tmpFile) + + variables, err := ParseEnvFile(tmpFile) + if nil != err { + t.Fatal("There must not be any error") + } + + if "HOME="+os.Getenv("HOME") != variables[0] { + t.Fatal("the HOME variable is not properly imported as the first variable (but it is the only one to import)") + } + + if 1 != len(variables) { + t.Fatal("exactly one variable is imported (as the other one is not set at all)") + } +} + +// ParseEnvFile with empty variable name +func TestParseEnvVariableWithNoNameFile(t *testing.T) { + content := `# comment= +=blank variable names are an error case +` + tmpFile := tmpFileWithContent(content, t) + defer os.Remove(tmpFile) + + _, err := ParseEnvFile(tmpFile) + if nil == err { + t.Fatal("if a variable has no name parsing an environment file must fail") + } +} diff --git a/opts/file.go b/opts/file.go index 281905949b..1721a46ef9 100644 --- a/opts/file.go +++ b/opts/file.go @@ -21,7 +21,7 @@ func (e ErrBadKey) Error() string { return fmt.Sprintf("poorly formatted environment: %s", e.msg) } -func parseKeyValueFile(filename string, emptyFn func(string) string) ([]string, error) { +func parseKeyValueFile(filename string, emptyFn func(string) (string, bool)) ([]string, error) { fh, err := os.Open(filename) if err != nil { return []string{}, err @@ -53,17 +53,23 @@ func parseKeyValueFile(filename string, emptyFn func(string) string) ([]string, if strings.ContainsAny(variable, whiteSpaces) { return []string{}, ErrBadKey{fmt.Sprintf("variable '%s' has white spaces", variable)} } + if len(variable) == 0 { + return []string{}, ErrBadKey{fmt.Sprintf("no variable name on line '%s'", line)} + } if len(data) > 1 { // pass the value through, no trimming lines = append(lines, fmt.Sprintf("%s=%s", variable, data[1])) } else { var value string + var present bool if emptyFn != nil { - value = emptyFn(line) + value, present = emptyFn(line) + } + if present { + // if only a pass-through variable is given, clean it up. + lines = append(lines, fmt.Sprintf("%s=%s", strings.TrimSpace(line), value)) } - // if only a pass-through variable is given, clean it up. - lines = append(lines, fmt.Sprintf("%s=%s", strings.TrimSpace(line), value)) } } } diff --git a/opts/parse.go b/opts/parse.go index 679759deda..70b60e142f 100644 --- a/opts/parse.go +++ b/opts/parse.go @@ -19,10 +19,10 @@ func ReadKVStrings(files []string, override []string) ([]string, error) { // present in the file with additional pairs specified in the override parameter. // If a key has no value, it will get the value from the environment. func ReadKVEnvStrings(files []string, override []string) ([]string, error) { - return readKVStrings(files, override, os.Getenv) + return readKVStrings(files, override, os.LookupEnv) } -func readKVStrings(files []string, override []string, emptyFn func(string) string) ([]string, error) { +func readKVStrings(files []string, override []string, emptyFn func(string) (string, bool)) ([]string, error) { variables := []string{} for _, ef := range files { parsedVars, err := parseKeyValueFile(ef, emptyFn)