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) 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 }