// Package godotenv is a go port of the ruby dotenv library (https://github.com/bkeepers/dotenv)//// Examples/readme can be found on the GitHub page at https://github.com/joho/godotenv//// The TL;DR is that you make a .env file that looks something like//// SOME_ENV_VAR=somevalue//// and then in your go code you can call//// godotenv.Load()//// and all the env vars declared in .env will be available through os.Getenv("SOME_ENV_VAR")
package godotenvimport ()const doubleQuoteSpecialChars = "\\\n\r\"!$`"// Parse reads an env file from io.Reader, returning a map of keys and values.func ( io.Reader) (map[string]string, error) {varbytes.Buffer , := io.Copy(&, )if != nil {returnnil, }returnUnmarshalBytes(.Bytes())}// Load 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 Load 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.Load("fileone", "filetwo")//// 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 ( ...string) ( error) { = filenamesOrDefault()for , := range { = loadFile(, false)if != 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 forcefully set all vars.func ( ...string) ( error) { = filenamesOrDefault()for , := range { = loadFile(, true)if != nil {return// return early on a spazout } }return}// Read all env (with same file loading semantics as Load) but return values as// a map rather than automatically writing values into envfunc ( ...string) ( map[string]string, error) { = filenamesOrDefault() = make(map[string]string)for , := range { , := readFile()if != nil { = return// return early on a spazout }for , := range { [] = } }return}// Unmarshal reads an env file from a string, returning a map of keys and values.func ( string) ( map[string]string, error) {returnUnmarshalBytes([]byte())}// UnmarshalBytes parses env file from byte slice of chars, returning a map of keys and values.func ( []byte) (map[string]string, error) { := make(map[string]string) := parseBytes(, )return , }// Exec loads env vars from the specified filenames (empty map falls back to default)// then executes the cmd specified.//// Simply hooks up os.Stdin/err/out to the command and calls Run().//// If you want more fine grained control over your command it's recommended// that you use `Load()`, `Overload()` or `Read()` and the `os/exec` package yourself.func ( []string, string, []string, bool) error { := Loadif { = Overload }if := (...); != nil {return } := exec.Command(, ...) .Stdin = os.Stdin .Stdout = os.Stdout .Stderr = os.Stderrreturn .Run()}// Write serializes the given environment and writes it to a file.func ( map[string]string, string) error { , := Marshal()if != nil {return } , := os.Create()if != nil {return }defer .Close() _, = .WriteString( + "\n")if != nil {return }return .Sync()}// Marshal outputs the given environment as a dotenv-formatted environment file.// Each line is in the format: KEY="VALUE" where VALUE is backslash-escaped.func ( map[string]string) (string, error) { := make([]string, 0, len())for , := range {if , := strconv.Atoi(); == nil { = append(, fmt.Sprintf(`%s=%d`, , )) } else { = append(, fmt.Sprintf(`%s="%s"`, , doubleQuoteEscape())) } }sort.Strings()returnstrings.Join(, "\n"), nil}func filenamesOrDefault( []string) []string {iflen() == 0 {return []string{".env"} }return}func loadFile( string, bool) error { , := readFile()if != nil {return } := map[string]bool{} := os.Environ()for , := range { := strings.Split(, "=")[0] [] = true }for , := range {if ![] || { _ = os.Setenv(, ) } }returnnil}func readFile( string) ( map[string]string, error) { , := os.Open()if != nil {return }defer .Close()returnParse()}func doubleQuoteEscape( string) string {for , := rangedoubleQuoteSpecialChars { := "\\" + string()if == '\n' { = `\n` }if == '\r' { = `\r` } = strings.Replace(, string(), , -1) }return}
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.