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
|
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
|
## Contributing
|
||||||
|
|
||||||
Contributions are most welcome! The parser itself is pretty stupidly naive and I wouldn't be surprised if it breaks with edge cases.
|
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
|
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) {
|
func Load(filenames ...string) (err error) {
|
||||||
if len(filenames) == 0 {
|
filenames = filenamesOrDefault(filenames)
|
||||||
filenames = []string{".env"}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
err = loadFile(filename)
|
err = loadFile(filename)
|
||||||
|
@ -47,12 +45,55 @@ func Load(filenames ...string) (err error) {
|
||||||
return
|
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) {
|
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)
|
content, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
envMap = make(map[string]string)
|
||||||
|
|
||||||
lines := strings.Split(string(content), "\n")
|
lines := strings.Split(string(content), "\n")
|
||||||
|
|
||||||
for _, fullLine := range lines {
|
for _, fullLine := range lines {
|
||||||
|
@ -60,11 +101,10 @@ func loadFile(filename string) (err error) {
|
||||||
key, value, err := parseLine(fullLine)
|
key, value, err := parseLine(fullLine)
|
||||||
|
|
||||||
if err == nil && os.Getenv(key) == "" {
|
if err == nil && os.Getenv(key) == "" {
|
||||||
os.Setenv(key, value)
|
envMap[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
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) {
|
func TestLoadPlainEnv(t *testing.T) {
|
||||||
envFileName := "fixtures/plain.env"
|
envFileName := "fixtures/plain.env"
|
||||||
expectedValues := map[string]string{
|
expectedValues := map[string]string{
|
||||||
|
|
Loading…
Reference in New Issue