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