gob/shell/command/command.go

128 lines
2.7 KiB
Go
Raw Normal View History

2023-10-05 08:42:40 +00:00
package command
import (
"strings"
"gitea.zaclys.com/bvaudour/gob/format"
. "gitea.zaclys.com/bvaudour/gob/option"
)
// Parser est une interface pour parser des arguments en ligne de commande.
type Parser interface {
Parse([]string) Result[[]string]
IsParsed() bool
Reset()
}
// Helper est une interface permettant dafficher laide dune ligne de commande.
type Helper interface {
Name() string
Usage() string
}
// Command représente une commande à saisir.
type Command interface {
Parser
Helper
Help() string
Flags() FlagSet
Run()
}
// CommandSet est une commande regroupant plusieurs sous-commandes.
type CommandSet interface {
Parser
Helper
Help() string
Commands() []Command
}
// CommandHelp retourne laide sur une commande
func CommandHelp(c Command) string {
h := c.Help()
if h != "" {
return h
}
var sb strings.Builder
sb.WriteString(c.Usage())
sb.WriteByte('\n')
sb.WriteString(format.Apply("Usage:", "bold", "underline"))
sb.WriteByte(' ')
sb.WriteString(format.Apply(c.Name(), "l_yellow"))
sb.WriteString(format.Apply(" <options> <args>", "yellow"))
sb.WriteByte('\n')
if fs := c.Flags(); fs != nil {
sb.WriteByte('\n')
sb.WriteString(fs.Help())
}
return sb.String()
}
// CommandSetHelp retourne laide sur un ensemble de commandes
func CommandSetHelp(cs CommandSet) string {
h := cs.Help()
if h != "" {
return h
}
var sb strings.Builder
sb.WriteString(cs.Usage())
sb.WriteByte('\n')
sb.WriteString(format.Apply("Usage:", "bold", "underline"))
sb.WriteByte(' ')
sb.WriteString(format.Apply(cs.Name(), "l_yellow"))
sb.WriteString(format.Apply(" <cmd> <args>", "yellow"))
sb.WriteString("\n\n")
sb.WriteString(format.Apply("Available commands:", "bold", "l_red"))
sb.WriteByte('\n')
var (
cmds = cs.Commands()
lines [][]string
n int
hasHelp bool
)
for _, c := range cmds {
hasHelp = hasHelp || c.Name() == "help"
cmd, usage := c.Name(), strings.Split(c.Usage(), "\n")
if len(cmd) > n {
n = len(cmd)
}
for i, l := range usage {
columns := make([]string, 2)
if i == 0 {
columns[0] = cmd
}
columns[1] = l
lines = append(lines, columns)
}
}
if !hasHelp {
cmd, usage := "help", "Print this help"
if len(cmd) > n {
n = len(cmd)
}
lines = append(lines, []string{cmd, usage})
}
f, c := format.NewAlignment(format.LEFT, n), format.ColorOf("l_yellow")
for _, columns := range lines {
cmd, usage := columns[0], columns[1]
sb.WriteString(format.Tab(2))
if cmd == "" {
sb.WriteString(f.Format(cmd))
} else {
sb.WriteString(c.Format(f.Format(cmd)))
}
sb.WriteString(format.Tab(1))
sb.WriteString(usage)
sb.WriteByte('\n')
}
return sb.String()
}