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