### Install GoCfg Package Source: https://github.com/jagerente/gocfg/blob/main/README.md This command installs the GoCfg package and its dependencies using the Go module system. It ensures you have the latest version available for use in your project. ```bash go get -u github.com/Jagerente/gocfg ``` -------------------------------- ### Generate Configuration Documentation File (Go) Source: https://github.com/jagerente/gocfg/blob/main/README.md This Go program utilizes the gocfg library to generate a documentation file for the application's configuration. It creates a new configuration struct, opens a file for writing, and then uses `cfgManager.GenerateDocumentation` with an `EnvDocGenerator` to populate the file with configuration details, including descriptions, defaults, and examples. ```Go package main import ( "fmt" "github.com/Jagerente/gocfg" "github.com/Jagerente/gocfg/pkg/docgens" "os" "your_cool_app/internal/config" ) const outputFile = ".env.dist.generated" func main() { cfg := new(config.Config) file, err := os.Create(outputFile) if err != nil { panic(fmt.Errorf("error creating %s file: %v", outputFile, err)) } cfgManager := gocfg.NewDefault() if err := cfgManager.GenerateDocumentation(cfg, docgens.NewEnvDocGenerator(file)); err != nil { panic(err) } } ``` -------------------------------- ### Implement Custom Value Provider for GoCfg Source: https://github.com/jagerente/gocfg/blob/main/README.md Demonstrates how to create and register a custom value provider with GoCfg. This allows fetching configuration values from custom sources, such as environment variables with a specific prefix, by implementing the `Get` method. ```go package main import ( "github.com/Jagerente/gocfg" "os" ) type CustomValueProvider struct { } func NewCustomValueProvider() *CustomValueProvider { return &CustomValueProvider{} } func (p *CustomValueProvider) Get(key string) string { return os.Getenv("CUSTOM_" + key) } type AppConfig struct { BoolField bool `env:"BOOL_FIELD"` StringField string `env:"STRING_FIELD"` IntField int `env:"INT_FIELD"` } func main() { customValueProvider := NewCustomValueProvider() cfg := gocfg.NewDefault(). AddValueProviders(customValueProvider) appConfig := new(AppConfig) if err := cfg.Unmarshal(appConfig); err != nil { panic(err) } } ``` -------------------------------- ### Implement Custom Value Provider for Prefixed Environment Variables in Go Source: https://context7.com/jagerente/gocfg/llms.txt Shows how to implement a custom ValueProvider to read configuration from environment variables with a specific prefix. This is useful for namespacing configuration keys. The example defines a PrefixedEnvProvider and demonstrates its usage with a Config struct. ```go package main import ( "fmt" "github.com/Jagerente/gocfg" "os" ) // PrefixedEnvProvider adds a prefix to all environment variable lookups type PrefixedEnvProvider struct { prefix string } func NewPrefixedEnvProvider(prefix string) *PrefixedEnvProvider { return &PrefixedEnvProvider{prefix: prefix} } func (p *PrefixedEnvProvider) Get(key string) string { return os.Getenv(p.prefix + key) } type Config struct { DatabaseHost string `env:"DB_HOST" default:"localhost"` DatabasePort uint16 `env:"DB_PORT" default:"5432"` } func main() { // Environment variables are prefixed with MYAPP_ os.Setenv("MYAPP_DB_HOST", "db.production.local") os.Setenv("MYAPP_DB_PORT", "5433") prefixedProvider := NewPrefixedEnvProvider("MYAPP_") cfg := gocfg.NewDefault().AddValueProviders(prefixedProvider) config := new(Config) if err := cfg.Unmarshal(config); err != nil { panic(err) } fmt.Printf("Database: %s:%d\n", config.DatabaseHost, config.DatabasePort) // Output: Database: db.production.local:5433 } ``` -------------------------------- ### GenerateDocumentation - Auto-Generate .env Template Files in Go Source: https://context7.com/jagerente/gocfg/llms.txt The GenerateDocumentation method in GoCfg automatically creates documentation files, such as `.env.dist` templates, from configuration structs. These templates include descriptions, default values, and examples extracted from struct tags, aiding in setting up new environments. It requires a struct pointer and a documentation generator implementation. ```go package main import ( "fmt" "github.com/Jagerente/gocfg" "github.com/Jagerente/gocfg/pkg/docgens" os ) type DatabaseConfig struct { Host string `env:"DB_HOST" default:"localhost" example:"db.production.com" description:"Database server hostname"` Port uint16 `env:"DB_PORT" default:"5432" example:"5432"` User string `env:"DB_USER" example:"app_user" description:"Database username"` Password string `env:"DB_PASSWORD" example:"secret" description:"Database password (use secrets manager in production)"` } type CacheConfig struct { Enabled bool `env:"CACHE_ENABLED" default:"true" example:"false"` TTL string `env:"CACHE_TTL" default:"5m" example:"10m" description:"Cache time-to-live duration"` } type Config struct { DatabaseConfig `title:"Database Configuration"` CacheConfig `title:"Cache Configuration"` AppName string `env:"APP_NAME" default:"myapp" example:"production-api"` Debug bool `env:"DEBUG,omitempty" default:"false" description:"Enable debug mode (disable in production)"` } func main() { config := new(Config) file, err := os.Create(".env.dist") if err != nil { panic(fmt.Errorf("error creating file: %w", err)) } defer file.Close() docGenerator := docgens.NewEnvDocGenerator(file) cfgManager := gocfg.NewDefault() if err := cfgManager.GenerateDocumentation(config, docGenerator); err != nil { panic(err) } fmt.Println("Generated .env.dist template file") // Output file contents: // # Auto-generated config // // ############################# // # Database Configuration // ############################# // // # Description: // # Database server hostname // # // # Default: `localhost` // DB_HOST=db.production.com // ... } ``` -------------------------------- ### Go Struct Tag Reference for GoCfg Source: https://context7.com/jagerente/gocfg/llms.txt GoCfg utilizes struct tags to define how configuration fields are processed during unmarshaling and documentation generation. Key tags include `env` for environment variable names, `default` for fallback values, `omitempty` to allow missing values, `example` for documentation examples, `description` for explanatory text, and `title` for section headers in nested structures. ```go package main import ( "github.com/Jagerente/gocfg" time ) type Config struct { // env: Specifies the environment variable name ServerPort uint16 `env:"SERVER_PORT"` // default: Value used when environment variable is empty LogLevel string `env:"LOG_LEVEL" default:"info"` // omitempty: Allow empty values (no error if missing and no default) OptionalKey string `env:"OPTIONAL_KEY,omitempty"` // example: Example value for documentation generation APIKey string `env:"API_KEY" example:"sk-live-xxxx"` // description: Description text for documentation Timeout time.Duration `env:"TIMEOUT" default:"30s" description:"Request timeout duration"` // title: Section title for nested struct documentation Database DatabaseSettings `title:"Database Settings"` } type DatabaseSettings struct { Host string `env:"DB_HOST" default:"localhost"` Port uint16 `env:"DB_PORT" default:"5432"` } func main() { cfg := gocfg.NewDefault() config := new(Config) if err := cfg.Unmarshal(config); err != nil { panic(err) } } ``` -------------------------------- ### Change Struct Tag Name with UseCustomKeyTag in Go Source: https://context7.com/jagerente/gocfg/llms.txt Demonstrates how to use the `UseCustomKeyTag` method to specify a different struct tag name for configuration keys, instead of the default `env`. This is useful for compatibility with other libraries like `mapstructure`. The example uses `mapstructure` as the custom tag. ```go package main import ( "fmt" "github.com/Jagerente/gocfg" "os" ) type Config struct { ServerHost string `mapstructure:"SERVER_HOST" default:"0.0.0.0"` ServerPort uint16 `mapstructure:"SERVER_PORT" default:"8080"` APIKey string `mapstructure:"API_KEY"` } func main() { os.Setenv("API_KEY", "sk-live-abc123") cfg := gocfg.NewDefault().UseCustomKeyTag("mapstructure") config := new(Config) if err := cfg.Unmarshal(config); err != nil { panic(err) } fmt.Printf("Server: %s:%d\n", config.ServerHost, config.ServerPort) // Output: Server: 0.0.0.0:8080 } ``` -------------------------------- ### Load Configuration from .env Files with GoCfg Source: https://github.com/jagerente/gocfg/blob/main/README.md Demonstrates how to load configuration settings from .env files using the gocfg library. It shows how to use default '.env' files, specify custom file paths, and load from multiple .env files. This approach is useful for managing environment-specific configurations. ```go package main import ( "github.com/Jagerente/gocfg" "github.com/Jagerente/gocfg/pkg/parsers" "github.com/Jagerente/gocfg/pkg/values" ) type AppConfig struct { BoolField bool `env:"BOOL_FIELD"` StringField string `env:"STRING_FIELD"` IntField int `env:"INT_FIELD"` } func main() { // With default '.env' file dotEnvProvider, _ := values.NewDotEnvProvider() // With custom env file path dotEnvProvider, _ = values.NewDotEnvProvider("local.env") // With multiple env files dotEnvProvider, _ = values.NewDotEnvProvider("local.env", "dev.env") cfg := gocfg.NewDefault(). AddValueProviders(dotEnvProvider) // Equals to cfg = gocfg.NewEmpty(). UseDefaults(). AddParserProviders(parsers.NewDefaultParserProvider()). AddValueProviders( values.NewEnvProvider(), dotEnvProvider, ) appConfig := new(AppConfig) if err := cfg.Unmarshal(appConfig); err != nil { panic(err) } } ``` -------------------------------- ### Load Configuration from .env Files with GoCfg Source: https://context7.com/jagerente/gocfg/llms.txt Explains how to use the `DotEnvProvider` to load configuration settings from `.env` files. It supports loading from a default `.env` file, a specific path, or multiple files with priority ordering, where earlier files override later ones. ```go package main import ( "fmt" "github.com/Jagerente/gocfg" "github.com/Jagerente/gocfg/pkg/values" ) type Config struct { APIKey string `env:"API_KEY"` DatabaseURL string `env:"DATABASE_URL"` Debug bool `env:"DEBUG" default:"false"` } func main() { // Load from default '.env' file dotEnvProvider, err := values.NewDotEnvProvider() if err != nil { // Handle missing .env gracefully fmt.Println("No .env file found, using environment variables only") } // Load from custom path dotEnvProvider, err = values.NewDotEnvProvider("config/local.env") // Load from multiple files (first file has priority) dotEnvProvider, err = values.NewDotEnvProvider( "config/local.env", // Highest priority "config/default.env", // Fallback values ) if err != nil { panic(err) } cfg := gocfg.NewDefault().AddValueProviders(dotEnvProvider) config := new(Config) if err := cfg.Unmarshal(config); err != nil { panic(err) } fmt.Printf("API Key loaded: %s...\n", config.APIKey[:8]) } ``` -------------------------------- ### Read Environment Variables with EnvProvider in Go Source: https://context7.com/jagerente/gocfg/llms.txt Demonstrates how to use EnvProvider to read configuration values directly from system environment variables. It shows setting environment variables and unmarshalling them into a Go struct. Dependencies include the gocfg library and the standard os package. ```go package main import ( "fmt" "github.com/Jagerente/gocfg" "github.com/Jagerente/gocfg/pkg/parsers" "github.com/Jagerente/gocfg/pkg/values" "os" ) type Config struct { AppName string `env:"APP_NAME" default:"myapp"` Port uint16 `env:"PORT" default:"3000"` } func main() { os.Setenv("APP_NAME", "production-api") os.Setenv("PORT", "8080") envProvider := values.NewEnvProvider() cfg := gocfg.NewEmpty(). UseDefaults(). AddParserProviders(parsers.NewDefaultParserProvider()). AddValueProviders(envProvider) config := new(Config) if err := cfg.Unmarshal(config); err != nil { panic(err) } fmt.Printf("App: %s on port %d\n", config.AppName, config.Port) // Output: App: production-api on port 8080 } ``` -------------------------------- ### Basic GoCfg Usage for Configuration Unmarshaling Source: https://github.com/jagerente/gocfg/blob/main/README.md This Go code demonstrates the basic usage of the GoCfg package to unmarshal configuration into an AppConfig struct. It initializes a configuration object, sets up default providers, and then unmarshals the configuration. Errors during unmarshaling are handled by panicking. ```go package main import ( "github.com/Jagerente/gocfg" "github.com/Jagerente/gocfg/pkg/parsers" "github.com/Jagerente/gocfg/pkg/values" "time" ) type LoggerConfig struct { LogLevel string `env:"LOG_LEVEL" default:"debug"` } type RedisConfig struct { RedisHost string `env:"REDIS_HOST" default:"localhost"` RedisPort uint16 `env:"REDIS_PORT" default:"6379"` RedisUser string `env:"REDIS_USER,omitempty"` RedisPassword string `env:"REDIS_PASS"` RedisDatabase string `env:"REDIS_DATABASE"` } type AppConfig struct { // Supported Tags: // - env: Specifies the environment variable name. // - default: Specifies the default value for the field. // - example: Specifies an example value for documentation generation. // - omitempty: Allows empty fields. // If both the parsed value and the default value are empty, // the field will be set to the zero value for its type in Go. // - description: Describes the field for documentation generation. // - title: Specifies the title for nested struct documentation. LogLevel LoggerConfig RedisConfig RedisConfig BoolField bool `env:"BOOL_FIELD"` StringField string `env:"STRING_FIELD"` IntField int `env:"INT_FIELD"` Int8Field int8 `env:"INT8_FIELD"` Int16Field int16 `env:"INT16_FIELD"` Int32Field int32 `env:"INT32_FIELD"` Int64Field int64 `env:"INT64_FIELD"` UintField uint `env:"UINT_FIELD"` Uint8Field uint8 `env:"UINT8_FIELD"` Uint16Field uint16 `env:"UINT16_FIELD"` Uint32Field uint32 `env:"UINT32_FIELD"` Uint64Field uint64 `env:"UINT64_FIELD"` Float32Field float32 `env:"FLOAT32_FIELD"` Float64Field float64 `env:"FLOAT64_FIELD"` TimeDurationField time.Duration `env:"TIME_DURATION_FIELD"` ByteSliceField []byte `env:"BYTE_SLICE_FIELD"` StringSliceField []string `env:"STRING_SLICE_FIELD" default:"string1,string2,string3"` IntSliceField []int `env:"INT_SLICE_FIELD" default:"3,2,1,0,-1,-2,-3"` EmptyField string `env:"EMPTY_FIELD,omitempty"` WithDefaultField string `env:"WITH_DEFAULT_FIELD" default:"ave"` } func main() { cfg := gocfg.NewDefault() // Equals to cfg = gocfg.NewEmpty(). UseDefaults(). AddParserProviders(parsers.NewDefaultParserProvider()). AddValueProviders(values.NewEnvProvider()) appConfig := new(AppConfig) if err := cfg.Unmarshal(appConfig); err != nil { panic(err) } } ``` -------------------------------- ### Define Configuration Structure with Gocfg Tags (Go) Source: https://github.com/jagerente/gocfg/blob/main/README.md This Go code defines a configuration structure for an application, utilizing gocfg tags to map environment variables, set default values, and provide descriptions. It includes nested structures for different configuration modules like Logger, Router, Redis, Memcache, and Cassandra. The `New` function initializes gocfg, adds an optional DotEnvProvider, and unmarshals the configuration. ```Go package config import ( "github.com/Jagerente/gocfg" "github.com/Jagerente/gocfg/pkg/values" "time" cache_factory "your_cool_app/internal/router/cache" ) type LoggerConfig struct { LogLevel int `env:"LOG_LEVEL" default:"6" example:"4" description:"https://pkg.go.dev/github.com/sirupsen/logrus@v1.9.3#Level"` ReportCaller bool `env:"REPORT_CALLER" default:"true" example:"false"` LogFormatter int `env:"LOG_FORMATTER" default:"0" example:"1"` } type CassandraConfig struct { CassandraHosts string `env:"CASSANDRA_HOSTS" default:"127.0.0.1" example:"cassandra.example.com"` CassandraKeyspace string `env:"CASSANDRA_KEYSPACE" default:"user_data_service" example:"production_keyspace"` } type RouterConfig struct { ServerPort uint16 `env:"SERVER_PORT" default:"8080" example:"3000"` Debug bool `env:"ROUTER_DEBUG" default:"true" example:"false"` CacheAdapter string `env:"CACHE_ADAPTER,omitempty" example:"redis" description:"Leave blank to not use.\nPossible values:\n- redis\n- memcache"` CacheAdapterTTL time.Duration `env:"CACHE_ADAPTER_TTL,omitempty" default:"1m" example:"5m"` CacheAdapterNoCacheParam string `env:"CACHE_ADAPTER_NOCACHE_PARAM,omitempty" default:"no-cache" example:"skip-cache"` } type RedisCacheAdapterConfig struct { RedisAddr string `env:"CACHE_ADAPTER_REDIS_ADDR,omitempty" default:":6379"` RedisDB int `env:"CACHE_ADAPTER_REDIS_DB,omitempty" default:"0"` RedisUsername string `env:"CACHE_ADAPTER_REDIS_USERNAME,omitempty"` RedisPassword string `env:"CACHE_ADAPTER_REDIS_PASSWORD,omitempty"` } type MemcacheCacheAdapterConfig struct { Capacity int `env:"CACHE_ADAPTER_MEMCACHE_CAPACITY,omitempty" default:"10000000"` CachingAlgorithm cache_factory.Algorithm `env:"CACHE_ADAPTER_MEMCACHE_CACHING_ALGORITHM,omitempty" default:"LRU"` } type Config struct { LoggerConfig `title:"Logger configuration"` RouterConfig `title:"Router configuration"` RedisCacheAdapterConfig `title:"Redis Cache Adapter configuration"` MemcacheCacheAdapterConfig `title:"Memcache Cache Adapter configuration"` CassandraConfig `title:"Cassandra configuration"` } func New() (*Config, error) { var cfg = new(Config) cfgManager := gocfg.NewDefault() if dotEnvProvider, err := values.NewDotEnvProvider(); err == nil { cfgManager = cfgManager.AddValueProviders(dotEnvProvider) } if err := cfgManager.Unmarshal(cfg); err != nil { return nil, err } return cfg, nil } ``` -------------------------------- ### Implement Custom Parser Provider for GoCfg Source: https://github.com/jagerente/gocfg/blob/main/README.md Shows how to create and register a custom parser provider with GoCfg. This is useful for handling custom data types, such as `time.Duration`, by defining how string values should be parsed into these types. ```go package main import ( "github.com/Jagerente/gocfg" "reflect" "time" ) type CustomParserProvider struct { } func NewCustomParserProvider() *CustomParserProvider { return &CustomParserProvider{} } func (p *CustomParserProvider) Get(field reflect.Value) (func(v string) (any, error), bool) { switch field.Type() { case reflect.TypeOf(time.Duration(83)): return func(v string) (any, error) { return time.ParseDuration(v) }, true default: return nil, false } } type AppConfig struct { BoolField bool `env:"BOOL_FIELD"` StringField string `env:"STRING_FIELD"` IntField int `env:"INT_FIELD"` } func main() { customParserProvider := NewCustomParserProvider() cfg := gocfg.NewDefault(). AddParserProviders(customParserProvider) appConfig := new(AppConfig) if err := cfg.Unmarshal(appConfig); err != nil { panic(err) } } ``` -------------------------------- ### Initialize and Unmarshal Configuration with GoCfg Source: https://context7.com/jagerente/gocfg/llms.txt Demonstrates initializing the GoCfg `ConfigManager` using default settings or a custom build. It then unmarshals configuration values from environment variables and default tags into a Go struct. This is the primary method for loading application settings. ```go package main import ( "fmt" "github.com/Jagerente/gocfg" "github.com/Jagerente/gocfg/pkg/parsers" "github.com/Jagerente/gocfg/pkg/values" "time" ) type AppConfig struct { ServerPort uint16 `env:"SERVER_PORT" default:"8080"` DatabaseURL string `env:"DATABASE_URL"` Debug bool `env:"DEBUG" default:"false"` Timeout time.Duration `env:"TIMEOUT" default:"30s"` AllowedHosts []string `env:"ALLOWED_HOSTS" default:"localhost,127.0.0.1"` MaxRetries int `env:"MAX_RETRIES,omitempty"` } func main() { // Create with defaults: env vars + default values + standard parsers cfg := gocfg.NewDefault() // Or build manually for more control cfg = gocfg.NewEmpty(). UseDefaults(). AddParserProviders(parsers.NewDefaultParserProvider()). AddValueProviders(values.NewEnvProvider()) appConfig := new(AppConfig) if err := cfg.Unmarshal(appConfig); err != nil { panic(fmt.Errorf("failed to load config: %w", err)) } fmt.Printf("Server running on port %d\n", appConfig.ServerPort) // Output: Server running on port 8080 } ``` -------------------------------- ### Use Custom Key Tag for Configuration Fields with GoCfg Source: https://github.com/jagerente/gocfg/blob/main/README.md Illustrates how to specify a custom tag for configuration fields instead of the default 'env'. This allows flexibility in how configuration keys are mapped to struct fields, using libraries like 'mapstructure'. ```go package main import ( "github.com/Jagerente/gocfg" ) type AppConfig struct { BoolField bool `mapstructure:"BOOL_FIELD"` StringField string `mapstructure:"STRING_FIELD"` IntField int `mapstructure:"INT_FIELD"` } func main() { cfg := gocfg.NewDefault(). UseCustomKeyTag("mapstructure") appConfig := new(AppConfig) if err := cfg.Unmarshal(appConfig); err != nil { panic(err) } } ``` -------------------------------- ### Add Custom Parser for URL Type with ParserProvider in Go Source: https://context7.com/jagerente/gocfg/llms.txt Illustrates how to implement a custom ParserProvider to support parsing of custom types, such as `*url.URL`. The URLParserProvider checks the field type and provides a parsing function using `url.Parse`. This extends gocfg's ability to handle non-primitive types. ```go package main import ( "fmt" "github.com/Jagerente/gocfg" "net/url" "os" "reflect" ) // URLParserProvider adds support for parsing *url.URL types type URLParserProvider struct{} func NewURLParserProvider() *URLParserProvider { return &URLParserProvider{} } func (p *URLParserProvider) Get(field reflect.Value) (func(v string) (interface{}, error), bool) { if field.Type() == reflect.TypeOf(&url.URL{}) { return func(v string) (interface{}, error) { return url.Parse(v) }, true } return nil, false } type Config struct { APIEndpoint *url.URL `env:"API_ENDPOINT"` WebhookURL *url.URL `env:"WEBHOOK_URL,omitempty"` } func main() { os.Setenv("API_ENDPOINT", "https://api.example.com/v1") urlParser := NewURLParserProvider() cfg := gocfg.NewDefault().AddParserProviders(urlParser) config := new(Config) if err := cfg.Unmarshal(config); err != nil { panic(err) } fmt.Printf("API Host: %s, Path: %s\n", config.APIEndpoint.Host, config.APIEndpoint.Path) // Output: API Host: api.example.com, Path: /v1 } ``` -------------------------------- ### Unmarshal Nested Configuration Structs with GoCfg Source: https://context7.com/jagerente/gocfg/llms.txt Illustrates how the `Unmarshal` method handles nested configuration structs. It parses values from environment variables and struct tags, supporting default values and optional fields (`omitempty`). This allows for organizing complex configurations into logical groups. ```go package main import ( "fmt" "github.com/Jagerente/gocfg" "os" "time" ) type DatabaseConfig struct { Host string `env:"DB_HOST" default:"localhost"` Port uint16 `env:"DB_PORT" default:"5432"` User string `env:"DB_USER"` Password string `env:"DB_PASSWORD"` Database string `env:"DB_NAME" default:"app"` } type CacheConfig struct { RedisAddr string `env:"REDIS_ADDR" default:"localhost:6379"` TTL time.Duration `env:"CACHE_TTL" default:"5m"` } type Config struct { Database DatabaseConfig Cache CacheConfig LogLevel string `env:"LOG_LEVEL" default:"info"` Environment string `env:"ENV,omitempty"` } func main() { // Set environment variables os.Setenv("DB_USER", "admin") os.Setenv("DB_PASSWORD", "secret123") os.Setenv("LOG_LEVEL", "debug") cfg := gocfg.NewDefault() config := new(Config) if err := cfg.Unmarshal(config); err != nil { panic(err) } fmt.Printf("Database: %s@%s:%d/%s\n", config.Database.User, config.Database.Host, config.Database.Port, config.Database.Database) fmt.Printf("Cache TTL: %v\n", config.Cache.TTL) fmt.Printf("Log Level: %s\n", config.LogLevel) // Output: // Database: admin@localhost:5432/app // Cache TTL: 5m0s // Log Level: debug } ``` -------------------------------- ### ForceDefaults - Override Values with Defaults in Go Source: https://context7.com/jagerente/gocfg/llms.txt The ForceDefaults method in GoCfg allows overriding all value providers and using only the default values specified in struct tags. This is particularly useful for testing scenarios or resetting configurations to a known state. It takes a struct pointer as input and returns an error if unmarshaling fails. ```go package main import ( "fmt" "github.com/Jagerente/gocfg" "os" ) type Config struct { Environment string `env:"ENV" default:"development"` LogLevel string `env:"LOG_LEVEL" default:"debug"` MaxWorkers int `env:"MAX_WORKERS" default:"4"` } func main() { // These will be ignored when ForceDefaults is used os.Setenv("ENV", "production") os.Setenv("LOG_LEVEL", "error") os.Setenv("MAX_WORKERS", "16") cfg := gocfg.NewDefault().ForceDefaults() config := new(Config) if err := cfg.Unmarshal(config); err != nil { panic(err) } fmt.Printf("Env: %s, LogLevel: %s, Workers: %d\n", config.Environment, config.LogLevel, config.MaxWorkers) // Output: Env: development, LogLevel: debug, Workers: 4 } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.