ProductPromotion
Logo

Go.Lang

made by https://0x3d.site

GitHub - go-simpler/env: ๐Ÿ” Load environment variables into a config struct
๐Ÿ” Load environment variables into a config struct. Contribute to go-simpler/env development by creating an account on GitHub.
Visit Site

GitHub - go-simpler/env: ๐Ÿ” Load environment variables into a config struct

GitHub - go-simpler/env: ๐Ÿ” Load environment variables into a config struct

logo

๐Ÿ” Load environment variables into a config struct

awesome-go checks pkg.go.dev goreportcard codecov

๐Ÿ“Œ About

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.

๐Ÿš€ Features

๐Ÿ“ฆ Install

Go 1.20+

go get go-simpler.org/env

๐Ÿ“‹ Usage

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

Supported types

  • int (any kind)
  • float (any kind)
  • bool
  • string
  • time.Duration
  • encoding.TextUnmarshaler
  • slices of any type above
  • nested structs of any depth

See the strconv.Parse* functions for the parsing rules. User-defined types can be used by implementing the encoding.TextUnmarshaler interface.

Nested structs

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

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

Required

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, &notSetErr) {
        fmt.Println(notSetErr) // env: PORT is required but not set
    }
}

Expand

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

Slice separator

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]

Name separator

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

Source

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

Usage message

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.
    }
}

Articles
to learn more about the golang concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here ๐Ÿ”ฅ.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here ๐Ÿ”ฅ.

Queries
or most google FAQ's about GoLang.

mail [email protected] to add more queries here ๐Ÿ”.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory