
The switch to urfave/cli had a use of a /v2 API, which go modules handles correctly but vndr ignores. Downgrade urfave/cli for now until the switch to go modules. Add missing dependencies, which vndr now sees. Note that CI was not catching this issue, it seems that some part of the build process was pulling in dependencies even if they weren't in vendor, causing the build to work. However the vendor check was not seeing it. The ARM build didn't pull in other dependencies into the gopath, causing those builds to break. Signed-off-by: Derek McGowan <derek@mcgstyle.net>
146 lines
3.1 KiB
Go
146 lines
3.1 KiB
Go
package cli
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"sort"
|
|
"strings"
|
|
"text/template"
|
|
|
|
"github.com/cpuguy83/go-md2man/md2man"
|
|
)
|
|
|
|
// ToMarkdown creates a markdown string for the `*App`
|
|
// The function errors if either parsing or writing of the string fails.
|
|
func (a *App) ToMarkdown() (string, error) {
|
|
var w bytes.Buffer
|
|
if err := a.writeDocTemplate(&w); err != nil {
|
|
return "", err
|
|
}
|
|
return w.String(), nil
|
|
}
|
|
|
|
// ToMan creates a man page string for the `*App`
|
|
// The function errors if either parsing or writing of the string fails.
|
|
func (a *App) ToMan() (string, error) {
|
|
var w bytes.Buffer
|
|
if err := a.writeDocTemplate(&w); err != nil {
|
|
return "", err
|
|
}
|
|
man := md2man.Render(w.Bytes())
|
|
return string(man), nil
|
|
}
|
|
|
|
type cliTemplate struct {
|
|
App *App
|
|
Commands []string
|
|
GlobalArgs []string
|
|
SynopsisArgs []string
|
|
}
|
|
|
|
func (a *App) writeDocTemplate(w io.Writer) error {
|
|
const name = "cli"
|
|
t, err := template.New(name).Parse(MarkdownDocTemplate)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return t.ExecuteTemplate(w, name, &cliTemplate{
|
|
App: a,
|
|
Commands: prepareCommands(a.Commands, 0),
|
|
GlobalArgs: prepareArgsWithValues(a.Flags),
|
|
SynopsisArgs: prepareArgsSynopsis(a.Flags),
|
|
})
|
|
}
|
|
|
|
func prepareCommands(commands []Command, level int) []string {
|
|
coms := []string{}
|
|
for i := range commands {
|
|
command := &commands[i]
|
|
usage := ""
|
|
if command.Usage != "" {
|
|
usage = command.Usage
|
|
}
|
|
|
|
prepared := fmt.Sprintf("%s %s\n\n%s\n",
|
|
strings.Repeat("#", level+2),
|
|
strings.Join(command.Names(), ", "),
|
|
usage,
|
|
)
|
|
|
|
flags := prepareArgsWithValues(command.Flags)
|
|
if len(flags) > 0 {
|
|
prepared += fmt.Sprintf("\n%s", strings.Join(flags, "\n"))
|
|
}
|
|
|
|
coms = append(coms, prepared)
|
|
|
|
// recursevly iterate subcommands
|
|
if len(command.Subcommands) > 0 {
|
|
coms = append(
|
|
coms,
|
|
prepareCommands(command.Subcommands, level+1)...,
|
|
)
|
|
}
|
|
}
|
|
|
|
return coms
|
|
}
|
|
|
|
func prepareArgsWithValues(flags []Flag) []string {
|
|
return prepareFlags(flags, ", ", "**", "**", `""`, true)
|
|
}
|
|
|
|
func prepareArgsSynopsis(flags []Flag) []string {
|
|
return prepareFlags(flags, "|", "[", "]", "[value]", false)
|
|
}
|
|
|
|
func prepareFlags(
|
|
flags []Flag,
|
|
sep, opener, closer, value string,
|
|
addDetails bool,
|
|
) []string {
|
|
args := []string{}
|
|
for _, f := range flags {
|
|
flag, ok := f.(DocGenerationFlag)
|
|
if !ok {
|
|
continue
|
|
}
|
|
modifiedArg := opener
|
|
for _, s := range strings.Split(flag.GetName(), ",") {
|
|
trimmed := strings.TrimSpace(s)
|
|
if len(modifiedArg) > len(opener) {
|
|
modifiedArg += sep
|
|
}
|
|
if len(trimmed) > 1 {
|
|
modifiedArg += fmt.Sprintf("--%s", trimmed)
|
|
} else {
|
|
modifiedArg += fmt.Sprintf("-%s", trimmed)
|
|
}
|
|
}
|
|
modifiedArg += closer
|
|
if flag.TakesValue() {
|
|
modifiedArg += fmt.Sprintf("=%s", value)
|
|
}
|
|
|
|
if addDetails {
|
|
modifiedArg += flagDetails(flag)
|
|
}
|
|
|
|
args = append(args, modifiedArg+"\n")
|
|
|
|
}
|
|
sort.Strings(args)
|
|
return args
|
|
}
|
|
|
|
// flagDetails returns a string containing the flags metadata
|
|
func flagDetails(flag DocGenerationFlag) string {
|
|
description := flag.GetUsage()
|
|
value := flag.GetValue()
|
|
if value != "" {
|
|
description += " (default: " + value + ")"
|
|
}
|
|
return ": " + description
|
|
}
|