cli/mtool/main.go

156 lines
2.6 KiB
Go

package mtool
// The package implements fast way
// to make multitool CLI applications.
import (
"flag"
"os"
"time"
)
type Flags struct {
*flag.FlagSet
tool *Tool
args []string
parsedArgs []string
customArgs []any
envNameMap map[string][]string
envMap map[string]string
}
type ToolMap map[string]*Tool
func (flags *Flags) CustomArgs() []any {
return flags.customArgs
}
func (flags *Flags) wasPassed(name string) bool {
found := false
flags.Visit(func(f *flag.Flag) {
if f.Name == name {
found = true
}
})
return found
}
func (flags *Flags) setEnv(
name string,
env []string,
) bool {
flags.envNameMap[name] = env
for _, k := range env {
value, has := os.LookupEnv(k)
if !has {
continue
}
flags.envMap[name] = value
return true
}
return false
}
// Set new string variable
// to parse.
func (flags *Flags) StringVar(
p *string,
name string,
value string,
usage string,
env ...string,
) {
flags.FlagSet.StringVar(p, name, value, usage)
flags.setEnv(name, env)
}
// Set new int variable to parse.
func (flags *Flags) IntVar(
p *int,
name string,
value int,
usage string,
env ...string,
) {
flags.FlagSet.IntVar(p, name, value, usage)
flags.setEnv(name, env)
}
// Set new int64 variable to parse.
func (flags *Flags) Int64Var(
p *int64,
name string,
value int64,
usage string,
env ...string,
) {
flags.FlagSet.Int64Var(p, name, value, usage)
flags.setEnv(name, env)
}
// Set new bool variable to parse.
func (flags *Flags) BoolVar(
p *bool,
name string,
value bool,
usage string,
env ...string,
) {
flags.FlagSet.BoolVar(p, name, value, usage)
flags.setEnv(name, env)
}
// Set new float64 variable to parse.
func (flags *Flags) Float64Var(
p *float64,
name string,
value float64,
usage string,
env ...string,
) {
flags.FlagSet.Float64Var(p, name, value, usage)
flags.setEnv(name, env)
}
// Set new duration variable to parse.
func (flags *Flags) DurationVar(
p *time.Duration,
name string,
value time.Duration,
usage string,
env ...string,
) {
flags.FlagSet.DurationVar(p, name, value, usage)
flags.setEnv(name, env)
}
func (flags *Flags) Parse() []string {
flags.FlagSet.Parse(flags.args)
for name, v := range flags.envMap {
if !flags.wasPassed(name) {
flags.FlagSet.Set(name, v)
}
}
flags.parsedArgs = flags.FlagSet.Args()
return flags.parsedArgs
}
// Get all the arguments, including the
// parsed ones.
func (flags *Flags) AllArgs() []string {
return flags.args
}
// Get all the arguments going after options.
func (flags *Flags) Args() []string {
return flags.parsedArgs
}
// Get the tool currently called.
func (flags *Flags) Tool() *Tool {
return flags.tool
}