d2/lib/xmain/opts.go

128 lines
2.7 KiB
Go
Raw Normal View History

2022-11-15 00:35:22 +00:00
package xmain
import (
"fmt"
"io"
"strconv"
"strings"
"github.com/spf13/pflag"
"oss.terrastruct.com/cmdlog"
"oss.terrastruct.com/xos"
)
type Opts struct {
args []string
flags *pflag.FlagSet
env *xos.Env
log *cmdlog.Logger
registeredEnvs []string
}
2022-11-17 00:42:39 +00:00
func NewOpts(env *xos.Env, log *cmdlog.Logger, args []string) *Opts {
2022-11-15 00:35:22 +00:00
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
flags.SortFlags = false
flags.Usage = func() {}
flags.SetOutput(io.Discard)
return &Opts{
args: args,
flags: flags,
env: env,
log: log,
}
}
func (o *Opts) Help() string {
b := &strings.Builder{}
o.flags.SetOutput(b)
o.flags.PrintDefaults()
if len(o.registeredEnvs) > 0 {
b.WriteString("\nYou may persistently set the following as environment variables (flags take precedent):\n")
for i, e := range o.registeredEnvs {
s := fmt.Sprintf("- $%s", e)
if i != len(o.registeredEnvs)-1 {
s += "\n"
}
b.WriteString(s)
}
}
return b.String()
}
2022-11-17 00:42:39 +00:00
func (o *Opts) Int64(envKey, flag, shortFlag string, defaultVal int64, usage string) (*int64, error) {
2022-11-15 00:35:22 +00:00
if envKey != "" {
if o.env.Getenv(envKey) != "" {
envVal, err := strconv.ParseInt(o.env.Getenv(envKey), 10, 64)
if err != nil {
2022-11-17 00:42:39 +00:00
return nil, fmt.Errorf(`invalid environment variable %s. Expected int64. Found "%v".`, envKey, envVal)
2022-11-15 00:35:22 +00:00
}
2022-11-17 00:42:39 +00:00
defaultVal = envVal
2022-11-15 00:35:22 +00:00
}
o.registeredEnvs = append(o.registeredEnvs, envKey)
}
2022-11-17 00:42:39 +00:00
return o.flags.Int64P(flag, shortFlag, defaultVal, usage), nil
2022-11-15 00:35:22 +00:00
}
func (o *Opts) String(envKey, flag, shortFlag string, defaultVal, usage string) *string {
if envKey != "" {
if o.env.Getenv(envKey) != "" {
envVal := o.env.Getenv(envKey)
2022-11-17 00:42:39 +00:00
defaultVal = envVal
2022-11-15 00:35:22 +00:00
}
o.registeredEnvs = append(o.registeredEnvs, envKey)
}
return o.flags.StringP(flag, shortFlag, defaultVal, usage)
}
2022-11-17 00:42:39 +00:00
func (o *Opts) Bool(envKey, flag, shortFlag string, defaultVal bool, usage string) (*bool, error) {
2022-11-15 00:35:22 +00:00
if envKey != "" {
if o.env.Getenv(envKey) != "" {
envVal := o.env.Getenv(envKey)
if !boolyEnv(envVal) {
2022-11-17 00:42:39 +00:00
return nil, fmt.Errorf(`invalid environment variable %s. Expected bool. Found "%s".`, envKey, envVal)
}
if truthyEnv(envVal) {
defaultVal = true
} else {
defaultVal = false
2022-11-15 00:35:22 +00:00
}
}
o.registeredEnvs = append(o.registeredEnvs, envKey)
}
2022-11-17 00:42:39 +00:00
return o.flags.BoolP(flag, shortFlag, defaultVal, usage), nil
2022-11-15 00:35:22 +00:00
}
func boolyEnv(s string) bool {
return falseyEnv(s) || truthyEnv(s)
}
func falseyEnv(s string) bool {
2022-11-17 00:42:39 +00:00
return s == "0" || s == "false"
2022-11-15 00:35:22 +00:00
}
func truthyEnv(s string) bool {
2022-11-17 00:42:39 +00:00
return s == "1" || s == "true"
2022-11-15 00:35:22 +00:00
}
func (o *Opts) Parse() error {
2022-11-17 00:42:39 +00:00
return o.flags.Parse(o.args)
2022-11-15 00:35:22 +00:00
}
func (o *Opts) SetArgs(args []string) {
o.args = args
}
func (o *Opts) Args() []string {
return o.flags.Args()
}
func (o *Opts) Arg(i int) string {
return o.flags.Arg(i)
}