mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 14:32:24 -05:00 
			
		
		
		
	* start fixing up tests * fix up tests + automate with drone * fiddle with linting * messing about with drone.yml * some more fiddling * hmmm * add cache * add vendor directory * verbose * ci updates * update some little things * update sig
		
			
				
	
	
		
			148 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package cli
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"sort"
 | |
| 	"strings"
 | |
| 	"text/template"
 | |
| 
 | |
| 	"github.com/cpuguy83/go-md2man/v2/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.VisibleFlags()),
 | |
| 		SynopsisArgs: prepareArgsSynopsis(a.VisibleFlags()),
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func prepareCommands(commands []*Command, level int) []string {
 | |
| 	var coms []string
 | |
| 	for _, command := range commands {
 | |
| 		if command.Hidden {
 | |
| 			continue
 | |
| 		}
 | |
| 		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 flag.Names() {
 | |
| 			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
 | |
| }
 |