// Package envflag is an extremely small bit of code to make configuration // via environment variables a little bit less of a hassle when using // the flag package in the standard library. // // Example: // // package main // // import ( // "flag" // "fmt" // "os" // // "riedstra.dev/go/envflag" // ) // // func main() { // fl := flag.NewFlagSet("envflag", flag.ExitOnError) // // var aFlag string = "some default" // fmt.Println("aFlag:", aFlag) // // envflag.String(fl, &aFlag, "a", "FLAG_A", "Set's the value of -a") // // // By default, command line flags override environment vars. // fl.Parse(os.Args[1:]) // // fmt.Println("aFlag:", aFlag) // } // // Known caveat, variables set in the environment will override what the flag // package sees as the "default" value. package envflag import ( "flag" "fmt" "os" "strconv" ) // String is a convent way to set value from environment variable, // and allow override when a command line flag is set. It's assumed `p` is // not nil. func String(fl *flag.FlagSet, p *string, name, envvar, usage string) { if v := os.Getenv(envvar); v != "" { *p = v } fl.StringVar(p, name, *p, fmt.Sprintf("%s (Environ: '%s')", usage, envvar)) } // Bool is a convent way to set value from environment variable, // and allow override when a command line flag is set. It's assumed `p` is // not nil. func Bool(fl *flag.FlagSet, p *bool, name, envvar, usage string) error { if v := os.Getenv(envvar); v != "" { res, err := strconv.ParseBool(v) if err != nil { return fmt.Errorf("Bool: cannot parse '%s=%s', %w", envvar, v, err) } *p = res } fl.BoolVar(p, name, *p, fmt.Sprintf("%s (Environ: '%s')", usage, envvar)) return nil } // Int is a convent way to set value from environment variable, // and allow override when a command line flag is set. It's assumed `p` is // not nil. func Int(fl *flag.FlagSet, p *int, name, envvar, usage string) error { if v := os.Getenv(envvar); v != "" { res, err := strconv.ParseInt(v, 10, 32) if err != nil { return fmt.Errorf("Int: cannot parse '%s=%s', %w", envvar, v, err) } *p = int(res) } fl.IntVar(p, name, *p, fmt.Sprintf("%s (Environ: '%s')", usage, envvar)) return nil }