Files
config/README.md

181 lines
4.2 KiB
Markdown

# Config
Thread-safe configuration management for Go with support for TOML files, environment variables, command-line arguments, and defaults with configurable precedence.
## Installation
```bash
go get github.com/LixenWraith/config
```
## Quick Start
```go
package main
import (
"log"
"github.com/lixenwraith/config"
)
type AppConfig struct {
Server struct {
Host string `toml:"host"`
Port int `toml:"port"`
} `toml:"server"`
Database struct {
URL string `toml:"url"`
MaxConns int `toml:"max_conns"`
} `toml:"database"`
Debug bool `toml:"debug"`
}
func main() {
// Define defaults
defaults := AppConfig{}
defaults.Server.Host = "localhost"
defaults.Server.Port = 8080
defaults.Database.URL = "postgres://localhost/myapp"
defaults.Database.MaxConns = 10
// Initialize with environment prefix and config file
cfg, err := config.Quick(defaults, "MYAPP_", "config.toml")
if err != nil {
log.Fatal(err)
}
// Access values
host, _ := cfg.String("server.host")
port, _ := cfg.Int64("server.port")
dbURL, _ := cfg.String("database.url")
debug, _ := cfg.Bool("debug")
log.Printf("Server: %s:%d, DB: %s, Debug: %v", host, port, dbURL, debug)
}
```
**config.toml:**
```toml
[server]
host = "production.example.com"
port = 9090
[database]
url = "postgres://prod-db/myapp"
max_conns = 50
debug = false
```
**Usage:**
```bash
# Override with environment variables
export MYAPP_SERVER_PORT=8443
export MYAPP_DEBUG=true
# Override with CLI arguments
./myapp --server.port=9999 --debug
```
## Key Features
- **Multiple Sources**: Defaults → File → Environment → CLI (configurable order)
- **Type Safety**: Automatic conversion with detailed error messages
- **Thread-Safe**: Concurrent reads with protected writes
- **Builder Pattern**: Fluent interface for advanced configuration
- **Source Tracking**: See which source provided each value
- **Zero Dependencies**: Only stdlib + minimal parsers
## Common Patterns
### Custom Precedence
```go
cfg, _ := config.NewBuilder().
WithDefaults(defaults).
WithSources(
config.SourceEnv, // Env vars highest priority
config.SourceFile,
config.SourceCLI,
config.SourceDefault,
).
Build()
```
### Environment Variable Mapping
```go
// Custom env var names
opts := config.LoadOptions{
EnvTransform: func(path string) string {
switch path {
case "server.port": return "PORT"
case "database.url": return "DATABASE_URL"
default: return ""
}
},
}
cfg.LoadWithOptions("config.toml", os.Args[1:], opts)
```
### Validation
```go
// Register and validate required fields
cfg.RegisterRequired("api.key", "")
cfg.RegisterRequired("database.url", "")
if err := cfg.Validate("api.key", "database.url"); err != nil {
log.Fatal("Missing required config: ", err)
}
```
### Source Inspection
```go
// See all sources for a value
sources := cfg.GetSources("server.port")
for source, value := range sources {
fmt.Printf("%s: %v\n", source, value)
}
// Get value from specific source
envPort, exists := cfg.GetSource("server.port", config.SourceEnv)
```
### Struct Scanning
```go
var serverConfig struct {
Host string `toml:"host"`
Port int `toml:"port"`
}
cfg.Scan("server", &serverConfig)
```
### Environment Whitelist
```go
// Only load specific env vars
cfg, _ := config.NewBuilder().
WithDefaults(defaults).
WithEnvPrefix("MYAPP_").
WithEnvWhitelist("api.key", "database.password").
Build()
```
## API Reference
### Core Methods
- `Quick(defaults, envPrefix, configFile)` - Quick initialization
- `Register(path, defaultValue)` - Register configuration path
- `Get/String/Int64/Bool/Float64(path)` - Type-safe accessors
- `Set(path, value)` - Update configuration
- `Validate(paths...)` - Ensure required values are set
### Advanced Methods
- `NewBuilder()` - Create custom configuration
- `GetSource(path, source)` - Get value from specific source
- `GetSources(path)` - Get all source values
- `Scan(basePath, target)` - Unmarshal into struct
- `Clone()` - Deep copy configuration
- `Debug()` - Show all values and sources
## License
BSD-3-Clause