Documentation ¶
Overview ¶
Package env provides a comprehensive solution for managing environment variables in Go applications. It offers a rich set of features for handling environment configuration through both .env files and runtime environment variables.
Core Features:
- Concurrent parsing of .env files with configurable parallelism
- Bidirectional mapping between environment variables and Go structures
- Support for nested structures and complex data types
- Advanced type conversion with validation
- URL parsing and validation support
- Flexible prefix-based filtering
- Custom marshaling and unmarshaling interfaces
The package supports loading configuration from .env files with features like:
- Variable expansion (${VAR} or $VAR syntax)
- Quoted values with escape sequences
- Comments and inline comments
- Export statements
- Multi-line values
- Default values
- Custom separators for arrays/slices
Type Support: The package handles all common Go types including:
- Basic types: string, bool, int/uint (all sizes), float32/64
- Complex types: url.URL, custom structs
- Collections: arrays, slices
- Nested structures with automatic prefix handling
- Pointers to supported types
Structure Tags:
- env: specifies the environment variable name
- def: provides default values
- sep: defines separator for array/slice values
Example usage:
type Config struct { Host string `env:"HOST" def:"localhost"` Port int `env:"PORT" def:"8080"` IPs []string `env:"ALLOWED_IPS" sep:","` APIUrl url.URL `env:"API_URL"` } func main() { var cfg Config // Load .env file and parse it if err := env.Load(".env"); err != nil { log.Fatal(err) } // Map environment variables to structure if err := env.Unmarshal("", &cfg); err != nil { log.Fatal(err) } }
The package is designed to be efficient and safe, with careful handling of concurrent operations and proper error management. It provides a clean API that follows Go idioms while offering powerful features for complex configuration scenarios.
Index ¶
- func Clear()
- func Environ() []string
- func Exists(keys ...string) bool
- func Expand(value string) string
- func Get(key string) string
- func Load(filename string) error
- func LoadSafe(filename string) error
- func Lookup(key string) (string, bool)
- func Marshal(prefix string, scope interface{}) ([]string, error)
- func ParallelTasks(pt int) int
- func Save(filename, prefix string, obj interface{}) error
- func Set(key, value string) error
- func Unmarshal(prefix string, obj interface{}) error
- func Unset(key string) error
- func Update(filename string) error
- func UpdateSafe(filename string) error
- type Marshaler
- type Unmarshaler
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Environ ¶
func Environ() []string
Environ is synonym for the os.Environ, returns a copy of strings representing the environment, in the form "key=value".
func Exists ¶
Exists returns true if all given keys exists in the environment.
Examples ¶
In this example, some variables are already set in the environment:
$ env | grep KEY_0 KEY_0=VALUE_DEF
Configuration file `.env` contains:
LAST_ID=002 KEY_0=VALUE_000 KEY_1=VALUE_001 KEY_2=VALUE_${LAST_ID}
Check if a variable exists in the environment:
fmt.Printf("KEY_0 is %v\n", env.Exists("KEY_0")) fmt.Printf("KEY_1 is %v\n", env.Exists("KEY_1")) fmt.Printf("KEY_0 and KEY_1 is %v\n\n", env.Exists("KEY_0", "KEY_1")) if err := env.Update("./cmd/.env"); err != nil { log.Fatal(err) } fmt.Printf("KEY_0 is %v\n", env.Exists("KEY_0")) fmt.Printf("KEY_1 is %v\n", env.Exists("KEY_1")) fmt.Printf("KEY_0 and KEY_1 is %v\n", env.Exists("KEY_0", "KEY_1")) // Output: // KEY_0 is true // KEY_1 is false // KEY_0 and KEY_1 is false // // KEY_0 is true // KEY_1 is true // KEY_0 and KEY_1 is true
func Expand ¶
Expand is synonym for the os.Expand, replaces ${var} or $var in the string according to the values of the current environment variables. References to undefined variables are replaced by the empty string.
func Get ¶
Get is synonym for the os.Getenv, retrieves the value of the environment variable named by the key. It returns the value, which will be empty if the variable is not present.
To distinguish between an empty value and an unset value, use Lookup.
func Load ¶
Load loads new keys only (without updating existing keys) from env-file into environment. Handles variables like ${var} or $var in the value, replacing them with a real result.
Returns an error if the env-file contains incorrect data, file is damaged or missing.
Examples:
In this example, some variables are already set in the environment:
$ env | grep KEY_0 KEY_0=VALUE_DEF
Configuration file `.env` contains:
LAST_ID=002 KEY_0=VALUE_000 KEY_1=VALUE_001 KEY_2=VALUE_${LAST_ID}
Load values from configuration file into environment:
if err := env.Load(".env"); err != nil { log.Fatal(err) } fmt.Printf("LAST_ID=%s\n", env.Get("LAST_ID")) fmt.Printf("KEY_0=%s\n", env.Get("KEY_0")) fmt.Printf("KEY_1=%s\n", env.Get("KEY_1")) fmt.Printf("KEY_2=%s\n", env.Get("KEY_2")) // Output: // LAST_ID=002 // KEY_0=VALUE_DEF // KEY_1=VALUE_001 // KEY_2=VALUE_002
Where:
- KEY_0 - has not been replaced by VALUE_000;
- KEY_1 - loaded new value;
- KEY_2 - loaded new value and replaced ${LAST_ID} to the value from environment.
func LoadSafe ¶
LoadSafe loads new keys only (without updating existing keys) from env-file into environment. Doesn't handles variables like ${var} or $var - doesn't turn them into a finite value.
Returns an error if the env-file contains incorrect data, file is damaged or missing.
Examples ¶
In this example, some variables are already set in the environment:
$ env | grep KEY_0 KEY_0=VALUE_DEF
Configuration file `.env` contains:
LAST_ID=002 KEY_0=VALUE_000 KEY_1=VALUE_001 KEY_2=VALUE_${LAST_ID}
Load values from configuration file into environment:
if err := env.LoadSafe(".env"); err != nil { log.Fatal(err) } fmt.Printf("LAST_ID=%s\n", env.Get("LAST_ID")) fmt.Printf("KEY_0=%s\n", env.Get("KEY_0")) fmt.Printf("KEY_1=%s\n", env.Get("KEY_1")) fmt.Printf("KEY_2=%s\n", env.Get("KEY_2")) // Output: // LAST_ID=002 // KEY_0=VALUE_DEF // KEY_1=VALUE_001 // KEY_2=VALUE_${LAST_ID}
Where:
- KEY_0 - has not been replaced by VALUE_000;
- KEY_1 - loaded new value;
- KEY_2 - loaded new value but doesn't replace ${LAST_ID} to the value from environment.
func Lookup ¶ added in v1.0.1
Lookup is synonym for the os.LookupEnv, retrieves the value of the environment variable named by the key. If the variable is present in the environment the value (which may be empty) is returned and the boolean is true. Otherwise the returned value will be empty and the boolean will be false.
func Marshal ¶
Marshal converts the structure in to key/value and put it into environment with update old values. As the first value returns a list of keys that were correctly sets in the environment and nil or error information as second value.
If the obj isn't a pointer to struct, struct or has fields of unsupported types will be returned an error.
Method supports the following type of the fields: int, int8, int16, int32, int64, uin, uint8, uin16, uint32, in64, float32, float64, string, bool, struct, url.URL and pointers, array or slice from thous types (i.e. *int, *uint, ..., []int, ..., []bool, ..., [2]*url.URL, etc.). The fields as a struct or pointer on the struct will be processed recursively.
If the structure implements Marshaler interface - the custom MarshalEnv method will be called.
Use the following tags in the fields of structure to set the marshing parameters:
- env matches the name of the key in the environment;
- def default value (if empty, sets the default value for the field type of structure);
- sep sets the separator for lists/arrays (default ` ` - space).
Structure example:
// Config structure for containing values from the environment. type Config struct { Host string `env:"HOST"` Port int `env:"PORT" def:"80"` AllowedHosts []string `env:"ALLOWED_HOSTS" sep:":"` }
Marshal data into environment from the Config.
var config = Config{ "localhost", 8080, []string{"localhost", "127.0.0.1"}, } if _, err := env.Marshal("", config); err != nil { log.Fatal(err) } fmt.Printf("Host: %v\n", env.Get("HOST")) fmt.Printf("Port: %v\n", env.Get("PORT")) fmt.Printf("AllowedHosts: %v\n", env.Get("ALLOWED_HOSTS")) // Output: // Host: localhost // Port: 8080 // AllowedHosts: localhost:127.0.0.1
If the object has MarshalEnv and is not a nil pointer - will call its method to marshaling.
// MarshalEnv it's custom method for marshalling. func (c *Config) MarshalEnv() ([]string, error) { env.Set("HOST", "192.168.0.1") env.Set("PORT", "80") env.Set("ALLOWED_HOSTS", "192.168.0.1") return []string{"HOST", "PORT", "ALLOWED_HOSTS"}, nil } ... // Output: // Host: 192.168.0.1 // Port: 80 // AllowedHosts: 192.168.0.1
func ParallelTasks ¶ added in v1.1.1
Together sets the number of parallel transliteration tasks.
func Save ¶ added in v1.0.1
Save saves the object to a file without changing the environment.
Example ¶
There is some configuration structure:
// Config it's struct of the server configuration. type Config struct { Host string `env:"HOST"` Port int `env:"PORT"` AllowedHosts []string `env:"ALLOWED_HOSTS" sep:":"` // parse by `:`. }
...
var config = Config{ Host: "localhost", Port: 8080, AllowedHosts: []string{"localhost", "127.0.0.1"}, } env.Save("/tmp/.env", "", config)
The result in the file /tmp/.env
HOST=localhost PORT=8080 ALLOWED_HOSTS=localhost:127.0.0.1
func Set ¶
Set is synonym for the os.Setenv, sets the value of the environment variable named by the key. It returns an error, if any.
func Unmarshal ¶
Unmarshal parses data from the environment and store result into Go-structure that passed by pointer. If the obj isn't a pointer to struct or has fields of unsupported types will be returned an error.
Method supports the following type of the fields: int, int8, int16, int32, int64, uin, uint8, uin16, uint32, in64, float32, float64, string, bool, struct, url.URL and pointers, array or slice from thous types (i.e. *int, *uint, ..., []int, ..., []bool, ..., [2]*url.URL, etc.). The fields as a struct or pointer on the struct will be processed recursively.
If the structure implements Unmarshaler interface - the custom UnmarshalEnv method will be called.
Use the following tags in the fields of structure to set the unmarshing parameters:
env matches the name of the key in the environment; def default value (if empty, sets the default value for the field type of structure); sep sets the separator for lists/arrays (default ` ` - space).
Examples ¶
Some keys was set into environment as:
$ export HOST="0.0.0.0" $ export PORT=8080 $ export ALLOWED_HOSTS=localhost:127.0.0.1 $ export SECRET_KEY=AgBsdjONL53IKa33LM9SNROvD3hZXfoz
Structure example:
// Config structure for containing values from the environment. // P.s. There is no need to describe all the keys in the environment, // for example, we ignore the SECRET_KEY key. type Config struct { Host string `env:"HOST"` Port int `env:"PORT" def:"80"` AllowedHosts []string `env:"ALLOWED_HOSTS" sep:":"` }
Unmarshal data from the environment into Config structure.
var config Config if err := env.Unmarshal("", &config); err != nil { log.Fatal(err) } fmt.Printf("Host: %v\n", config.Host) fmt.Printf("Port: %v\n", config.Port) fmt.Printf("AllowedHosts: %v\n", config.AllowedHosts) // Output: // Host: 0.0.0.0 // Port: 8080 // AllowedHosts: [localhost 127.0.0.1]
If the structure will has custom UnmarshalEnv it will be called:
// UnmarshalEnv it's custom method for unmarshalling. func (c *Config) UnmarshalEnv() error { c.Host = "192.168.0.1" c.Port = 80 c.AllowedHosts = []string{"192.168.0.1"} return nil } ... // Output: // Host: 192.168.0.1 // Port: 80 // AllowedHosts: [192.168.0.1]
func Update ¶
Update loads keys from the env-file into environment, update existing keys. Handles variables like ${var} or $var in the value, replacing them with a real result.
Returns an error if the env-file contains incorrect data, file is damaged or missing.
Examples ¶
In this example, some variables are already set in the environment:
$ env | grep KEY_0 KEY_0=VALUE_DEF
Configuration file `.env` contains:
LAST_ID=002 KEY_0=VALUE_000 KEY_1=VALUE_001 KEY_2=VALUE_${LAST_ID}
Load values from configuration file into environment:
if err := env.Update(".env"); err != nil { log.Fatal(err) } fmt.Printf("LAST_ID=%s\n", env.Get("LAST_ID")) fmt.Printf("KEY_0=%s\n", env.Get("KEY_0")) fmt.Printf("KEY_1=%s\n", env.Get("KEY_1")) fmt.Printf("KEY_2=%s\n", env.Get("KEY_2")) // Output: // LAST_ID=002 // KEY_0=VALUE_000 // KEY_1=VALUE_001 // KEY_2=VALUE_002
Where:
- KEY_0 - replaced VALUE_DEF on VALUE_000;
- KEY_1 - loaded new value;
- KEY_2 - loaded new value and replaced ${LAST_ID} to the value from environment.
func UpdateSafe ¶
UpdateSafe loads keys from the env-file into environment, update existing keys. Doesn't handles variables like ${var} or $var - doesn't turn them into a finite value.
Returns an error if the env-file contains incorrect data, file is damaged or missing.
Examples ¶
In this example, some variables are already set in the environment:
$ env | grep KEY_0 KEY_0=VALUE_DEF
Configuration file `.env` contains:
LAST_ID=002 KEY_0=VALUE_000 KEY_1=VALUE_001 KEY_2=VALUE_${LAST_ID}
Load values from configuration file into environment:
if err := env.Update(".env"); err != nil { log.Fatal(err) } fmt.Printf("LAST_ID=%s\n", env.Get("LAST_ID")) fmt.Printf("KEY_0=%s\n", env.Get("KEY_0")) fmt.Printf("KEY_1=%s\n", env.Get("KEY_1")) fmt.Printf("KEY_2=%s\n", env.Get("KEY_2")) // Output: // LAST_ID=002 // KEY_0=VALUE_000 // KEY_1=VALUE_001 // KEY_2=VALUE_${LAST_ID}
Where:
- KEY_0 - replaced VALUE_DEF on VALUE_000;
- KEY_1 - loaded new value;
- KEY_2 - loaded new value but doesn't replace ${LAST_ID} to the value from environment.
Types ¶
type Marshaler ¶
Marshaler is the interface implemented by types that can marshal themselves into valid object.
type Unmarshaler ¶
type Unmarshaler interface {
UnmarshalEnv() error
}
Unmarshaler is the interface implements by types that can unmarshal an environment variables of themselves.