feat: show environment variables where from values are taken and better usage information.

This commit is contained in:
Andrey Parhomenko 2024-07-21 02:18:38 +05:00
parent bf3699257d
commit b5baabf74f
3 changed files with 63 additions and 10 deletions

View file

@ -59,10 +59,8 @@ var (
),
).Desc(
"the testing program to show how to use the lib",
).Ldesc(
"this is the long description where you " +
"can put anything you want about the program",
)
).Ldesc(`This is the long description where you
can put anything you want about the program.`)
)
func main() {

View file

@ -15,6 +15,7 @@ type Flags struct {
tool *Tool
args []string
parsedArgs []string
envNameMap map[string] []string
envMap map[string]string
}
@ -34,6 +35,7 @@ func (flags *Flags) setEnv(
name string,
env []string,
) bool {
flags.envNameMap[name] = env
for _, k := range env {
value, has := os.LookupEnv(k)
if !has {
@ -47,6 +49,8 @@ func (flags *Flags) setEnv(
return false
}
// Set new string variable
// to parse.
func (flags *Flags) StringVar(
p *string,
name string,
@ -58,6 +62,7 @@ func (flags *Flags) StringVar(
flags.setEnv(name, env)
}
// Set new int variable to parse.
func (flags *Flags) IntVar(
p *int,
name string,
@ -69,6 +74,7 @@ func (flags *Flags) IntVar(
flags.setEnv(name, env)
}
// Set new int64 variable to parse.
func (flags *Flags) Int64Var(
p *int64,
name string,
@ -80,6 +86,7 @@ func (flags *Flags) Int64Var(
flags.setEnv(name, env)
}
// Set new bool variable to parse.
func (flags *Flags) BoolVar(
p *bool,
name string,
@ -91,6 +98,7 @@ func (flags *Flags) BoolVar(
flags.setEnv(name, env)
}
// Set new float64 variable to parse.
func (flags *Flags) Float64Var(
p *float64,
name string,
@ -102,6 +110,7 @@ func (flags *Flags) Float64Var(
flags.setEnv(name, env)
}
// Set new duration variable to parse.
func (flags *Flags) DurationVar(
p *time.Duration,
name string,
@ -126,14 +135,18 @@ func (flags *Flags) Parse() []string {
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
}

View file

@ -2,6 +2,7 @@ package mtool
import (
"text/tabwriter"
"strings"
"flag"
"sort"
"fmt"
@ -118,14 +119,28 @@ func (t *Tool) Run(args []string) {
flags := &Flags{
FlagSet : flagSet,
envMap: make(map[string]string),
envNameMap: make(map[string] []string),
}
out := flags.Output()
flags.Usage = func() {
n := 0
nflags := 0
flags.VisitAll(func(f *flag.Flag){
n++
nflags++
varNames, ok := flags.envNameMap[f.Name]
if !ok || len(varNames) == 0 {
return
}
f.Usage += " ("
for i, name := range varNames {
f.Usage += "$"+name
if i < len(varNames) - 1 {
f.Usage += ", "
}
}
f.Usage += ")"
})
hasOptions := n != 0
hasOptions := nflags != 0
// Name
if usageTool.desc != "" {
@ -162,6 +177,7 @@ func (t *Tool) Run(args []string) {
// Options
if hasOptions {
fmt.Fprintln(out, "\nOptions:")
fmt.Fprintln(out, " --\n option terminator")
flags.PrintDefaults()
}
@ -178,7 +194,18 @@ func (t *Tool) Run(args []string) {
// Print available sub commands if
// got no arguments.
if len(args) == 0 {
if len(args) == 0 || func() bool {
toolName := args[0]
_, ok := t.subs[toolName]
if ok {
return false
}
if toolName != "" && toolName[0]=='-' {
return true
}
return false
}() {
if t.desc != "" {
fmt.Fprintf(
@ -191,7 +218,11 @@ func (t *Tool) Run(args []string) {
" %s <command>\n", t.FullName())
if t.ldesc != "" {
fmt.Fprintf(out, "\nDescription:\n %s\n", t.ldesc)
fmt.Fprintf(
out,
"\nDescription:\n %s\n",
t.GetLongFormattedDesc(),
)
}
if len(t.subs) > 0 {
@ -205,7 +236,13 @@ func (t *Tool) Run(args []string) {
args = args[1:]
if _, ok := t.subs[toolName] ; !ok {
fmt.Printf("%s: No such util %q'\n", t.ProgName(), toolName)
fmt.Fprintf(
out,
"%s: No such util %q'\n" +
"use ' %s ' to see available commands\n",
t.FullName(), toolName,
t.FullName(),
)
os.Exit(1)
}
@ -213,3 +250,8 @@ func (t *Tool) Run(args []string) {
usageTool = sub
sub.Run(args)
}
func (t *Tool) GetLongFormattedDesc() string {
return strings.ReplaceAll(t.ldesc, "\n", "\n ")
}