128 lines
2.7 KiB
Go
128 lines
2.7 KiB
Go
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 d’afficher l’aide d’une 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 l’aide 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 l’aide 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()
|
||
}
|