emp is a Go library for parsing environment variable to structures, while providing helpful error handling.
Directly read environment variables in Go will case a lot of repeat code like this:
package main
import "os"
func main() {
envStringValue := os.Getenv("SOME_ENV")
if envStringValue == "" {
panic("missing SOME_ENV")
// OR: envStringValue = "default"
}
// convert string to the type you want
envValue := sthConvert(envStringValue)
}
It's a bit complicated and unclear, isn't it?
Let's try emp!
package main
import "github.com/XMLHexagram/emp"
func main() {
type EnvModel struct {
SOME_ENV int
SOME_ENV_1 string
SOME_ENV_2 []string
// whatever type you want, but not map
}
envModel := new(EnvModel)
err := Parse(envModel)
if err != nil {
panic(err)
}
}
Now, SOME_ENV
is parsed to envModel
.
It is simpler and easier to understand than the previous one, right?
What, no? Then you need to see Usage below.
Standard go get
:
$ go get github.com/XMLHexagram/emp
For full usage and examples see the Godoc.
Or you can see Real Project Example, Test Case and Example Test Case
Here is a short introduction of emp:
The easiest way to use emp is to use Parse
function.
First, define an empty struct:
type EnvModel struct {
JWT_SECERT string
JWT_EXPIRE int
REDIS_URL string
SERVER_ struct {
PORT string
HTTP_TIMEOUT int
}
// whatever type you want, but not map
}
Then, Let's use emp.Marshal
to see the environment variables emp will looking for.
res, err := emp.Marshal(&EnvModel{})
fmt.Println(res)
/*
JWT_SECERT=
JWT_EXPIRE=0
REDIS_URL=
// you want SERVER_PORT and SERVER_HTTP_TIMEOUT, right?
PORT=
HTTP_TIMEOUT=0
*/
Good, but not good enough. Maybe you want SERVER_PORT
and SERVER_HTTP_TIMEOUT
.
Let's try AutoPrefix
:
parser, _ := emp.NewParser(&Config{
AutoPrefix: true,
})
res, _ = parser.Marshal(&EnvModel{})
fmt.Println(res)
/*
JWT_SECERT=
JWT_EXPIRE=0
REDIS_URL=
// the prefix is `SERVER_` now!
SERVER_PORT=
SERVER_HTTP_TIMEOUT=0
*/
Much better, but can emp do something more?
Of course can, let's try field tag
to customize the prefix
and environment variable
emp looking for:
type EnvModel struct {
JwtSecret string `emp:"JWT_SECRET"`
JwtExpire int `emp:"JWT_EXPIRE"`
RedisUrl string `emp:"REDIS_URL"`
Server struct {
Port string `emp:"SERVER_PORT"`
HttpTimeout int `emp:"SERVER_HTTP_TIMEOUT"`
} `emp:"prefix:SERVER_"`
// whatever type you want, but not map
}
res, _ := emp.Marshal(&EnvModel1{})
fmt.Println(res)
/*
JWT_SECRET=
JWT_EXPIRE=0
REDIS_URL=
SERVER_SERVER_PORT=
SERVER_SERVER_HTTP_TIMEOUT=0
*/
COOL! This struct defines looks perfect. Now, we only need one more step.
Finally, call Parse
function:
envModel := new(EnvModel)
_ := emp.Parse(envModel)
envModel is now filled with environment variables you need. 🎉
That's All?
No, emp also provides more features to customize your environment variables parsing.
See emp doc for more details.
A: emp => EnvironMent variable Parser
Yes, but maybe not in the future.
As we all know, environment variables in most time are ALL CAPS. So if someone need this feature, I will add it as a configurable option.
There is an easy way to set environment variables by use godotenv
No, the only not supported native type of Go is map. Sincerely, I have no idea on how to support it. If you have any idea, please open an issue.
Thanks to mitchellh/mapstructure and spf13/viper, Your repos have inspired me, and I used some code from your repo.
Feel free to open an issue when you want to report a bug, feature or ask for help. ✨