148 lines
3.0 KiB
Go
148 lines
3.0 KiB
Go
package hugot
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
"text/tabwriter"
|
|
|
|
"context"
|
|
)
|
|
|
|
type muxHelp struct {
|
|
p *Mux
|
|
}
|
|
|
|
func (mx *muxHelp) Describe() (string, string) {
|
|
return "help", "provides help"
|
|
}
|
|
|
|
func (mx *muxHelp) Command(ctx context.Context, w ResponseWriter, m *Message) error {
|
|
//capture the command we were called as
|
|
initcmd := m.args[0]
|
|
m.Parse()
|
|
cmds := m.Args()
|
|
|
|
// list the full help
|
|
if len(cmds) == 0 && initcmd == "help" {
|
|
mx.fullHelp(ctx, w, m)
|
|
} else {
|
|
if initcmd != "help" {
|
|
cmds = append([]string{initcmd}, cmds...)
|
|
}
|
|
err := mx.cmdHelp(ctx, w, cmds)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return ErrSkipHears
|
|
}
|
|
|
|
func (mx *muxHelp) fullHelp(ctx context.Context, w ResponseWriter, m *Message) {
|
|
out := &bytes.Buffer{}
|
|
tw := new(tabwriter.Writer)
|
|
tw.Init(out, 0, 8, 1, '\t', 0)
|
|
|
|
if len(*mx.p.cmds) > 0 {
|
|
fmt.Fprintf(out, "Available commands are:\n")
|
|
_, _, hs := (*mx.p.cmds).List()
|
|
for _, h := range hs {
|
|
n, d := h.Describe()
|
|
fmt.Fprintf(tw, " %s\t - %s\n", n, d)
|
|
}
|
|
tw.Flush()
|
|
}
|
|
|
|
if len(mx.p.hears) > 0 {
|
|
fmt.Fprintf(out, "Active hear handlers are patternss are:\n")
|
|
for r, hs := range mx.p.hears {
|
|
for _, h := range hs {
|
|
n, d := h.Describe()
|
|
fmt.Fprintf(tw, " %s\t`%s`\t - %s\n", n, r.String(), d)
|
|
}
|
|
}
|
|
tw.Flush()
|
|
}
|
|
|
|
if len(mx.p.bghndlrs) > 0 {
|
|
fmt.Fprintf(out, "Active background handlers are:\n")
|
|
for _, h := range mx.p.bghndlrs {
|
|
n, d := h.Describe()
|
|
fmt.Fprintf(tw, " %s\t - %s\n", n, d)
|
|
}
|
|
tw.Flush()
|
|
}
|
|
|
|
if len(mx.p.rhndlrs) > 0 {
|
|
fmt.Fprintf(out, "Active raw handlers are:\n")
|
|
for _, h := range mx.p.rhndlrs {
|
|
n, d := h.Describe()
|
|
fmt.Fprintf(tw, " %s\t - %s\n", n, d)
|
|
}
|
|
tw.Flush()
|
|
}
|
|
|
|
io.Copy(w, out)
|
|
}
|
|
|
|
func (mx *muxHelp) cmdHelp(ctx context.Context, w ResponseWriter, cmds []string) error {
|
|
var cs *CommandSet
|
|
var path []string
|
|
|
|
cs = mx.p.cmds
|
|
|
|
var cmd CommandHandler
|
|
for {
|
|
if len(cmds) == 0 {
|
|
break
|
|
}
|
|
|
|
ok := false
|
|
if cmd, ok = (*cs)[cmds[0]]; !ok {
|
|
return ErrUnknownCommand
|
|
}
|
|
|
|
path = append(path, cmds[0])
|
|
cmds = cmds[1:]
|
|
if sch, ok := cmd.(CommandWithSubsHandler); ok {
|
|
cs = sch.SubCommands()
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
|
|
fmt.Fprint(w, cmdUsage(cmd, strings.Join(path, " "), nil))
|
|
return nil
|
|
}
|
|
|
|
func cmdUsage(c CommandHandler, cmdStr string, err error) error {
|
|
_, desc := c.Describe()
|
|
m := &Message{args: []string{cmdStr, "-help"}}
|
|
m.flagOut = &bytes.Buffer{}
|
|
m.FlagSet = flag.NewFlagSet(cmdStr, flag.ContinueOnError)
|
|
m.FlagSet.SetOutput(m.flagOut)
|
|
|
|
c.Command(context.TODO(), NewNullResponseWriter(*m), m)
|
|
if subcx, ok := c.(CommandWithSubsHandler); ok {
|
|
subs := subcx.SubCommands()
|
|
if subs != nil && len(*subs) > 0 {
|
|
fmt.Fprintf(m.flagOut, " Sub commands:\n")
|
|
for n, s := range *subs {
|
|
_, desc := s.Describe()
|
|
fmt.Fprintf(m.flagOut, " %s - %s\n", n, desc)
|
|
}
|
|
}
|
|
}
|
|
|
|
str := ""
|
|
if err != nil {
|
|
str = fmt.Sprintf("error, %s\n", err.Error())
|
|
} else {
|
|
str = fmt.Sprintf("Description: %s\n", desc)
|
|
}
|
|
return ErrUsage{str + m.flagOut.String()}
|
|
}
|