Custom output template for auto-generated docs (#785)
## Description Introduces a Corso specific (more desirable) formatting for the auto generated documentation. More or less an adaptation or https://github.com/spf13/cobra/blob/main/doc/md_docs.go. Unfortunately the original package does not have sufficient hooks to allow for plugging in a new renderer. Other approaches considered: * [Override the UsageTemplate ](https://github.com/spf13/cobra/blob/main/user_guide.md#defining-your-own-help) - unfortunately does not apply to Markdown generation * Use a golang template for the docs output - unfortunately the `pflags` package does not have a suitable way of iterating over the flags that can be easily fed into a template. Follow on work: * ~~Styling of flags tables as part of docs rendering - Done~~ * Opens up possibility for flag ordering - need to set `pflags.SortFlags = false` before parsing the flags - https://github.com/alcionai/corso/issues/783 * Can simplify sidebar command maintenance by naming the rendered docs files line similar to `<Num>_corso_command1_command2` where `<Num>` can be set as annotation on the commands. Order in the navbar can be set as part of command authoring - https://github.com/alcionai/corso/issues/784 ## Type of change Please check the type of change your PR introduces: - [ ] 🌻 Feature - [ ] 🐛 Bugfix - [x] 🗺️ Documentation - [ ] 🤖 Test - [ ] 🐹 Trivial/Minor ## Issue(s) <!-- Can reference multiple issues. Use one of the following "magic words" - "closes, fixes" to auto-close the Github issue. --> * https://github.com/alcionai/corso/issues/536 * https://github.com/alcionai/corso/issues/528 ## Test Plan <!-- How will this be tested prior to merging.--> - [x] 💪 Manual - [ ] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
ca6331b66e
commit
f509543856
@ -1,14 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/cobra/doc"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/alcionai/corso/src/cli"
|
||||
)
|
||||
@ -27,12 +29,6 @@ var cmd = &cobra.Command{
|
||||
Run: genDocs,
|
||||
}
|
||||
|
||||
const fmTemplate = `---
|
||||
title: "%s"
|
||||
hide_title: true
|
||||
---
|
||||
`
|
||||
|
||||
func main() {
|
||||
cmd.
|
||||
PersistentFlags().
|
||||
@ -48,22 +44,13 @@ func main() {
|
||||
}
|
||||
|
||||
func genDocs(cmd *cobra.Command, args []string) {
|
||||
identity := func(s string) string { return s }
|
||||
filePrepender := func(filename string) string {
|
||||
name := filepath.Base(filename)
|
||||
base := strings.TrimSuffix(name, filepath.Ext(name))
|
||||
|
||||
return fmt.Sprintf(fmTemplate, strings.Replace(base, "_", " ", -1))
|
||||
}
|
||||
|
||||
if err := makeDir(cliMarkdownDir); err != nil {
|
||||
fatal(errors.Wrap(err, "preparing directory for markdown generation"))
|
||||
}
|
||||
|
||||
corsoCmd := cli.CorsoCommand()
|
||||
corsoCmd.DisableAutoGenTag = true
|
||||
|
||||
err := doc.GenMarkdownTreeCustom(corsoCmd, cliMarkdownDir, filePrepender, identity)
|
||||
err := genMarkdownCorso(corsoCmd, cliMarkdownDir)
|
||||
if err != nil {
|
||||
fatal(errors.Wrap(err, "generating the Corso CLI markdown"))
|
||||
}
|
||||
@ -97,3 +84,116 @@ func fatal(err error) {
|
||||
fmt.Fprintf(os.Stderr, "ERR: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Adapted from https://github.com/spf13/cobra/blob/main/doc/md_docs.go for Corso specific formatting
|
||||
func genMarkdownCorso(cmd *cobra.Command, dir string) error {
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := genMarkdownCorso(c, dir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Skip docs for non-leaf commands
|
||||
if !cmd.Runnable() || cmd.HasSubCommands() {
|
||||
return nil
|
||||
}
|
||||
|
||||
basename := strings.ReplaceAll(cmd.CommandPath(), " ", "_") + ".md"
|
||||
filename := filepath.Join(dir, basename)
|
||||
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
return genMarkdownCustomCorso(cmd, f)
|
||||
}
|
||||
|
||||
func genMarkdownCustomCorso(cmd *cobra.Command, w io.Writer) error {
|
||||
cmd.InitDefaultHelpCmd()
|
||||
cmd.InitDefaultHelpFlag()
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
name := cmd.CommandPath()
|
||||
|
||||
// frontMatter section
|
||||
buf.WriteString("---\n")
|
||||
buf.WriteString(fmt.Sprintf("title: %s\n", name))
|
||||
buf.WriteString("hide_title: true\n")
|
||||
buf.WriteString("---\n")
|
||||
|
||||
// actual markdown
|
||||
buf.WriteString("## " + name + "\n\n")
|
||||
|
||||
if len(cmd.Long) > 0 {
|
||||
buf.WriteString(cmd.Long + "\n\n")
|
||||
} else {
|
||||
buf.WriteString(cmd.Short + "\n\n")
|
||||
}
|
||||
|
||||
if cmd.Runnable() {
|
||||
buf.WriteString(fmt.Sprintf("```bash\n%s\n```\n", cmd.UseLine()))
|
||||
}
|
||||
|
||||
flags := cmd.NonInheritedFlags()
|
||||
if flags.HasAvailableFlags() {
|
||||
buf.WriteString("\n")
|
||||
buf.WriteString("### Flags\n\n")
|
||||
printFlags(buf, flags)
|
||||
}
|
||||
|
||||
parentFlags := cmd.InheritedFlags()
|
||||
if parentFlags.HasAvailableFlags() {
|
||||
buf.WriteString("\n")
|
||||
buf.WriteString("### Global and inherited flags\n\n")
|
||||
printFlags(buf, parentFlags)
|
||||
}
|
||||
|
||||
if len(cmd.Example) > 0 {
|
||||
buf.WriteString("\n### Examples\n\n")
|
||||
buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.Example))
|
||||
}
|
||||
|
||||
_, err := buf.WriteTo(w)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func printFlags(buf *bytes.Buffer, flags *pflag.FlagSet) {
|
||||
if !flags.HasAvailableFlags() {
|
||||
return
|
||||
}
|
||||
|
||||
buf.WriteString("|Flag|Short|Default|Help\n")
|
||||
buf.WriteString("|:----|:-----|:-------|:----\n")
|
||||
|
||||
flags.VisitAll(func(flag *pflag.Flag) {
|
||||
if flag.Hidden {
|
||||
return
|
||||
}
|
||||
|
||||
buf.WriteString("|")
|
||||
buf.WriteString(fmt.Sprintf("`--%s`", flag.Name))
|
||||
buf.WriteString("|")
|
||||
|
||||
if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
|
||||
buf.WriteString(fmt.Sprintf("`-%s`", flag.Shorthand))
|
||||
}
|
||||
|
||||
buf.WriteString("|")
|
||||
|
||||
if flag.DefValue != "" {
|
||||
buf.WriteString(fmt.Sprintf("`%s`", flag.DefValue))
|
||||
}
|
||||
|
||||
buf.WriteString("|")
|
||||
buf.WriteString(flag.Usage)
|
||||
buf.WriteString("\n")
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user