feat: show environment variables where from values are taken and better usage information.
This commit is contained in:
parent
bf3699257d
commit
b5baabf74f
3 changed files with 63 additions and 10 deletions
|
@ -59,10 +59,8 @@ var (
|
||||||
),
|
),
|
||||||
).Desc(
|
).Desc(
|
||||||
"the testing program to show how to use the lib",
|
"the testing program to show how to use the lib",
|
||||||
).Ldesc(
|
).Ldesc(`This is the long description where you
|
||||||
"this is the long description where you " +
|
can put anything you want about the program.`)
|
||||||
"can put anything you want about the program",
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -15,6 +15,7 @@ type Flags struct {
|
||||||
tool *Tool
|
tool *Tool
|
||||||
args []string
|
args []string
|
||||||
parsedArgs []string
|
parsedArgs []string
|
||||||
|
envNameMap map[string] []string
|
||||||
envMap map[string]string
|
envMap map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@ func (flags *Flags) setEnv(
|
||||||
name string,
|
name string,
|
||||||
env []string,
|
env []string,
|
||||||
) bool {
|
) bool {
|
||||||
|
flags.envNameMap[name] = env
|
||||||
for _, k := range env {
|
for _, k := range env {
|
||||||
value, has := os.LookupEnv(k)
|
value, has := os.LookupEnv(k)
|
||||||
if !has {
|
if !has {
|
||||||
|
@ -47,6 +49,8 @@ func (flags *Flags) setEnv(
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set new string variable
|
||||||
|
// to parse.
|
||||||
func (flags *Flags) StringVar(
|
func (flags *Flags) StringVar(
|
||||||
p *string,
|
p *string,
|
||||||
name string,
|
name string,
|
||||||
|
@ -58,6 +62,7 @@ func (flags *Flags) StringVar(
|
||||||
flags.setEnv(name, env)
|
flags.setEnv(name, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set new int variable to parse.
|
||||||
func (flags *Flags) IntVar(
|
func (flags *Flags) IntVar(
|
||||||
p *int,
|
p *int,
|
||||||
name string,
|
name string,
|
||||||
|
@ -69,6 +74,7 @@ func (flags *Flags) IntVar(
|
||||||
flags.setEnv(name, env)
|
flags.setEnv(name, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set new int64 variable to parse.
|
||||||
func (flags *Flags) Int64Var(
|
func (flags *Flags) Int64Var(
|
||||||
p *int64,
|
p *int64,
|
||||||
name string,
|
name string,
|
||||||
|
@ -80,6 +86,7 @@ func (flags *Flags) Int64Var(
|
||||||
flags.setEnv(name, env)
|
flags.setEnv(name, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set new bool variable to parse.
|
||||||
func (flags *Flags) BoolVar(
|
func (flags *Flags) BoolVar(
|
||||||
p *bool,
|
p *bool,
|
||||||
name string,
|
name string,
|
||||||
|
@ -91,6 +98,7 @@ func (flags *Flags) BoolVar(
|
||||||
flags.setEnv(name, env)
|
flags.setEnv(name, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set new float64 variable to parse.
|
||||||
func (flags *Flags) Float64Var(
|
func (flags *Flags) Float64Var(
|
||||||
p *float64,
|
p *float64,
|
||||||
name string,
|
name string,
|
||||||
|
@ -102,6 +110,7 @@ func (flags *Flags) Float64Var(
|
||||||
flags.setEnv(name, env)
|
flags.setEnv(name, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set new duration variable to parse.
|
||||||
func (flags *Flags) DurationVar(
|
func (flags *Flags) DurationVar(
|
||||||
p *time.Duration,
|
p *time.Duration,
|
||||||
name string,
|
name string,
|
||||||
|
@ -126,14 +135,18 @@ func (flags *Flags) Parse() []string {
|
||||||
return flags.parsedArgs
|
return flags.parsedArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get all the arguments, including the
|
||||||
|
// parsed ones.
|
||||||
func (flags *Flags) AllArgs() []string {
|
func (flags *Flags) AllArgs() []string {
|
||||||
return flags.args
|
return flags.args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get all the arguments going after options.
|
||||||
func (flags *Flags) Args() []string {
|
func (flags *Flags) Args() []string {
|
||||||
return flags.parsedArgs
|
return flags.parsedArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the tool currently called.
|
||||||
func (flags *Flags) Tool() *Tool {
|
func (flags *Flags) Tool() *Tool {
|
||||||
return flags.tool
|
return flags.tool
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package mtool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
"strings"
|
||||||
"flag"
|
"flag"
|
||||||
"sort"
|
"sort"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -118,14 +119,28 @@ func (t *Tool) Run(args []string) {
|
||||||
flags := &Flags{
|
flags := &Flags{
|
||||||
FlagSet : flagSet,
|
FlagSet : flagSet,
|
||||||
envMap: make(map[string]string),
|
envMap: make(map[string]string),
|
||||||
|
envNameMap: make(map[string] []string),
|
||||||
}
|
}
|
||||||
out := flags.Output()
|
out := flags.Output()
|
||||||
flags.Usage = func() {
|
flags.Usage = func() {
|
||||||
n := 0
|
nflags := 0
|
||||||
flags.VisitAll(func(f *flag.Flag){
|
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
|
// Name
|
||||||
if usageTool.desc != "" {
|
if usageTool.desc != "" {
|
||||||
|
@ -162,6 +177,7 @@ func (t *Tool) Run(args []string) {
|
||||||
// Options
|
// Options
|
||||||
if hasOptions {
|
if hasOptions {
|
||||||
fmt.Fprintln(out, "\nOptions:")
|
fmt.Fprintln(out, "\nOptions:")
|
||||||
|
fmt.Fprintln(out, " --\n option terminator")
|
||||||
flags.PrintDefaults()
|
flags.PrintDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +194,18 @@ func (t *Tool) Run(args []string) {
|
||||||
|
|
||||||
// Print available sub commands if
|
// Print available sub commands if
|
||||||
// got no arguments.
|
// 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 != "" {
|
if t.desc != "" {
|
||||||
fmt.Fprintf(
|
fmt.Fprintf(
|
||||||
|
@ -191,7 +218,11 @@ func (t *Tool) Run(args []string) {
|
||||||
" %s <command>\n", t.FullName())
|
" %s <command>\n", t.FullName())
|
||||||
|
|
||||||
if t.ldesc != "" {
|
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 {
|
if len(t.subs) > 0 {
|
||||||
|
@ -205,7 +236,13 @@ func (t *Tool) Run(args []string) {
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
|
|
||||||
if _, ok := t.subs[toolName] ; !ok {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,3 +250,8 @@ func (t *Tool) Run(args []string) {
|
||||||
usageTool = sub
|
usageTool = sub
|
||||||
sub.Run(args)
|
sub.Run(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Tool) GetLongFormattedDesc() string {
|
||||||
|
return strings.ReplaceAll(t.ldesc, "\n", "\n ")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue