// Package envutil provides environment variable helpers with defaults. // // rdev uses os.Getenv() directly rather than Viper because: // - rdev always runs in Kubernetes with env vars injected via ConfigMaps/Secrets // - rdev has a credential store overlay (loadInfraConfig) that Viper can't model // - Adding Viper would add complexity without functional benefit for this use case // // Generated projects (skeleton templates) use Viper because: // - App services benefit from .env file loading during development // - Viper provides built-in duration parsing, type coercion, and defaults // - App config is simpler (no credential store overlay) // // This divergence is intentional. See: .claude/guides/services/templates.md package envutil import ( "os" "strconv" "strings" ) // GetEnv returns the environment variable value or the default. func GetEnv(key, defaultVal string) string { if v := os.Getenv(key); v != "" { return v } return defaultVal } // GetEnvInt returns the environment variable as an int or the default. func GetEnvInt(key string, defaultVal int) int { v := os.Getenv(key) if v == "" { return defaultVal } if i, err := strconv.Atoi(v); err == nil { return i } return defaultVal } // GetEnvBool returns the environment variable as a bool or the default. func GetEnvBool(key string, defaultVal bool) bool { v := os.Getenv(key) if v == "" { return defaultVal } v = strings.ToLower(v) return v == "true" || v == "1" || v == "yes" }