
Security News
152 Chrome Live Wallpaper Extensions Hid Ad Tracking and Faked Google Search Traffic
A network of 152 Chrome live wallpaper extensions hid ad tracking and made extension-driven traffic look like Google search clicks.
This package is made for apps that store config in environment variables.
Its purpose is to replace fragmented os.Getenv calls in main.go with a single struct definition,
which simplifies config management and improves code readability.
Go 1.20+
go get go-simpler.org/env
Load is the main function of the package.
It loads environment variables into the given struct.
The struct fields must have the env:"VAR" struct tag,
where VAR is the name of the corresponding environment variable.
Unexported fields are ignored.
os.Setenv("PORT", "8080")
var cfg struct {
Port int `env:"PORT"`
}
if err := env.Load(&cfg, nil); err != nil {
fmt.Println(err)
}
fmt.Println(cfg.Port) // 8080
int (any kind)float (any kind)boolstringtime.Durationencoding.TextUnmarshalerSee the strconv.Parse* functions for the parsing rules.
User-defined types can be used by implementing the encoding.TextUnmarshaler interface.
Nested struct of any depth level are supported, allowing grouping of related environment variables.
os.Setenv("DB_HOST", "localhost")
os.Setenv("DB_PORT", "5432")
var cfg struct {
DB struct {
Host string `env:"DB_HOST"`
Port int `env:"DB_PORT"`
}
}
if err := env.Load(&cfg, nil); err != nil {
fmt.Println(err)
}
fmt.Println(cfg.DB.Host) // localhost
fmt.Println(cfg.DB.Port) // 5432
If a nested struct has the optional env:"PREFIX" tag,
the environment variables declared by its fields are prefixed with PREFIX.
os.Setenv("DB_HOST", "localhost")
os.Setenv("DB_PORT", "5432")
var cfg struct {
DB struct {
Host string `env:"HOST"`
Port int `env:"PORT"`
} `env:"DB_"`
}
if err := env.Load(&cfg, nil); err != nil {
fmt.Println(err)
}
fmt.Println(cfg.DB.Host) // localhost
fmt.Println(cfg.DB.Port) // 5432
Default values can be specified using the default:"VALUE" struct tag.
os.Unsetenv("PORT")
var cfg struct {
Port int `env:"PORT" default:"8080"`
}
if err := env.Load(&cfg, nil); err != nil {
fmt.Println(err)
}
fmt.Println(cfg.Port) // 8080
Use the required option to mark an environment variable as required.
If it is not set, an error of type NotSetError is returned.
os.Unsetenv("PORT")
var cfg struct {
Port int `env:"PORT,required"`
}
if err := env.Load(&cfg, nil); err != nil {
var notSetErr *env.NotSetError
if errors.As(err, ¬SetErr) {
fmt.Println(notSetErr) // env: PORT is required but not set
}
}
Use the expand option to automatically expand the value of an environment variable using os.Expand.
os.Setenv("PORT", "8080")
os.Setenv("ADDR", "localhost:${PORT}")
var cfg struct {
Addr string `env:"ADDR,expand"`
}
if err := env.Load(&cfg, nil); err != nil {
fmt.Println(err)
}
fmt.Println(cfg.Addr) // localhost:8080
Space is the default separator used to parse slice values.
It can be changed with Options.SliceSep.
os.Setenv("PORTS", "8080,8081,8082")
var cfg struct {
Ports []int `env:"PORTS"`
}
if err := env.Load(&cfg, &env.Options{SliceSep: ","}); err != nil {
fmt.Println(err)
}
fmt.Println(cfg.Ports) // [8080 8081 8082]
By default, environment variable names are concatenated from nested struct tags as is.
If Options.NameSep is not empty, it is used as the separator.
os.Setenv("DB_HOST", "localhost")
os.Setenv("DB_PORT", "5432")
var cfg struct {
DB struct {
Host string `env:"HOST"`
Port int `env:"PORT"`
} `env:"DB"`
}
if err := env.Load(&cfg, &env.Options{NameSep: "_"}); err != nil {
fmt.Println(err)
}
fmt.Println(cfg.DB.Host) // localhost
fmt.Println(cfg.DB.Port) // 5432
By default, Load retrieves environment variables directly from OS.
To use a different source, pass an implementation of the Source interface via Options.Source.
type Source interface {
LookupEnv(key string) (value string, ok bool)
}
Here's an example of using Map, a Source implementation useful in tests.
m := env.Map{"PORT": "8080"}
var cfg struct {
Port int `env:"PORT"`
}
if err := env.Load(&cfg, &env.Options{Source: m}); err != nil {
fmt.Println(err)
}
fmt.Println(cfg.Port) // 8080
The Usage function prints a usage message documenting all defined environment variables.
An optional usage string can be added to environment variables with the usage:"STRING" struct tag.
os.Unsetenv("DB_HOST")
os.Unsetenv("DB_PORT")
var cfg struct {
DB struct {
Host string `env:"DB_HOST,required" usage:"database host"`
Port int `env:"DB_PORT,required" usage:"database port"`
}
HTTPPort int `env:"HTTP_PORT" default:"8080" usage:"http server port"`
}
if err := env.Load(&cfg, nil); err != nil {
fmt.Println(err)
fmt.Println("Usage:")
env.Usage(&cfg, os.Stdout, nil)
}
Usage:
DB_HOST string required database host
DB_PORT int required database port
HTTP_PORT int default 8080 http server port
The format of the message can be customized by implementing the Usage([]env.Var, io.Writer, *env.Options) method.
type Config struct{ ... }
func (Config) Usage(vars []env.Var, w io.Writer, opts *env.Options) {
for v := range vars {
// write to w.
}
}
FAQs
Unknown package
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
A network of 152 Chrome live wallpaper extensions hid ad tracking and made extension-driven traffic look like Google search clicks.

Company News
Socket’s first CISO brings deep experience securing high-growth SaaS companies as open source supply chain threats accelerate.

Company News
Replit is integrating Socket Firewall into its AI-powered development experience to help protect builders from malicious open source packages.