Config Package
The config
package provides a comprehensive configuration management system for Go applications. It offers a unified interface for loading, accessing, and manipulating configuration data from various sources such as environment variables, files, and in-memory stores.
Features
- Multiple Data Sources: Load configuration from files, environment variables, or programmatically
- Type-Safe Access: Get configuration values as specific types (string, int, float, bool)
- Default Values: Specify fallback values when configuration keys are missing
- Dynamic Configuration: Update configuration values at runtime
- Persistence: Save configuration changes back to storage
Core Components
Configuration Interface
The core of the package is the Configuration
interface, which provides methods for loading, saving, and accessing configuration values:
type Configuration interface {
Load(r io.Reader) error
Save(w io.Writer) error
Get(k, defaultVal string) string
GetAsInt(k string, defaultVal int) (int, error)
GetAsInt64(k string, defaultVal int64) (int64, error)
GetAsBool(k string, defaultVal bool) (bool, error)
GetAsDecimal(k string, defaultVal float64) (float64, error)
Put(k, v string) string
PutInt(k string, v int) (int, error)
PutInt64(k string, v int64) (int64, error)
PutBool(k string, v bool) (bool, error)
PutDecimal(k string, v float64) (float64, error)
}
Implementation Types
The package includes several concrete implementations of the Configuration interface:
- Properties: Manages configuration as key-value pairs, typically loaded from properties files
- MapAttributes: Stores configuration in an in-memory map
- Environment: Accesses configuration from environment variables
Usage Examples
Loading Configuration from a File
package main
import (
"fmt"
"os"
"oss.nandlabs.io/golly/config"
)
func main() {
// Create a new Properties configuration
conf := config.NewProperties()
// Open the configuration file
file, err := os.Open("config.properties")
if err != nil {
fmt.Printf("Error opening config file: %v\n", err)
return
}
defer file.Close()
// Load the configuration
if err := conf.Load(file); err != nil {
fmt.Printf("Error loading config: %v\n", err)
return
}
// Access configuration values
serverHost := conf.Get("server.host", "localhost")
serverPort, _ := conf.GetAsInt("server.port", 8080)
fmt.Printf("Server: %s:%d\n", serverHost, serverPort)
}
Creating and Modifying Configuration
package main
import (
"fmt"
"oss.nandlabs.io/golly/config"
)
func main() {
// Create a new in-memory configuration
conf := config.NewMapAttributes()
// Set configuration values
conf.Put("app.name", "MyApp")
conf.PutInt("app.version.major", 1)
conf.PutInt("app.version.minor", 2)
conf.PutBool("app.debug", true)
// Access configuration values
appName := conf.Get("app.name", "")
majorVersion, _ := conf.GetAsInt("app.version.major", 0)
minorVersion, _ := conf.GetAsInt("app.version.minor", 0)
debugMode, _ := conf.GetAsBool("app.debug", false)
fmt.Printf("%s v%d.%d (Debug: %t)\n", appName, majorVersion, minorVersion, debugMode)
}
Using Environment Variables
package main
import (
"fmt"
"os"
"oss.nandlabs.io/golly/config"
)
func main() {
// Set some environment variables for demonstration
os.Setenv("APP_HOST", "example.com")
os.Setenv("APP_PORT", "9000")
// Create a configuration that reads from environment variables
conf := config.NewEnvironment()
// Access configuration from environment variables
host := conf.Get("APP_HOST", "localhost")
port, _ := conf.GetAsInt("APP_PORT", 8080)
fmt.Printf("Application will run on %s:%d\n", host, port)
}
Installation
go get oss.nandlabs.io/golly/config