Documentation
¶
Overview ¶
Package env provides utilities for working with environment variables and loading configuration from .env files.
This package offers three main areas of functionality:
1. Simple environment variable access with type conversion 2. Struct-based configuration parsing using struct tags 3. Loading and parsing of .env files
Basic Usage ¶
Get environment variables with automatic type conversion:
port, err := env.GetInt("PORT")
if err != nil {
port = env.GetOrInt("PORT", 8080) // with default
}
// Or panic if missing/invalid
dbHost := env.MustGet("DATABASE_HOST")
Struct-based Configuration ¶
Parse environment variables into structs using tags:
type Config struct {
Host string `env:"HOST" envDefault:"localhost"`
Port int `env:"PORT" envDefault:"8080"`
Debug bool `env:"DEBUG"`
}
var cfg Config
if err := env.Parse(&cfg); err != nil {
log.Fatal(err)
}
File Loading ¶
Load environment variables from .env files:
// Load from .env file
err := env.Load()
if err != nil {
log.Fatal(err)
}
// Load from specific files
err = env.Load("config.env", "local.env")
Supported Types ¶
The package supports automatic conversion for:
- bool, int, uint, int64, uint64, float32, float64
- time.Duration (using time.ParseDuration format)
- *url.URL (using url.ParseRequestURI)
- []string and other slice types (comma-separated by default)
- Any type implementing encoding.TextUnmarshaler
Struct Tags ¶
When using Parse functions, the following struct tags are supported:
- env:"VAR_NAME" - specifies the environment variable name
- envDefault:"value" - provides a default value if the variable is not set
- required:"true" - makes the field required (parsing fails if missing)
- envSeparator:";" - custom separator for slice types (default is comma)
- envExpand:"true" - enables variable expansion using os.ExpandEnv
Error Handling ¶
Functions come in three variants for different error handling approaches:
- Get*() functions return (value, error)
- GetOr*() functions return value with a fallback default
- MustGet*() functions panic if the variable is missing or invalid
Index ¶
- Constants
- Variables
- func EnableDebugLogging(logger func(format string, args ...interface{}))
- func Get(key string) string
- func GetBool(key string) (bool, error)
- func GetDuration(key string) (time.Duration, error)
- func GetFloat32(key string) (float32, error)
- func GetFloat64(key string) (float64, error)
- func GetInt(key string) (int, error)
- func GetInt64(key string) (int64, error)
- func GetOr(key, defaultValue string) string
- func GetOrBool(key string, defaultValue bool) bool
- func GetOrDuration(key string, defaultValue string) time.Duration
- func GetOrFloat32(key string, defaultValue float32) float32
- func GetOrFloat64(key string, defaultValue float64) float64
- func GetOrInt(key string, defaultValue int) int
- func GetOrInt64(key string, defaultValue int64) int64
- func GetOrParsed[T any](key string, defaultValue T, parser Parser[T]) T
- func GetOrUint(key string, defaultValue uint) uint
- func GetOrUint64(key string, defaultValue uint64) uint64
- func GetOrUrl(key string, defaultValue string) *url.URL
- func GetParsed[T any](key string, parser Parser[T]) (T, error)
- func GetRequiredVars(v interface{}, prefix string) ([]string, error)
- func GetUint(key string) (uint, error)
- func GetUint64(key string) (uint64, error)
- func GetUrl(key string) (*url.URL, error)
- func Load(filenames ...string) (err error)
- func Marshal(envMap map[string]string) (string, error)
- func MustGet(key string) string
- func MustGetBool(key string) bool
- func MustGetDuration(key string) time.Duration
- func MustGetFloat32(key string) float32
- func MustGetFloat64(key string) float64
- func MustGetInt(key string) int
- func MustGetInt64(key string) int64
- func MustGetParsed[T any](key string, parser Parser[T], typeName string) T
- func MustGetUint(key string) uint
- func MustGetUint64(key string) uint64
- func MustGetUrl(key string) *url.URL
- func MustGetWithContext(key, context string) string
- func MustLoad(filenames ...string)
- func MustOverload(filenames ...string)
- func Overload(filenames ...string) (err error)
- func Parse(v interface{}) error
- func ParseIO(r io.Reader) (envMap map[string]string, err error)
- func ParseWithFuncs(v interface{}, funcMap CustomParsers) error
- func ParseWithPrefix(v interface{}, prefix string) error
- func ParseWithPrefixFuncs(v interface{}, prefix string, funcMap CustomParsers) error
- func Read(filenames ...string) (envMap map[string]string, err error)
- func Set(key, value string) error
- func SetForTest(t TestHelper, key, value string) func()
- func Unmarshal(str string) (envMap map[string]string, err error)
- func Unset(key string) error
- func UnsetForTest(t TestHelper, key string) func()
- func ValidateRequired(v interface{}, prefix string) error
- func Write(envMap map[string]string, filename string) error
- type CustomParsers
- type ParseErrors
- type Parser
- type ParserFunc
- type TestHelper
- type VarInfo
Examples ¶
Constants ¶
const ( DecimalBase = 10 Int32Bits = 32 Int64Bits = 64 Float32Bits = 32 Float64Bits = 64 )
Constants for parsing operations (shared with util.go)
Variables ¶
var ( // ErrNotAStructPtr is returned if you pass something that is not a pointer to a // Struct to Parse ErrNotAStructPtr = errors.New("expected a pointer to a Struct") // ErrUnsupportedType if the struct field type is not supported by env ErrUnsupportedType = errors.New("type is not supported") // ErrUnsupportedSliceType if the slice element type is not supported by env ErrUnsupportedSliceType = errors.New("unsupported slice type") )
var ( // OnEnvVarSet is an optional convenience callback, such as for logging purposes. // If not nil, it's called after successfully setting the given field from the given value. OnEnvVarSet func(reflect.StructField, string) // DebugLogger is an optional function for logging configuration parsing details. // If not nil, it's called with debug messages during Parse operations. // Use EnableDebugLogging to set this conveniently. DebugLogger func(format string, args ...interface{}) )
var ( ParseBool = func(s string) (bool, error) { return strconv.ParseBool(s) } ParseInt = func(s string) (int, error) { v, err := strconv.ParseInt(s, DecimalBase, Int32Bits) return int(v), err } ParseUint = func(s string) (uint, error) { v, err := strconv.ParseUint(s, DecimalBase, Int32Bits) return uint(v), err } ParseFloat32 = func(s string) (float32, error) { v, err := strconv.ParseFloat(s, Float32Bits) return float32(v), err } ParseFloat64 = func(s string) (float64, error) { return strconv.ParseFloat(s, Float64Bits) } ParseInt64 = func(s string) (int64, error) { return strconv.ParseInt(s, DecimalBase, Int64Bits) } ParseUint64 = func(s string) (uint64, error) { return strconv.ParseUint(s, DecimalBase, Int64Bits) } ParseDuration = func(s string) (time.Duration, error) { return time.ParseDuration(s) } ParseURL = func(s string) (*url.URL, error) { return url.ParseRequestURI(s) } )
Type-specific parser functions
Functions ¶
func EnableDebugLogging ¶ added in v0.4.8
func EnableDebugLogging(logger func(format string, args ...interface{}))
EnableDebugLogging enables debug logging for configuration parsing. The provided logger function will be called with debug messages during Parse operations.
This is useful for debugging configuration issues, especially in production where you want to see what environment variables are being read and their values.
Example usage:
env.EnableDebugLogging(log.Printf)
cfg := &Config{}
env.Parse(&cfg) // Will log each env var as it's read
To disable debug logging, call env.EnableDebugLogging(nil).
func Get ¶ added in v0.2.0
Get retrieves the value of an environment variable. If the variable is not set, it returns an empty string.
This is a simple wrapper around os.Getenv for consistency with other functions in this package.
Example ¶
package main
import (
"fmt"
"os"
"github.com/lindenlab/env"
)
func main() {
os.Setenv("HOME", "/home/user")
fmt.Println(env.Get("HOME"))
fmt.Println(env.Get("NONEXISTENT"))
}
Output: /home/user
func GetBool ¶ added in v0.2.6
GetBool retrieves an environment variable and parses it as a boolean. It accepts values like "true", "false", "1", "0", "t", "f", "T", "F", "TRUE", "FALSE" (case-insensitive). Returns the parsed boolean value and any parsing error.
Example ¶
package main
import (
"fmt"
"os"
"github.com/lindenlab/env"
)
func main() {
os.Setenv("DEBUG", "true")
os.Setenv("VERBOSE", "1")
os.Setenv("QUIET", "false")
debug, _ := env.GetBool("DEBUG")
verbose, _ := env.GetBool("VERBOSE")
quiet, _ := env.GetBool("QUIET")
fmt.Println("Debug:", debug)
fmt.Println("Verbose:", verbose)
fmt.Println("Quiet:", quiet)
}
Output: Debug: true Verbose: true Quiet: false
func GetDuration ¶ added in v0.4.0
GetDuration retrieves an environment variable and parses it as a time.Duration. It accepts duration strings like "5s", "2m30s", "1h", "300ms", etc. See time.ParseDuration for the complete format specification. Returns the parsed duration value and any parsing error.
Example ¶
package main
import (
"fmt"
"os"
"github.com/lindenlab/env"
)
func main() {
os.Setenv("TIMEOUT", "30s")
os.Setenv("INTERVAL", "5m30s")
timeout, _ := env.GetDuration("TIMEOUT")
interval, _ := env.GetDuration("INTERVAL")
fmt.Println("Timeout:", timeout)
fmt.Println("Interval:", interval)
}
Output: Timeout: 30s Interval: 5m30s
func GetFloat32 ¶ added in v0.2.7
GetFloat32 retrieves an environment variable and parses it as a 32-bit floating point number. It accepts decimal numbers in standard or scientific notation. Returns the parsed float32 value and any parsing error.
func GetFloat64 ¶ added in v0.4.0
GetFloat64 retrieves an environment variable and parses it as a 64-bit floating point number. It accepts decimal numbers in standard or scientific notation. Returns the parsed float64 value and any parsing error.
func GetInt ¶ added in v0.2.6
GetInt retrieves an environment variable and parses it as a signed integer. It accepts decimal integers that fit in the int type (platform-dependent size). Returns the parsed integer value and any parsing error.
Example ¶
package main
import (
"fmt"
"log"
"os"
"github.com/lindenlab/env"
)
func main() {
os.Setenv("PORT", "8080")
os.Setenv("INVALID_PORT", "not-a-number")
port, err := env.GetInt("PORT")
if err != nil {
log.Fatal(err)
}
fmt.Println("Port:", port)
_, err = env.GetInt("INVALID_PORT")
fmt.Println("Error:", err != nil)
}
Output: Port: 8080 Error: true
func GetInt64 ¶ added in v0.4.0
GetInt64 retrieves an environment variable and parses it as a 64-bit signed integer. It accepts decimal integers in the range -9223372036854775808 to 9223372036854775807. Returns the parsed int64 value and any parsing error.
func GetOr ¶ added in v0.2.0
GetOr retrieves the value of an environment variable. If the variable is not set, it returns the provided default value.
This function distinguishes between unset variables and variables set to empty strings.
Example ¶
package main
import (
"fmt"
"os"
"github.com/lindenlab/env"
)
func main() {
os.Setenv("PORT", "8080")
fmt.Println(env.GetOr("PORT", "3000"))
fmt.Println(env.GetOr("MISSING_PORT", "3000"))
}
Output: 8080 3000
func GetOrBool ¶ added in v0.2.6
GetOrBool retrieves an environment variable and parses it as a boolean. If the variable is not set or parsing fails, it returns the default value.
func GetOrDuration ¶ added in v0.4.0
GetOrDuration retrieves an environment variable and parses it as a time.Duration. If the variable is not set or parsing fails, it parses and returns the default value. The default value must be a valid duration string, or the function will panic.
Note: This function takes a string default value (unlike other GetOr* functions) to maintain backwards compatibility with existing APIs.
func GetOrFloat32 ¶ added in v0.2.7
GetOrFloat32 retrieves an environment variable and parses it as a 32-bit floating point number. If the variable is not set or parsing fails, it returns the default value.
func GetOrFloat64 ¶ added in v0.4.0
GetOrFloat64 retrieves an environment variable and parses it as a 64-bit floating point number. If the variable is not set or parsing fails, it returns the default value.
func GetOrInt ¶ added in v0.2.6
GetOrInt retrieves an environment variable and parses it as a signed integer. If the variable is not set or parsing fails, it returns the default value.
Example ¶
package main
import (
"fmt"
"os"
"github.com/lindenlab/env"
)
func main() {
os.Setenv("PORT", "8080")
fmt.Println("Existing:", env.GetOrInt("PORT", 3000))
fmt.Println("Missing:", env.GetOrInt("MISSING_PORT", 3000))
fmt.Println("Invalid:", env.GetOrInt("INVALID_PORT", 3000))
}
Output: Existing: 8080 Missing: 3000 Invalid: 3000
func GetOrInt64 ¶ added in v0.4.0
GetOrInt64 retrieves an environment variable and parses it as a 64-bit signed integer. If the variable is not set or parsing fails, it returns the default value.
func GetOrParsed ¶ added in v0.4.6
GetOrParsed retrieves an environment variable and parses it using the provided parser function. If the environment variable is not set or parsing fails, it returns the default value.
This function never returns an error; it falls back to the default value on any failure.
func GetOrUint ¶ added in v0.2.6
GetOrUint retrieves an environment variable and parses it as an unsigned integer. If the variable is not set or parsing fails, it returns the default value.
func GetOrUint64 ¶ added in v0.4.0
GetOrUint64 retrieves an environment variable and parses it as a 64-bit unsigned integer. If the variable is not set or parsing fails, it returns the default value.
func GetOrUrl ¶ added in v0.4.0
GetOrUrl retrieves an environment variable and parses it as a URL. If the variable is not set or parsing fails, it parses and returns the default value. The default value must be a valid URL string, or the function will panic.
Note: This function takes a string default value (unlike other GetOr* functions) to maintain backwards compatibility with existing APIs.
func GetParsed ¶ added in v0.4.6
GetParsed retrieves an environment variable and parses it using the provided parser function. It returns the parsed value and any parsing error. If the environment variable is not set, the parser receives an empty string.
This is a generic function that can be used with any type that has a corresponding parser. For common types, use the specific Get* functions which are more convenient.
func GetRequiredVars ¶ added in v0.4.8
GetRequiredVars returns the names of all required environment variables that would be read when parsing the given struct.
The prefix parameter is prepended to all environment variable names.
This function is useful for validating that all required variables are set before attempting to parse the configuration.
Example usage:
required := env.GetRequiredVars(&Config{}, "")
for _, name := range required {
if _, ok := os.LookupEnv(name); !ok {
log.Fatalf("Required environment variable %s is not set", name)
}
}
func GetUint ¶ added in v0.2.6
GetUint retrieves an environment variable and parses it as an unsigned integer. It accepts non-negative decimal integers that fit in the uint type (platform-dependent size). Returns the parsed unsigned integer value and any parsing error.
func GetUint64 ¶ added in v0.4.0
GetUint64 retrieves an environment variable and parses it as a 64-bit unsigned integer. It accepts non-negative decimal integers in the range 0 to 18446744073709551615. Returns the parsed uint64 value and any parsing error.
func GetUrl ¶ added in v0.4.0
GetUrl retrieves an environment variable and parses it as a URL. It accepts absolute URLs and parses them using url.ParseRequestURI. Returns the parsed *url.URL value and any parsing error.
func Load ¶ added in v0.2.5
Load reads environment variables from .env files and sets them in the current process. If no filenames are provided, it defaults to loading ".env" from the current directory.
Multiple files can be loaded in order:
err := env.Load("base.env", "local.env")
Important: Load will NOT override environment variables that are already set. This allows .env files to provide defaults while respecting existing environment configuration. Use Overload if you need to override existing variables.
The function returns an error if any file cannot be read or parsed. Call this early in your program, typically in main().
Example ¶
package main
import (
"fmt"
"log"
"os"
"github.com/lindenlab/env"
)
func main() {
// Create a temporary .env file
envContent := `# Database configuration
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=myapp
# Application settings
DEBUG=true
LOG_LEVEL=info`
err := os.WriteFile(".env", []byte(envContent), 0600)
if err != nil {
log.Fatal(err)
}
defer os.Remove(".env")
// Load the .env file
err = env.Load()
if err != nil {
log.Fatal(err)
}
// Access the loaded variables
fmt.Println("Database Host:", env.Get("DATABASE_HOST"))
fmt.Println("Database Port:", env.GetOrInt("DATABASE_PORT", 0))
fmt.Println("Debug Mode:", env.GetOrBool("DEBUG", false))
}
Output: Database Host: localhost Database Port: 5432 Debug Mode: true
func Marshal ¶ added in v0.2.5
Marshal converts a map of environment variables to .env file format. It returns a string with KEY="VALUE" pairs, one per line, with keys sorted alphabetically and values properly escaped with backslashes.
This function does not write to any file; use Write to save the output to disk.
Example ¶
package main
import (
"fmt"
"log"
"github.com/lindenlab/env"
)
func main() {
envMap := map[string]string{
"DATABASE_URL": "postgres://localhost/myapp",
"DEBUG": "true",
"PORT": "8080",
"API_KEY": "secret with spaces",
}
content, err := env.Marshal(envMap)
if err != nil {
log.Fatal(err)
}
fmt.Println(content)
}
Output: API_KEY="secret with spaces" DATABASE_URL="postgres://localhost/myapp" DEBUG="true" PORT="8080"
func MustGet ¶ added in v0.2.0
MustGet retrieves the value of an environment variable. If the variable is not set, it panics with a descriptive message.
Use this function when the environment variable is required for the application to function.
func MustGetBool ¶ added in v0.2.6
MustGetBool retrieves an environment variable and parses it as a boolean. If the variable is not set or parsing fails, it panics.
func MustGetDuration ¶ added in v0.4.0
MustGetDuration retrieves an environment variable and parses it as a time.Duration. If the variable is not set or parsing fails, it panics.
func MustGetFloat32 ¶ added in v0.2.7
MustGetFloat32 retrieves an environment variable and parses it as a 32-bit floating point number. If the variable is not set or parsing fails, it panics.
func MustGetFloat64 ¶ added in v0.4.0
MustGetFloat64 retrieves an environment variable and parses it as a 64-bit floating point number. If the variable is not set or parsing fails, it panics.
func MustGetInt ¶ added in v0.2.6
MustGetInt retrieves an environment variable and parses it as a signed integer. If the variable is not set or parsing fails, it panics.
func MustGetInt64 ¶ added in v0.4.0
MustGetInt64 retrieves an environment variable and parses it as a 64-bit signed integer. If the variable is not set or parsing fails, it panics.
func MustGetParsed ¶ added in v0.4.6
MustGetParsed retrieves an environment variable and parses it using the provided parser function. If the environment variable is not set or parsing fails, it panics with a descriptive message.
The typeName parameter is used in panic messages to identify the expected type. Use this function when the environment variable is required for the application to function.
func MustGetUint ¶ added in v0.2.6
MustGetUint retrieves an environment variable and parses it as an unsigned integer. If the variable is not set or parsing fails, it panics.
func MustGetUint64 ¶ added in v0.4.0
MustGetUint64 retrieves an environment variable and parses it as a 64-bit unsigned integer. If the variable is not set or parsing fails, it panics.
func MustGetUrl ¶ added in v0.4.0
MustGetUrl retrieves an environment variable and parses it as a URL. If the variable is not set or parsing fails, it panics.
func MustGetWithContext ¶ added in v0.4.8
MustGetWithContext retrieves the value of an environment variable with additional context. If the variable is not set, it panics with a descriptive message that includes the context.
The context parameter should describe why this variable is needed, making errors more helpful. For example: "generating wallet URIs" or "connecting to database".
Use this function when the environment variable is required and you want to provide additional context in error messages.
func MustLoad ¶ added in v0.2.7
func MustLoad(filenames ...string)
MustLoad reads environment variables from .env files and sets them in the current process. If no filenames are provided, it defaults to loading ".env" from the current directory.
This function behaves exactly like Load, except it panics on any error instead of returning it. Use this when .env file loading is critical for your application to function.
Multiple files can be loaded in order:
env.MustLoad("base.env", "local.env")
Like Load, this will NOT override environment variables that are already set.
func MustOverload ¶ added in v0.2.7
func MustOverload(filenames ...string)
MustOverload reads environment variables from .env files and sets them in the current process, overriding any existing environment variables. If no filenames are provided, it defaults to loading ".env" from the current directory.
This function behaves exactly like Overload, except it panics on any error instead of returning it. Use this when .env file loading is critical and should override existing configuration.
Multiple files can be loaded in order:
env.MustOverload("base.env", "production.env")
func Overload ¶ added in v0.2.5
Overload reads environment variables from .env files and sets them in the current process, overriding any existing environment variables. If no filenames are provided, it defaults to loading ".env" from the current directory.
Unlike Load, this function WILL override environment variables that are already set. Use this when you want .env files to take precedence over existing environment configuration.
Multiple files can be loaded in order:
err := env.Overload("base.env", "production.env")
The function returns an error if any file cannot be read or parsed.
func Parse ¶
func Parse(v interface{}) error
Parse populates a struct's fields from environment variables. The struct fields must be tagged with `env:"VAR_NAME"` to specify which environment variable to read.
Supported struct tags:
- env:"VAR_NAME" - specifies the environment variable name (required)
- envDefault:"value" - default value if the environment variable is not set
- required:"true" - makes the field required (causes error if missing)
- envSeparator:"," - separator for slice types (default is comma)
- envExpand:"true" - enables variable expansion using os.ExpandEnv
The function supports nested structs and pointers to structs. It returns an error if required fields are missing or if type conversion fails.
Example ¶
type config struct {
Home string `env:"HOME"`
Port int `env:"PORT" envDefault:"3000"`
IsProduction bool `env:"PRODUCTION"`
}
os.Setenv("HOME", "/tmp/fakehome")
cfg := config{}
_ = Parse(&cfg)
fmt.Println(cfg)
Output: {/tmp/fakehome 3000 false}
Example ¶
package main
import (
"fmt"
"log"
"os"
"time"
"github.com/lindenlab/env"
)
func main() {
// Set up environment variables
os.Setenv("HOME", "/tmp/fakehome")
os.Setenv("PORT", "8080")
os.Setenv("DEBUG", "true")
os.Setenv("TAGS", "web,api,database")
os.Setenv("TIMEOUT", "30s")
type Config struct {
Home string `env:"HOME"`
Port int `env:"PORT" envDefault:"3000"`
Debug bool `env:"DEBUG"`
Tags []string `env:"TAGS" envSeparator:","`
Timeout time.Duration `env:"TIMEOUT" envDefault:"10s"`
Version string `env:"VERSION" envDefault:"1.0.0"`
Required string `env:"REQUIRED_VAR" required:"true"`
}
// This will fail because REQUIRED_VAR is not set
var cfg Config
err := env.Parse(&cfg)
if err != nil {
fmt.Println("Error:", err != nil)
}
// Set the required variable and try again
os.Setenv("REQUIRED_VAR", "important-value")
err = env.Parse(&cfg)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Home: %s\n", cfg.Home)
fmt.Printf("Port: %d\n", cfg.Port)
fmt.Printf("Debug: %t\n", cfg.Debug)
fmt.Printf("Tags: %v\n", cfg.Tags)
fmt.Printf("Timeout: %v\n", cfg.Timeout)
fmt.Printf("Version: %s\n", cfg.Version)
fmt.Printf("Required: %s\n", cfg.Required)
}
Output: Error: true Home: /tmp/fakehome Port: 8080 Debug: true Tags: [web api database] Timeout: 30s Version: 1.0.0 Required: important-value
func ParseIO ¶ added in v0.2.5
ParseIO reads environment variables from an io.Reader in .env format. It parses the content and returns a map of key-value pairs.
This function supports the standard .env file format including:
- Comments (lines starting with #)
- Quoted values (both single and double quotes)
- Variable expansion (${VAR} and $VAR syntax)
- Multiline values
- Both KEY=value and KEY: value formats
It does not set any environment variables; it only parses and returns the data.
func ParseWithFuncs ¶
func ParseWithFuncs(v interface{}, funcMap CustomParsers) error
ParseWithFuncs populates a struct's fields from environment variables, using custom parsing functions for specific types.
This allows you to handle types that aren't supported by default. The funcMap parameter maps reflect.Type values to ParserFunc implementations.
See Parse for details on supported struct tags and behavior.
func ParseWithPrefix ¶
ParseWithPrefix populates a struct's fields from environment variables with a prefix. This is useful for loading different configurations for the same struct type.
For example, with prefix "CLIENT2_", a field tagged `env:"ENDPOINT"` will read from the environment variable "CLIENT2_ENDPOINT".
The prefix must end with an underscore if it's not empty, otherwise an error is returned.
See Parse for details on supported struct tags and behavior.
Example ¶
package main
import (
"fmt"
"log"
"os"
"github.com/lindenlab/env"
)
func main() {
// Set up environment variables with prefixes
os.Setenv("CLIENT1_HOST", "api.example.com")
os.Setenv("CLIENT1_PORT", "443")
os.Setenv("CLIENT2_HOST", "internal.example.com")
os.Setenv("CLIENT2_PORT", "8080")
type ClientConfig struct {
Host string `env:"HOST" envDefault:"localhost"`
Port int `env:"PORT" envDefault:"80"`
}
var client1, client2 ClientConfig
err := env.ParseWithPrefix(&client1, "CLIENT1_")
if err != nil {
log.Fatal(err)
}
err = env.ParseWithPrefix(&client2, "CLIENT2_")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Client 1: %s:%d\n", client1.Host, client1.Port)
fmt.Printf("Client 2: %s:%d\n", client2.Host, client2.Port)
}
Output: Client 1: api.example.com:443 Client 2: internal.example.com:8080
func ParseWithPrefixFuncs ¶
func ParseWithPrefixFuncs(v interface{}, prefix string, funcMap CustomParsers) error
ParseWithPrefixFuncs populates a struct's fields from environment variables with both a prefix and custom parsing functions.
This combines the functionality of ParseWithPrefix and ParseWithFuncs, allowing both prefixed variable names and custom type parsing.
The prefix must end with an underscore if it's not empty, otherwise an error is returned.
See Parse for details on supported struct tags and behavior.
func Read ¶ added in v0.2.5
Read parses .env files and returns the key-value pairs as a map, without setting them as environment variables in the current process.
This is useful when you want to inspect or manipulate the values before applying them, or when you want to use the values in a different way. If no filenames are provided, it defaults to reading ".env" from the current directory.
Multiple files can be read, with later files overriding earlier ones:
envMap, err := env.Read("base.env", "local.env")
if err != nil {
log.Fatal(err)
}
fmt.Printf("DATABASE_URL=%s\n", envMap["DATABASE_URL"])
Example ¶
package main
import (
"fmt"
"log"
"os"
"github.com/lindenlab/env"
)
func main() {
// Create a temporary .env file
envContent := `DATABASE_URL=postgres://localhost/myapp
REDIS_URL=redis://localhost:6379
API_KEY=secret123
DEBUG=true`
err := os.WriteFile("config.env", []byte(envContent), 0600)
if err != nil {
log.Fatal(err)
}
defer os.Remove("config.env")
// Read the file without setting environment variables
envMap, err := env.Read("config.env")
if err != nil {
log.Fatal(err)
}
fmt.Println("Database URL:", envMap["DATABASE_URL"])
fmt.Println("Redis URL:", envMap["REDIS_URL"])
fmt.Println("Debug:", envMap["DEBUG"])
}
Output: Database URL: postgres://localhost/myapp Redis URL: redis://localhost:6379 Debug: true
func Set ¶ added in v0.2.0
Set sets an environment variable to the specified value. It returns an error if the operation fails.
This is a simple wrapper around os.Setenv for consistency with other functions in this package.
func SetForTest ¶ added in v0.4.8
func SetForTest(t TestHelper, key, value string) func()
SetForTest sets an environment variable for testing and automatically cleans it up. It returns a cleanup function that can be called manually, though cleanup is also registered with t.Cleanup() if t is non-nil.
If the environment variable already exists, it will be restored to its original value. If it doesn't exist, it will be removed during cleanup.
Example usage:
func TestConfig(t *testing.T) {
cleanup := env.SetForTest(t, "WALLET_TRANSACTION_API", "https://test.com")
defer cleanup() // Optional: cleanup is also registered with t.Cleanup()
// test code
}
func Unmarshal ¶ added in v0.2.5
Unmarshal parses environment variables from a string in .env format. It returns a map of key-value pairs without setting any environment variables.
This is a convenience function that wraps ParseIO with a strings.NewReader. See ParseIO for details on the supported .env file format.
func Unset ¶ added in v0.2.0
Unset removes an environment variable. It returns an error if the operation fails.
This is a simple wrapper around os.Unsetenv for consistency with other functions in this package.
func UnsetForTest ¶ added in v0.4.8
func UnsetForTest(t TestHelper, key string) func()
UnsetForTest removes an environment variable for testing and automatically restores it. It returns a cleanup function that can be called manually, though cleanup is also registered with t.Cleanup() if t is non-nil.
If the environment variable exists, it will be restored to its original value during cleanup.
Example usage:
func TestWithoutEnv(t *testing.T) {
cleanup := env.UnsetForTest(t, "OPTIONAL_CONFIG")
defer cleanup()
// test code that expects the variable to not exist
}
func ValidateRequired ¶ added in v0.4.8
ValidateRequired checks if all required environment variables for the given struct are set. It does not parse the values, only checks for their existence.
This is useful for validating configuration at startup before attempting to parse, which can provide clearer error messages.
Example usage:
if err := env.ValidateRequired(&Config{}, ""); err != nil {
log.Fatalf("Configuration validation failed: %v", err)
}
// Now safe to parse
env.Parse(&cfg)
Types ¶
type CustomParsers ¶
type CustomParsers map[reflect.Type]ParserFunc
CustomParsers maps Go types to custom parsing functions. It allows you to provide custom logic for parsing environment variables into specific types that aren't supported by default.
The key is the reflect.Type of the target type, and the value is a ParserFunc that knows how to convert a string to that type.
type ParseErrors ¶ added in v0.4.6
type ParseErrors []error
ParseErrors represents multiple errors that occurred during parsing
func (ParseErrors) Error ¶ added in v0.4.6
func (pe ParseErrors) Error() string
Error implements the error interface for ParseErrors
type Parser ¶ added in v0.4.6
Parser is a function type that converts a string value to type T. It is used by the generic parsing functions to provide type-safe conversion from environment variable string values.
type ParserFunc ¶
ParserFunc defines the signature of a custom parsing function. It takes a string value from an environment variable and returns the parsed value as an interface{} and any parsing error.
The returned value should be of the type that the parser is designed to handle.
type TestHelper ¶ added in v0.4.8
type TestHelper interface {
Helper()
Cleanup(func())
}
TestHelper is an interface that represents a testing object (typically *testing.T or *testing.B). It provides the minimal interface needed for test helper functions.
type VarInfo ¶ added in v0.4.8
type VarInfo struct {
// Name is the full environment variable name (including any prefix)
Name string
// FieldName is the struct field name
FieldName string
// FieldPath is the full path to the field (for nested structs)
FieldPath string
// Required indicates if the environment variable is required
Required bool
// Default is the default value if the environment variable is not set
Default string
// Type is the Go type of the field
Type string
// HasDefault indicates if a default value is specified
HasDefault bool
}
VarInfo contains information about an environment variable used by a struct field.
func GetAllVars ¶ added in v0.4.8
GetAllVars returns information about all environment variables that would be read when parsing the given struct. This includes both required and optional variables.
The prefix parameter is prepended to all environment variable names.
This function is useful for:
- Generating documentation
- Creating example .env files
- Debugging configuration issues
- Validating that all expected variables are set
Example usage:
vars := env.GetAllVars(&Config{}, "")
for _, v := range vars {
fmt.Printf("%s: %s (required: %v, default: %s)\n",
v.Name, v.Type, v.Required, v.Default)
}