Files
lysenko/vendor/github.com/tcolgate/hugot/help.go
2016-10-14 23:42:51 +01:00

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