cli/main.go

136 lines
2 KiB
Go

package mtool
import(
"fmt"
"os"
path "path/filepath"
"flag"
"sort"
)
type Flags struct {
*flag.FlagSet
progName string
utilName string
args []string
parsedArgs []string
}
type Handler func(*Flags)
type Tool struct {
Handler Handler
Desc, Usage string
}
type Tools map[string] Tool
func (flags *Flags) Parse() []string {
flags.FlagSet.Parse(flags.args)
flags.parsedArgs = flags.FlagSet.Args()
return flags.parsedArgs
}
func (flags *Flags) AllArgs() []string {
return flags.args
}
func (flags *Flags) Args() []string {
return flags.parsedArgs
}
func (flags *Flags) ProgName() string {
return flags.progName
}
func (flags *Flags) UtilName() string {
return flags.utilName
}
func Main(name string, m Tools) {
var(
utilName string
args []string
)
arg0 := os.Args[0]
binBase := path.Base(arg0) ;
binBase = binBase[:len(binBase)-len(path.Ext(binBase))]
if binBase != name {
utilName = binBase
args = os.Args
} else {
if len(os.Args)<2 {
keys := make([]string, len(m))
i := 0
for k, _ := range m {
keys[i] = k
i++
}
sort.Strings(keys)
for _, k := range keys {
tool := m[k]
fmt.Printf("%s: %s\n", k, tool.Desc)
}
os.Exit(0)
}
utilName = os.Args[1]
args = os.Args[1:]
}
if _, ok := m[utilName] ; !ok {
fmt.Printf("%s: No such uitl as '%s'.\n", arg0, utilName )
os.Exit(1)
}
util := m[utilName]
flagSet := flag.NewFlagSet(utilName, flag.ExitOnError)
flags := &Flags{
FlagSet : flagSet,
}
flags.Usage = func() {
out := flags.Output()
n := 0
flags.VisitAll(func(f *flag.Flag){
n++
})
hasOptions := n != 0
fmt.Fprintf(
out,
"Usage of %s:\n\t%s",
utilName, utilName,
)
if hasOptions {
fmt.Fprintf(out, " [options]")
}
if util.Usage != "" {
fmt.Fprintf(
out,
" %s",
util.Usage,
)
}
fmt.Fprintln(out, "")
if hasOptions {
fmt.Fprintln(out, "Options:")
flags.PrintDefaults()
}
os.Exit(1)
}
flags.progName = name
flags.utilName = utilName
flags.args = args[1:]
util.Handler(flags)
}