diff --git a/README.md b/README.md index f696370..8af9068 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,17 @@ FOO: bar BAR: baz ``` +as a final aside, if you don't want godotenv munging your env you can just get a map back instead + +```go +var myEnv map[string]string +myEnv, err := godotenv.Read() + +s3Bucket := myEnv["S3_BUCKET"] +``` + +end + ## Contributing Contributions are most welcome! The parser itself is pretty stupidly naive and I wouldn't be surprised if it breaks with edge cases. diff --git a/godotenv.go b/godotenv.go index f89ec30..a421053 100644 --- a/godotenv.go +++ b/godotenv.go @@ -34,9 +34,7 @@ import ( It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults */ func Load(filenames ...string) (err error) { - if len(filenames) == 0 { - filenames = []string{".env"} - } + filenames = filenamesOrDefault(filenames) for _, filename := range filenames { err = loadFile(filename) @@ -47,12 +45,55 @@ func Load(filenames ...string) (err error) { return } +func Read(filenames ...string) (envMap map[string]string, err error) { + filenames = filenamesOrDefault(filenames) + envMap = make(map[string]string) + + for _, filename := range filenames { + individualEnvMap, individualErr := readFile(filename) + + if individualErr != nil { + err = individualErr + return // return early on a spazout + } + + for key, value := range individualEnvMap { + envMap[key] = value + } + } + + return +} + +func filenamesOrDefault(filenames []string) []string { + if len(filenames) == 0 { + return []string{".env"} + } else { + return filenames + } +} + func loadFile(filename string) (err error) { + envMap, err := readFile(filename) + if err != nil { + return + } + + for key, value := range envMap { + os.Setenv(key, value) + } + + return +} + +func readFile(filename string) (envMap map[string]string, err error) { content, err := ioutil.ReadFile(filename) if err != nil { return } + envMap = make(map[string]string) + lines := strings.Split(string(content), "\n") for _, fullLine := range lines { @@ -60,11 +101,10 @@ func loadFile(filename string) (err error) { key, value, err := parseLine(fullLine) if err == nil && os.Getenv(key) == "" { - os.Setenv(key, value) + envMap[key] = value } } } - return } diff --git a/godotenv_test.go b/godotenv_test.go index e6ec8d9..381be3e 100644 --- a/godotenv_test.go +++ b/godotenv_test.go @@ -44,6 +44,32 @@ func TestLoadFileNotFound(t *testing.T) { } } +func TestReadPlainEnv(t *testing.T) { + envFileName := "fixtures/plain.env" + expectedValues := map[string]string{ + "OPTION_A": "1", + "OPTION_B": "2", + "OPTION_C": "3", + "OPTION_D": "4", + "OPTION_E": "5", + } + + envMap, err := Read(envFileName) + if err != nil { + t.Error("Error reading file") + } + + if len(envMap) != len(expectedValues) { + t.Error("Didn't get the right size map back") + } + + for key, value := range expectedValues { + if envMap[key] != value { + t.Error("Read got one of the keys wrong") + } + } +} + func TestLoadPlainEnv(t *testing.T) { envFileName := "fixtures/plain.env" expectedValues := map[string]string{