-
Notifications
You must be signed in to change notification settings - Fork 0
/
help.go
119 lines (102 loc) · 2.77 KB
/
help.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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"
}