mirror of
https://github.com/thegeeklab/wp-plugin-go.git
synced 2024-11-22 00:20:38 +00:00
feat: add helper to auto-generate cli docs (#40)
This commit is contained in:
parent
6d2c362281
commit
4d62198740
99
docs/docs.go
Normal file
99
docs/docs.go
Normal file
@ -0,0 +1,99 @@
|
||||
package docs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"embed"
|
||||
"html/template"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
type PluginArg struct {
|
||||
Name string
|
||||
EnvVars []string
|
||||
Description string
|
||||
Default string
|
||||
}
|
||||
|
||||
type CliTemplate struct {
|
||||
Name string
|
||||
Version string
|
||||
Description string
|
||||
Usage string
|
||||
UsageText string
|
||||
GlobalArgs []*PluginArg
|
||||
}
|
||||
|
||||
//go:embed templates
|
||||
var templateFs embed.FS
|
||||
|
||||
// ToMarkdown creates a markdown string for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func ToMarkdown(app *cli.App) (string, error) {
|
||||
var w bytes.Buffer
|
||||
|
||||
tpls, err := template.New("cli").ParseFS(templateFs, "**/*.tmpl")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := tpls.ExecuteTemplate(&w, "markdown.md.tmpl", GetTemplateData(app)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return w.String(), nil
|
||||
}
|
||||
|
||||
func GetTemplateData(app *cli.App) *CliTemplate {
|
||||
return &CliTemplate{
|
||||
Name: app.Name,
|
||||
Version: app.Version,
|
||||
Description: prepareMultilineString(app.Description),
|
||||
Usage: prepareMultilineString(app.Usage),
|
||||
UsageText: prepareMultilineString(app.UsageText),
|
||||
GlobalArgs: prepareArgsWithValues(app.VisibleFlags()),
|
||||
}
|
||||
}
|
||||
|
||||
func prepareMultilineString(s string) string {
|
||||
return strings.TrimRight(
|
||||
strings.TrimSpace(
|
||||
strings.ReplaceAll(s, "\n", " "),
|
||||
),
|
||||
".\r\n\t",
|
||||
)
|
||||
}
|
||||
|
||||
func prepareArgsWithValues(flags []cli.Flag) []*PluginArg {
|
||||
return parseFlags(flags)
|
||||
}
|
||||
|
||||
func parseFlags(flags []cli.Flag) []*PluginArg {
|
||||
args := make([]*PluginArg, 0)
|
||||
|
||||
for _, f := range flags {
|
||||
flag, ok := f.(cli.DocGenerationFlag)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
modArg := &PluginArg{}
|
||||
|
||||
name := flag.GetEnvVars()[0]
|
||||
name = strings.TrimPrefix(name, "PLUGIN_")
|
||||
modArg.Name = strings.ToLower(strings.TrimSpace(name))
|
||||
|
||||
modArg.Description = flag.GetUsage()
|
||||
modArg.Default = flag.GetDefaultText()
|
||||
|
||||
args = append(args, modArg)
|
||||
}
|
||||
|
||||
sort.SliceStable(args, func(i, j int) bool {
|
||||
return args[i].Name < args[j].Name
|
||||
})
|
||||
|
||||
return args
|
||||
}
|
67
docs/docs_test.go
Normal file
67
docs/docs_test.go
Normal file
@ -0,0 +1,67 @@
|
||||
package docs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func testApp() *cli.App {
|
||||
app := &cli.App{
|
||||
Name: "test",
|
||||
Description: "test description",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "dummy-flag",
|
||||
Usage: "dummy flag desc",
|
||||
EnvVars: []string{"PLUGIN_DUMMY_FLAG"},
|
||||
Value: "test",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "simpe-flag",
|
||||
EnvVars: []string{"PLUGIN_X_SIMPLE_FLAG"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "other.flag",
|
||||
Usage: "other flag with desc",
|
||||
EnvVars: []string{"PLUGIN_Z_OTHER_FLAG"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func testFileContent(t *testing.T, file string) string {
|
||||
t.Helper()
|
||||
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
data = bytes.ReplaceAll(data, []byte("\r\n"), []byte("\n"))
|
||||
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func TestToMarkdownFull(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
app *cli.App
|
||||
want string
|
||||
}{
|
||||
{"normal branch", testApp(), "testdata/expected-doc-full.md"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
want := testFileContent(t, tt.want)
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got, _ := ToMarkdown(tt.app); got != want {
|
||||
t.Errorf("got = %v, want %v", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
15
docs/templates/markdown.md.tmpl
vendored
Normal file
15
docs/templates/markdown.md.tmpl
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{{ with .Name }}# {{ . }}{{ end }}
|
||||
{{- with .Description }}
|
||||
|
||||
{{ . }}
|
||||
{{- end }}
|
||||
{{- if .GlobalArgs }}
|
||||
|
||||
## Parameters
|
||||
{{ range $v := .GlobalArgs }}
|
||||
**_{{ $v.Name }}_**{{ with $v.Default }} (defaut: {{ . }}){{ end }}{{ if $v.Description }}{{ "\\" }}{{ end }}
|
||||
{{- with $v.Description }}
|
||||
 {{ . }}
|
||||
{{- end }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
13
docs/testdata/expected-doc-full.md
vendored
Normal file
13
docs/testdata/expected-doc-full.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# test
|
||||
|
||||
test description
|
||||
|
||||
## Parameters
|
||||
|
||||
**_dummy_flag_** (defaut: "test")\
|
||||
 dummy flag desc
|
||||
|
||||
**_x_simple_flag_**
|
||||
|
||||
**_z_other_flag_**\
|
||||
 other flag with desc
|
Loading…
Reference in New Issue
Block a user