v0.2.0 toml-only, harden concurrency and env export, dep updates
Test / test (push) Canceled after 0s
Test / test (push) Canceled after 0s
This commit is contained in:
1 parent
3c35601179
commit
e08467bf38
42 files changed
+2533
-4274
No files matched your search
+18
-198
@@ -1,202 +1,22 @@
|
||||
# Environment Variables
|
||||
# Environment variables
|
||||
|
||||
The config package provides flexible environment variable support with automatic name transformation, custom mappings, and whitelist capabilities.
|
||||
`LoadEnv("APP_")` maps `server.port` to `APP_SERVER_PORT`. It replaces the complete
|
||||
environment source: variables removed since the previous load lose their overrides.
|
||||
Set `LoadOptions.EnvTransform` for custom names and `EnvWhitelist` to limit paths.
|
||||
Options are copied. Custom transforms run outside Config locks and may inspect Config.
|
||||
|
||||
## Basic Usage
|
||||
Environment values are stored as strings and validated against registered types
|
||||
before any part of the replacement is published. Numbers use decimal text; durations
|
||||
use Go duration syntax; timestamps use RFC3339Nano-compatible text. Slices and arrays
|
||||
use comma-separated elements without an escaping convention. Empty text gives an
|
||||
empty slice. Values larger than MaxValueSize are rejected.
|
||||
|
||||
Environment variables are automatically mapped from configuration paths:
|
||||
`RegisterWithEnv` and a struct field's `env` tag load an explicitly named variable
|
||||
during registration. Later `LoadEnv` calls use the configured transform/whitelist,
|
||||
so explicit registration-time mappings are not automatically repeated on reload.
|
||||
|
||||
```go
|
||||
cfg, _ := config.Quick(defaults, "MYAPP_", "config.toml")
|
||||
|
||||
// These environment variables are automatically loaded:
|
||||
// MYAPP_SERVER_PORT → server.port
|
||||
// MYAPP_DATABASE_URL → database.url
|
||||
// MYAPP_LOG_LEVEL → log.level
|
||||
// MYAPP_FEATURES_ENABLED → features.enabled
|
||||
```
|
||||
|
||||
## Name Transformation
|
||||
|
||||
### Default Transformation
|
||||
|
||||
By default, paths are transformed as follows:
|
||||
1. Dots (`.`) become underscores (`_`)
|
||||
2. Converted to uppercase
|
||||
3. Prefix is prepended
|
||||
|
||||
```go
|
||||
// Path transformations:
|
||||
// server.port → MYAPP_SERVER_PORT
|
||||
// database.url → MYAPP_DATABASE_URL
|
||||
// tls.cert.path → MYAPP_TLS_CERT_PATH
|
||||
// maxRetries → MYAPP_MAXRETRIES
|
||||
```
|
||||
|
||||
### Custom Transformation
|
||||
|
||||
Define custom environment variable mappings:
|
||||
|
||||
```go
|
||||
cfg, _ := config.NewBuilder().
|
||||
WithEnvTransform(func(path string) string {
|
||||
switch path {
|
||||
case "server.port":
|
||||
return "PORT" // Use $PORT directly
|
||||
case "database.url":
|
||||
return "DATABASE_URL"
|
||||
case "api.key":
|
||||
return "API_KEY"
|
||||
default:
|
||||
// Fallback to default transformation
|
||||
return "MYAPP_" + strings.ToUpper(
|
||||
strings.ReplaceAll(path, ".", "_"),
|
||||
)
|
||||
}
|
||||
}).
|
||||
Build()
|
||||
```
|
||||
|
||||
### No Transformation
|
||||
|
||||
Return empty string to skip environment lookup:
|
||||
|
||||
```go
|
||||
cfg, _ := config.NewBuilder().
|
||||
WithEnvTransform(func(path string) string {
|
||||
// Only allow specific env vars
|
||||
allowed := map[string]string{
|
||||
"port": "PORT",
|
||||
"database": "DATABASE_URL",
|
||||
}
|
||||
return allowed[path] // Empty string if not in map
|
||||
}).
|
||||
Build()
|
||||
```
|
||||
|
||||
## Explicit Environment Variable Mapping
|
||||
|
||||
Use the `env` struct tag for explicit mappings:
|
||||
|
||||
```go
|
||||
type Config struct {
|
||||
Port int `toml:"port" env:"PORT"`
|
||||
Database string `toml:"database" env:"DATABASE_URL"`
|
||||
APIKey string `toml:"api_key" env:"API_KEY"`
|
||||
}
|
||||
|
||||
// These use the explicit env tag names, ignoring prefix
|
||||
cfg, _ := config.NewBuilder().
|
||||
WithDefaults(&Config{}).
|
||||
WithEnvPrefix("MYAPP_"). // Not used for tagged fields
|
||||
Build()
|
||||
```
|
||||
|
||||
Or register with explicit environment variable:
|
||||
|
||||
```go
|
||||
cfg.RegisterWithEnv("server.port", 8080, "PORT")
|
||||
cfg.RegisterWithEnv("database.url", "localhost", "DATABASE_URL")
|
||||
```
|
||||
|
||||
## Using the `env` Tag
|
||||
|
||||
Structs can specify explicit environment variable names using the `env` tag:
|
||||
|
||||
```go
|
||||
type Config struct {
|
||||
Server struct {
|
||||
Port int `toml:"port" env:"PORT"` // Uses $PORT
|
||||
Host string `toml:"host" env:"SERVER_HOST"` // Uses $SERVER_HOST
|
||||
} `toml:"server"`
|
||||
}
|
||||
```
|
||||
|
||||
## Environment Variable Whitelist
|
||||
|
||||
Limit which paths can be set via environment:
|
||||
|
||||
```go
|
||||
cfg, _ := config.NewBuilder().
|
||||
WithEnvWhitelist(
|
||||
"server.port",
|
||||
"database.url",
|
||||
"api.key",
|
||||
"log.level",
|
||||
). // Only these paths read from environment
|
||||
Build()
|
||||
```
|
||||
|
||||
## Type Conversion
|
||||
|
||||
Environment variables (strings) are automatically converted to the registered type:
|
||||
|
||||
```bash
|
||||
# Booleans
|
||||
export MYAPP_DEBUG=true
|
||||
export MYAPP_VERBOSE=false
|
||||
|
||||
# Numbers
|
||||
export MYAPP_PORT=8080
|
||||
export MYAPP_TIMEOUT=30
|
||||
export MYAPP_RATIO=0.95
|
||||
|
||||
# Durations
|
||||
export MYAPP_TIMEOUT=30s
|
||||
export MYAPP_INTERVAL=5m
|
||||
|
||||
# Lists (comma-separated)
|
||||
export MYAPP_TAGS=prod,stable,v2
|
||||
```
|
||||
|
||||
## Manual Environment Loading
|
||||
|
||||
Load environment variables at any time:
|
||||
|
||||
```go
|
||||
cfg := config.New()
|
||||
cfg.RegisterStruct("", &Config{})
|
||||
|
||||
// Load with prefix
|
||||
if err := cfg.LoadEnv("MYAPP_"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Or use existing options
|
||||
if err := cfg.LoadWithOptions("", nil, config.LoadOptions{
|
||||
EnvPrefix: "MYAPP_",
|
||||
Sources: []config.Source{config.SourceEnv},
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
```
|
||||
|
||||
## Discovering Environment Variables
|
||||
|
||||
Find which environment variables are set:
|
||||
|
||||
```go
|
||||
// Discover all env vars matching registered paths
|
||||
discovered := cfg.DiscoverEnv("MYAPP_")
|
||||
|
||||
for path, envVar := range discovered {
|
||||
log.Printf("%s is set via %s", path, envVar)
|
||||
}
|
||||
```
|
||||
|
||||
## Precedence Examples
|
||||
|
||||
Default precedence: CLI > Env > File > Default
|
||||
|
||||
Custom precedence (Env > File > CLI > Default):
|
||||
|
||||
```go
|
||||
cfg, _ := config.NewBuilder().
|
||||
WithSources(
|
||||
config.SourceEnv,
|
||||
config.SourceFile,
|
||||
config.SourceCLI,
|
||||
config.SourceDefault,
|
||||
).
|
||||
Build()
|
||||
```
|
||||
`DiscoverEnv(prefix)` returns registered paths with present variable names.
|
||||
`ExportEnv(prefix)` returns formatted effective values that differ from defaults;
|
||||
it safely handles containers. It is diagnostic output, not a general lossless
|
||||
serialization format for maps, slices or strings containing delimiters. Use Save
|
||||
for round-trip persistence.
|
||||
Reference in new issue
Block a user