add environment variable-based configuration
this is a sample implementation of environment variable based configuration outlined in #1066
The code that does this has moved to internal/flags/flags.go. Perhaps something like this following generated code to use generics and simply calculate the envar name automatically: list-all -> TASK_LIST_ALL. Then it becomes pretty easy to operate as the envars are easy to "guess" from whatever the cli arguments are.
Anyway, the code:
``` func GetTaskEnv[T any](name string, defaultValue T) T { if name == "" { return defaultValue } envName := "TASK_" + strings.ToUpper(strings.ReplaceAll(name, "-", "_")) value, ok := os.LookupEnv(envName) if !ok { return defaultValue }switch v := any(defaultValue).(type) {
case bool:
boolVal, err := strconv.ParseBool(value)
if err != nil {
return defaultValue
}
return any(boolVal).(T)
case int:
intVal, err := strconv.Atoi(value)
if err != nil {
return defaultValue
}
return any(intVal).(T)
case string:
return any(value).(T)
default:
return defaultValue
}
}
func FlagVar[T any](p *T, name, short string, defaultValue T, usage string) { *p = GetTaskEnv(name, defaultValue)
switch v := any(defaultValue).(type) {
case bool:
pflag.CommandLine.BoolVarP((*bool)(any(p).(*bool)), name, short, *p, usage)
case int:
pflag.CommandLine.IntVarP((*int)(any(p).(*int)), name, short, *p, usage)
case string:
pflag.CommandLine.StringVarP((*string)(any(p).(*string)), name, short, *p, usage)
}
}
func main() { var ListAll bool FlagVar(&ListAll, "list-all", "a", false, "Lists tasks with or without a description") }
</details>
Hello! Thanks for your PR. I am closing it. See my comment here