mirror of https://github.com/joho/godotenv.git
adding Overload method
parent
443e926da0
commit
008304c688
29
godotenv.go
29
godotenv.go
|
@ -36,7 +36,30 @@ func Load(filenames ...string) (err error) {
|
|||
filenames = filenamesOrDefault(filenames)
|
||||
|
||||
for _, filename := range filenames {
|
||||
err = loadFile(filename)
|
||||
err = loadFile(filename, false)
|
||||
if err != nil {
|
||||
return // return early on a spazout
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Overload will read your env file(s) and load them into ENV for this process.
|
||||
//
|
||||
// Call this function as close as possible to the start of your program (ideally in main)
|
||||
//
|
||||
// If you call Overload without any args it will default to loading .env in the current path
|
||||
//
|
||||
// You can otherwise tell it which files to load (there can be more than one) like
|
||||
//
|
||||
// godotenv.Overload("fileone", "filetwo")
|
||||
//
|
||||
// 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)
|
||||
|
||||
for _, filename := range filenames {
|
||||
err = loadFile(filename, true)
|
||||
if err != nil {
|
||||
return // return early on a spazout
|
||||
}
|
||||
|
@ -90,14 +113,14 @@ func filenamesOrDefault(filenames []string) []string {
|
|||
return filenames
|
||||
}
|
||||
|
||||
func loadFile(filename string) error {
|
||||
func loadFile(filename string, overload bool) error {
|
||||
envMap, err := readFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for key, value := range envMap {
|
||||
if os.Getenv(key) == "" {
|
||||
if os.Getenv(key) == "" || overload {
|
||||
os.Setenv(key, value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
var noopPresets = make(map[string]string)
|
||||
|
||||
func parseAndCompare(t *testing.T, rawEnvLine string, expectedKey string, expectedValue string) {
|
||||
key, value, _ := parseLine(rawEnvLine)
|
||||
if key != expectedKey || value != expectedValue {
|
||||
|
@ -12,11 +14,15 @@ func parseAndCompare(t *testing.T, rawEnvLine string, expectedKey string, expect
|
|||
}
|
||||
}
|
||||
|
||||
func loadEnvAndCompareValues(t *testing.T, envFileName string, expectedValues map[string]string) {
|
||||
func loadEnvAndCompareValues(t *testing.T, loader func(files ...string) error, envFileName string, expectedValues map[string]string, presets map[string]string) {
|
||||
// first up, clear the env
|
||||
os.Clearenv()
|
||||
|
||||
err := Load(envFileName)
|
||||
for k, v := range presets {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
|
||||
err := loader(envFileName)
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading %v", envFileName)
|
||||
}
|
||||
|
@ -38,6 +44,14 @@ func TestLoadWithNoArgsLoadsDotEnv(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestOverloadWithNoArgsOverloadsDotEnv(t *testing.T) {
|
||||
err := Overload()
|
||||
pathError := err.(*os.PathError)
|
||||
if pathError == nil || pathError.Op != "open" || pathError.Path != ".env" {
|
||||
t.Errorf("Didn't try and open .env by default")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadFileNotFound(t *testing.T) {
|
||||
err := Load("somefilethatwillneverexistever.env")
|
||||
if err == nil {
|
||||
|
@ -45,6 +59,13 @@ func TestLoadFileNotFound(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestOverloadFileNotFound(t *testing.T) {
|
||||
err := Overload("somefilethatwillneverexistever.env")
|
||||
if err == nil {
|
||||
t.Error("File wasn't found but Overload didn't return an error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadPlainEnv(t *testing.T) {
|
||||
envFileName := "fixtures/plain.env"
|
||||
expectedValues := map[string]string{
|
||||
|
@ -71,6 +92,34 @@ func TestReadPlainEnv(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestLoadDoesNotOverride(t *testing.T) {
|
||||
envFileName := "fixtures/plain.env"
|
||||
|
||||
// ensure NO overload
|
||||
presets := map[string]string{
|
||||
"OPTION_A": "do_not_override",
|
||||
}
|
||||
|
||||
expectedValues := map[string]string{
|
||||
"OPTION_A": "do_not_override",
|
||||
}
|
||||
loadEnvAndCompareValues(t, Load, envFileName, expectedValues, presets)
|
||||
}
|
||||
|
||||
func TestOveroadDoesOverride(t *testing.T) {
|
||||
envFileName := "fixtures/plain.env"
|
||||
|
||||
// ensure NO overload
|
||||
presets := map[string]string{
|
||||
"OPTION_A": "do_not_override",
|
||||
}
|
||||
|
||||
expectedValues := map[string]string{
|
||||
"OPTION_A": "1",
|
||||
}
|
||||
loadEnvAndCompareValues(t, Overload, envFileName, expectedValues, presets)
|
||||
}
|
||||
|
||||
func TestLoadPlainEnv(t *testing.T) {
|
||||
envFileName := "fixtures/plain.env"
|
||||
expectedValues := map[string]string{
|
||||
|
@ -81,7 +130,7 @@ func TestLoadPlainEnv(t *testing.T) {
|
|||
"OPTION_E": "5",
|
||||
}
|
||||
|
||||
loadEnvAndCompareValues(t, envFileName, expectedValues)
|
||||
loadEnvAndCompareValues(t, Load, envFileName, expectedValues, noopPresets)
|
||||
}
|
||||
|
||||
func TestLoadExportedEnv(t *testing.T) {
|
||||
|
@ -91,7 +140,7 @@ func TestLoadExportedEnv(t *testing.T) {
|
|||
"OPTION_B": "\n",
|
||||
}
|
||||
|
||||
loadEnvAndCompareValues(t, envFileName, expectedValues)
|
||||
loadEnvAndCompareValues(t, Load, envFileName, expectedValues, noopPresets)
|
||||
}
|
||||
|
||||
func TestLoadEqualsEnv(t *testing.T) {
|
||||
|
@ -100,7 +149,7 @@ func TestLoadEqualsEnv(t *testing.T) {
|
|||
"OPTION_A": "postgres://localhost:5432/database?sslmode=disable",
|
||||
}
|
||||
|
||||
loadEnvAndCompareValues(t, envFileName, expectedValues)
|
||||
loadEnvAndCompareValues(t, Load, envFileName, expectedValues, noopPresets)
|
||||
}
|
||||
|
||||
func TestLoadQuotedEnv(t *testing.T) {
|
||||
|
@ -116,7 +165,7 @@ func TestLoadQuotedEnv(t *testing.T) {
|
|||
"OPTION_H": "\n",
|
||||
}
|
||||
|
||||
loadEnvAndCompareValues(t, envFileName, expectedValues)
|
||||
loadEnvAndCompareValues(t, Load, envFileName, expectedValues, noopPresets)
|
||||
}
|
||||
|
||||
func TestActualEnvVarsAreLeftAlone(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue