Refactor markdown generator
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
Родитель
cd90893cc2
Коммит
885c73a35e
|
@ -1,46 +1,23 @@
|
|||
package main
|
||||
package docgen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/docker/buildx/commands"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const descriptionSourcePath = "docs/reference/"
|
||||
|
||||
func generateDocs(opts *options) error {
|
||||
dockerCLI, err := command.NewDockerCli()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := &cobra.Command{
|
||||
Use: "docker [OPTIONS] COMMAND [ARG...]",
|
||||
Short: "The base command for the Docker CLI.",
|
||||
}
|
||||
cmd.AddCommand(commands.NewRootCmd("buildx", true, dockerCLI))
|
||||
return genCmd(cmd, opts.target)
|
||||
}
|
||||
|
||||
func getMDFilename(cmd *cobra.Command) string {
|
||||
name := cmd.CommandPath()
|
||||
if i := strings.Index(name, " "); i >= 0 {
|
||||
name = name[i+1:]
|
||||
}
|
||||
return strings.ReplaceAll(name, " ", "_") + ".md"
|
||||
}
|
||||
|
||||
func genCmd(cmd *cobra.Command, dir string) error {
|
||||
func GenMarkdown(cmd *cobra.Command, dir string) error {
|
||||
for _, c := range cmd.Commands() {
|
||||
if err := genCmd(c, dir); err != nil {
|
||||
if err := GenMarkdown(c, dir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -48,23 +25,42 @@ func genCmd(cmd *cobra.Command, dir string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
mdFile := getMDFilename(cmd)
|
||||
mdFile := mdFilename(cmd)
|
||||
fullPath := filepath.Join(dir, mdFile)
|
||||
|
||||
if _, err := os.Stat(fullPath); os.IsNotExist(err) {
|
||||
log.Printf("INFO: Init markdown for %s", cmd.CommandPath())
|
||||
var icBuf bytes.Buffer
|
||||
icTpl, err := template.New("ic").Option("missingkey=error").Parse(`# {{ .Command }}
|
||||
|
||||
<!---MARKER_GEN_START-->
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = icTpl.Execute(&icBuf, struct {
|
||||
Command string
|
||||
}{
|
||||
Command: cmd.CommandPath(),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = ioutil.WriteFile(fullPath, icBuf.Bytes(), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadFile(fullPath)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return errors.Wrapf(err, "%s does not exist", mdFile)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
cs := string(content)
|
||||
|
||||
markerStart := "<!---MARKER_GEN_START-->"
|
||||
markerEnd := "<!---MARKER_GEN_END-->"
|
||||
|
||||
start := strings.Index(cs, markerStart)
|
||||
end := strings.Index(cs, markerEnd)
|
||||
start := strings.Index(cs, "<!---MARKER_GEN_START-->")
|
||||
end := strings.Index(cs, "<!---MARKER_GEN_END-->")
|
||||
|
||||
if start == -1 {
|
||||
return errors.Errorf("no start marker in %s", mdFile)
|
||||
|
@ -73,11 +69,11 @@ func genCmd(cmd *cobra.Command, dir string) error {
|
|||
return errors.Errorf("no end marker in %s", mdFile)
|
||||
}
|
||||
|
||||
out, err := cmdOutput(cmd, cs)
|
||||
out, err := mdCmdOutput(cmd, cs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cont := cs[:start] + markerStart + "\n" + out + "\n" + cs[end:]
|
||||
cont := cs[:start] + "<!---MARKER_GEN_START-->" + "\n" + out + "\n" + cs[end:]
|
||||
|
||||
fi, err := os.Stat(fullPath)
|
||||
if err != nil {
|
||||
|
@ -86,15 +82,24 @@ func genCmd(cmd *cobra.Command, dir string) error {
|
|||
if err := ioutil.WriteFile(fullPath, []byte(cont), fi.Mode()); err != nil {
|
||||
return errors.Wrapf(err, "failed to write %s", fullPath)
|
||||
}
|
||||
log.Printf("updated %s", fullPath)
|
||||
|
||||
log.Printf("INFO: Markdown updated for %s", cmd.CommandPath())
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeLink(txt, link string) string {
|
||||
func mdFilename(cmd *cobra.Command) string {
|
||||
name := cmd.CommandPath()
|
||||
if i := strings.Index(name, " "); i >= 0 {
|
||||
name = name[i+1:]
|
||||
}
|
||||
return strings.ReplaceAll(name, " ", "_") + ".md"
|
||||
}
|
||||
|
||||
func mdMakeLink(txt, link string) string {
|
||||
return "[" + txt + "](#" + link + ")"
|
||||
}
|
||||
|
||||
func cmdOutput(cmd *cobra.Command, old string) (string, error) {
|
||||
func mdCmdOutput(cmd *cobra.Command, old string) (string, error) {
|
||||
b := &strings.Builder{}
|
||||
|
||||
desc := cmd.Short
|
||||
|
@ -118,7 +123,7 @@ func cmdOutput(cmd *cobra.Command, old string) (string, error) {
|
|||
fmt.Fprint(b, "| Name | Description |\n")
|
||||
fmt.Fprint(b, "| --- | --- |\n")
|
||||
for _, c := range cmd.Commands() {
|
||||
fmt.Fprintf(b, "| [`%s`](%s) | %s |\n", c.Name(), getMDFilename(c), c.Short)
|
||||
fmt.Fprintf(b, "| [`%s`](%s) | %s |\n", c.Name(), mdFilename(c), c.Short)
|
||||
}
|
||||
fmt.Fprint(b, "\n\n")
|
||||
}
|
||||
|
@ -141,7 +146,7 @@ func cmdOutput(cmd *cobra.Command, old string) (string, error) {
|
|||
if f.Shorthand != "" {
|
||||
name := "`-" + f.Shorthand + "`"
|
||||
if isLink {
|
||||
name = makeLink(name, f.Name)
|
||||
name = mdMakeLink(name, f.Name)
|
||||
}
|
||||
fmt.Fprintf(b, "%s, ", name)
|
||||
}
|
||||
|
@ -151,7 +156,7 @@ func cmdOutput(cmd *cobra.Command, old string) (string, error) {
|
|||
}
|
||||
name += "`"
|
||||
if isLink {
|
||||
name = makeLink(name, f.Name)
|
||||
name = mdMakeLink(name, f.Name)
|
||||
}
|
||||
fmt.Fprintf(b, "%s | %s |\n", name, f.Usage)
|
||||
})
|
||||
|
@ -160,33 +165,3 @@ func cmdOutput(cmd *cobra.Command, old string) (string, error) {
|
|||
|
||||
return b.String(), nil
|
||||
}
|
||||
|
||||
type options struct {
|
||||
target string
|
||||
}
|
||||
|
||||
func parseArgs() (*options, error) {
|
||||
opts := &options{}
|
||||
flags := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError)
|
||||
flags.StringVar(&opts.target, "target", descriptionSourcePath, "Docs directory")
|
||||
err := flags.Parse(os.Args[1:])
|
||||
return opts, err
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
log.Printf("error: %+v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
opts, err := parseArgs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := generateDocs(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -18,7 +18,7 @@ func main() {
|
|||
|
||||
dockerCLI, err := command.NewDockerCli()
|
||||
if err != nil {
|
||||
log.Printf("error: %+v", err)
|
||||
log.Printf("ERROR: %+v", err)
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
@ -32,15 +32,20 @@ func main() {
|
|||
|
||||
cwd, _ := os.Getwd()
|
||||
source := filepath.Join(cwd, sourcePath)
|
||||
if err := docgen.LoadLongDescription(cmd, source); err != nil {
|
||||
log.Printf("error: %+v", err)
|
||||
}
|
||||
|
||||
if err = os.MkdirAll(sourcePath, 0755); err != nil {
|
||||
log.Printf("error: %+v", err)
|
||||
log.Printf("ERROR: %+v", err)
|
||||
}
|
||||
|
||||
if err = docgen.GenMarkdown(cmd, sourcePath); err != nil {
|
||||
log.Printf("ERROR: %+v", err)
|
||||
}
|
||||
|
||||
if err := docgen.LoadLongDescription(cmd, source); err != nil {
|
||||
log.Printf("ERROR: %+v", err)
|
||||
}
|
||||
|
||||
if err = docgen.GenYamlTree(cmd, sourcePath); err != nil {
|
||||
log.Printf("error: %+v", err)
|
||||
log.Printf("ERROR: %+v", err)
|
||||
}
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module github.com/docker/docgen
|
|||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/spf13/cobra v1.2.1
|
||||
github.com/spf13/pflag v1.0.5
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -190,6 +190,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
|
|||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
|
|
Загрузка…
Ссылка в новой задаче