mirror of https://github.com/joho/godotenv.git
add godotenv.Read() which returns a map rather than calling os.Setenv
parent
38f18b8248
commit
6e333bd708
11
README.md
11
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.
|
||||
|
|
50
godotenv.go
50
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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{
|
||||
|
|
Loading…
Reference in New Issue