mirror of
https://github.com/foomo/posh.git
synced 2025-10-16 12:45:38 +00:00
120 lines
2.8 KiB
Go
120 lines
2.8 KiB
Go
package command
|
|
|
|
import (
|
|
"context"
|
|
"math"
|
|
"strings"
|
|
|
|
"github.com/foomo/posh/pkg/log"
|
|
"github.com/foomo/posh/pkg/prompt/goprompt"
|
|
"github.com/foomo/posh/pkg/readline"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type Help struct {
|
|
l log.Logger
|
|
name string
|
|
commands Commands
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Constructor
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func NewHelp(l log.Logger, commands Commands) *Help {
|
|
return &Help{
|
|
l: l,
|
|
name: "help",
|
|
commands: commands,
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Public methods
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func (c *Help) Name() string {
|
|
return c.name
|
|
}
|
|
|
|
func (c *Help) Description() string {
|
|
return "print help"
|
|
}
|
|
|
|
func (c *Help) Complete(ctx context.Context, r *readline.Readline) []goprompt.Suggest {
|
|
var suggests []goprompt.Suggest
|
|
switch {
|
|
case r.Args().LenLte(1):
|
|
for _, value := range c.list() {
|
|
suggests = append(suggests, goprompt.Suggest{Text: value.Name(), Description: value.Description()})
|
|
}
|
|
}
|
|
return suggests
|
|
}
|
|
|
|
func (c *Help) Validate(ctx context.Context, r *readline.Readline) error {
|
|
switch {
|
|
case r.Args().LenIs(0):
|
|
// all good
|
|
case r.Args().LenIs(1):
|
|
for _, command := range c.list() {
|
|
if r.Args().At(0) == command.Name() {
|
|
return nil
|
|
}
|
|
}
|
|
return errors.Errorf("invalid [command] argument: %s", r.Args().At(0))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Help) Execute(ctx context.Context, r *readline.Readline) error {
|
|
switch r.Args().Len() {
|
|
case 0:
|
|
ret := `Help about all available commands.
|
|
|
|
Usage:
|
|
help [command]
|
|
|
|
Available Commands:
|
|
`
|
|
for _, value := range c.list() {
|
|
ret += c.format(value.Name(), value.Description())
|
|
}
|
|
c.l.Print(ret)
|
|
default:
|
|
if helper, ok := c.commands.Get(r.Args().At(0)).(Helper); ok {
|
|
c.l.Print(helper.Help(ctx, r))
|
|
} else {
|
|
c.l.Print("command not found")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Private methods
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func (c *Help) list() []Command {
|
|
var ret []Command
|
|
for _, value := range c.commands.List() {
|
|
if _, ok := value.(Helper); ok {
|
|
ret = append(ret, value)
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// print formatted output
|
|
func (c *Help) format(name, description string) string {
|
|
offset := int(math.Max(0, float64(20-len(name))))
|
|
suffix := strings.Repeat(" ", offset)
|
|
prefix := ""
|
|
if offset == 0 {
|
|
suffix = "\n"
|
|
prefix = strings.Repeat(" ", 20)
|
|
}
|
|
return " " + name + suffix + prefix + description + "\n"
|
|
}
|