// Package config loads platform configuration from the environment. // // The Env* helpers all follow the same contract: an unset (or empty) variable // returns def silently; a variable that is set but unparseable — or rejected by // the optional valid predicate — logs once and falls back to def. This keeps the // "parse env, validate, log, default" boilerplate out of every cmd/* main. package config import ( "log" "os" "strconv" "time" ) // EnvString returns the value of key, or def when unset/empty. func EnvString(key, def string) string { if v, ok := os.LookupEnv(key); ok && v != "" { return v } return def } // EnvInt parses key as an int, validating with valid (nil = accept any). func EnvInt(key string, def int, valid func(int) bool) int { v, ok := os.LookupEnv(key) if !ok || v == "" { return def } n, err := strconv.Atoi(v) if err != nil || (valid != nil && !valid(n)) { log.Printf("invalid %s %q, using %d", key, v, def) return def } return n } // EnvFloat64 parses key as a float64, validating with valid (nil = accept any). func EnvFloat64(key string, def float64, valid func(float64) bool) float64 { v, ok := os.LookupEnv(key) if !ok || v == "" { return def } f, err := strconv.ParseFloat(v, 64) if err != nil || (valid != nil && !valid(f)) { log.Printf("invalid %s %q, using %g", key, v, def) return def } return f } // EnvFloat32 parses key as a float32, validating with valid (nil = accept any). func EnvFloat32(key string, def float32, valid func(float32) bool) float32 { v, ok := os.LookupEnv(key) if !ok || v == "" { return def } f, err := strconv.ParseFloat(v, 32) if err != nil || (valid != nil && !valid(float32(f))) { log.Printf("invalid %s %q, using %g", key, v, def) return def } return float32(f) } // EnvBool parses key as a boolean ("1", "true", "yes", "on" / "0", "false", // ...), accepting the same literals strconv.ParseBool accepts. func EnvBool(key string, def bool) bool { v, ok := os.LookupEnv(key) if !ok || v == "" { return def } b, err := strconv.ParseBool(v) if err != nil { log.Printf("invalid %s %q, using %t", key, v, def) return def } return b } // EnvDuration parses key as a time.Duration (e.g. "2m", "30s"). func EnvDuration(key string, def time.Duration) time.Duration { v, ok := os.LookupEnv(key) if !ok || v == "" { return def } d, err := time.ParseDuration(v) if err != nil || d <= 0 { log.Printf("invalid %s %q, using %s", key, v, def) return def } return d }