diff --git a/.gitignore b/.gitignore index e43b0f9..f5511b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ .DS_Store +.idea + +try +go.mod diff --git a/godotenv.go b/godotenv.go index 69e816c..9aef909 100644 --- a/godotenv.go +++ b/godotenv.go @@ -20,6 +20,7 @@ import ( "io" "os" "os/exec" + "path/filepath" "regexp" "sort" "strings" @@ -37,16 +38,32 @@ const doubleQuoteSpecialChars = "\\\n\r\"!$`" // // godotenv.Load("fileone", "filetwo") // +// Also, you can tell it a folder name, and it would crawl the folder tree and load all the env files +// +// godotenv.Load("fixtures") +// // 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) { filenames = filenamesOrDefault(filenames) + paths := make([]string, 0) for _, filename := range filenames { - err = loadFile(filename, false) - if err != nil { - return // return early on a spazout + if _, err = os.Stat(filename); !os.IsNotExist(err) { + paths, err = folders(filenames) + for _, p := range paths { + err = loadFile(p, false) + if err != nil { + return + } + } + }else{ + err = loadFile(filename, false) + if err != nil { + return // return early on a spazout + } } } + return } @@ -60,14 +77,30 @@ func Load(filenames ...string) (err error) { // // godotenv.Overload("fileone", "filetwo") // +// Also, you can tell it a folder name, and it would crawl the folder tree and load all the env files +// +// godotenv.Overload("fixtures") +// +// // It's important to note this WILL OVERRIDE an env variable that already exists - consider the .env file to forcefilly set all vars. func Overload(filenames ...string) (err error) { filenames = filenamesOrDefault(filenames) + paths := make([]string, 0) for _, filename := range filenames { - err = loadFile(filename, true) - if err != nil { - return // return early on a spazout + if _, err = os.Stat(filename); !os.IsNotExist(err) { + paths, err = folders(filenames) + for _, p := range paths { + err = loadFile(p, true) + if err != nil { + return + } + } + }else{ + err = loadFile(filename, true) + if err != nil { + return // return early on a spazout + } } } return @@ -182,6 +215,28 @@ func filenamesOrDefault(filenames []string) []string { return filenames } +func folders(folders []string) ([]string, error) { + paths := make([]string, 0) + + for _, folder := range folders { + err := filepath.Walk(folder, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if ext := filepath.Ext(path); ext == ".env" { + paths = append(paths, path) + } + return nil + }) + if err != nil { + return nil, err + } + } + + return paths, nil +} + func loadFile(filename string, overload bool) error { envMap, err := readFile(filename) if err != nil { diff --git a/godotenv_test.go b/godotenv_test.go index d1f73cb..62e517c 100644 --- a/godotenv_test.go +++ b/godotenv_test.go @@ -40,6 +40,18 @@ func loadEnvAndCompareValues(t *testing.T, loader func(files ...string) error, e } } +func compareTotal(t *testing.T, loader func(files []string) ([]string, error), envFolderName []string, expectedNum int) { + values, err := loader(envFolderName) + if err != nil { + t.Fatalf("Error loading %v", envFolderName) + } + + if len(values) != expectedNum { + t.Errorf("wrong number of files fetched: expected, %v got %v", len(values), expectedNum) + } + +} + func TestLoadWithNoArgsLoadsDotEnv(t *testing.T) { err := Load() pathError := err.(*os.PathError) @@ -416,6 +428,13 @@ func TestErrorReadDirectory(t *testing.T) { } } +func TestLoadMultipleEnvFiles(t *testing.T) { + folderName := []string{"fixtures"} + expectedFilesNum := 6 + + compareTotal(t, folders, folderName, expectedFilesNum) +} + func TestErrorParsing(t *testing.T) { envFileName := "fixtures/invalid1.env" envMap, err := Read(envFileName)