mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-14 10:30:59 +00:00
Add utility for generating cobra documentation from .md files
This commit is contained in:
3
cmd/mdtogo/go.mod
Normal file
3
cmd/mdtogo/go.mod
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module sigs.k8s.io/kustomize/cmd/mdtogo
|
||||||
|
|
||||||
|
go 1.13
|
||||||
202
cmd/mdtogo/main.go
Normal file
202
cmd/mdtogo/main.go
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
// Package main generates cobra.Command go variables containing documentation read from .md files.
|
||||||
|
// Usage: mdtogo SOURCE_MD_DIR/ DEST_GO_DIR/ [--full=true]
|
||||||
|
//
|
||||||
|
// The command will create a docs.go file under DEST_GO_DIR/ containing string variables to be
|
||||||
|
// used by cobra commands for documentation.The variable names are generated from the SOURCE_MD_DIR/
|
||||||
|
// file names, replacing '-' with '', title casing the filename, and dropping the extension.
|
||||||
|
// All *.md will be read from DEST_GO_DIR/, and a single DEST_GO_DIR/docs.go file is generated.
|
||||||
|
//
|
||||||
|
// Each .md document will be parsed as follows if no flags are provided:
|
||||||
|
//
|
||||||
|
// ## cmd
|
||||||
|
//
|
||||||
|
// This section will be parsed into a string variable for `Short`
|
||||||
|
//
|
||||||
|
// ### Synopsis
|
||||||
|
//
|
||||||
|
// This section will be parsed into a string variable for `Long`
|
||||||
|
//
|
||||||
|
// ### Examples
|
||||||
|
//
|
||||||
|
// This section will be parsed into a string variable for `Example`
|
||||||
|
//
|
||||||
|
// If --full=true is provided, the document will be parsed as follows:
|
||||||
|
//
|
||||||
|
// ## cmd
|
||||||
|
//
|
||||||
|
// All sections will be parsed into a Long string.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var full bool
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
for _, a := range os.Args {
|
||||||
|
if a == "--full=true" {
|
||||||
|
full = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(os.Args) < 3 {
|
||||||
|
fmt.Fprintf(os.Stderr, "Usage: mdtogo SOURCE_MD_DIR/ DEST_GO_DIR/\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
source := os.Args[1]
|
||||||
|
dest := os.Args[2]
|
||||||
|
|
||||||
|
files, err := ioutil.ReadDir(source)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var docs []doc
|
||||||
|
for _, f := range files {
|
||||||
|
if filepath.Ext(f.Name()) != ".md" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b, err := ioutil.ReadFile(filepath.Join(source, f.Name()))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
docs = append(docs, parse(f.Name(), string(b)))
|
||||||
|
}
|
||||||
|
|
||||||
|
out := []string{`// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
// Code generated by "mdtogo"; DO NOT EDIT.
|
||||||
|
package ` + filepath.Base(dest) + "\n"}
|
||||||
|
|
||||||
|
for i := range docs {
|
||||||
|
out = append(out, docs[i].String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(dest); err != nil {
|
||||||
|
_ = os.Mkdir(dest, 0700)
|
||||||
|
}
|
||||||
|
|
||||||
|
o := strings.Join(out, "\n")
|
||||||
|
err = ioutil.WriteFile(filepath.Join(dest, "docs.go"), []byte(o), 0600)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parse(name, value string) doc {
|
||||||
|
name = strings.ReplaceAll(name, filepath.Ext(name), "")
|
||||||
|
name = strings.Title(name)
|
||||||
|
name = strings.ReplaceAll(name, "-", "")
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(bytes.NewBufferString(value))
|
||||||
|
|
||||||
|
var long, examples []string
|
||||||
|
var short string
|
||||||
|
var isLong, isExample, isIndent bool
|
||||||
|
var doc doc
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "## ") && short == "" {
|
||||||
|
for scanner.Scan() {
|
||||||
|
if strings.TrimSpace(scanner.Text()) == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
short = scanner.Text()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !full {
|
||||||
|
if strings.HasPrefix(line, "### Synopsis") {
|
||||||
|
isLong = true
|
||||||
|
isExample = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "### Examples") {
|
||||||
|
isLong = false
|
||||||
|
isExample = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "### ") {
|
||||||
|
isLong = false
|
||||||
|
isExample = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "```") {
|
||||||
|
isIndent = !isIndent
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
line = strings.ReplaceAll(line, "`", "` + \"`\" + `")
|
||||||
|
if isIndent {
|
||||||
|
line = "\t" + line
|
||||||
|
}
|
||||||
|
|
||||||
|
if isLong || full {
|
||||||
|
long = append(long, line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if isExample {
|
||||||
|
examples = append(examples, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doc.Name = name
|
||||||
|
doc.Short = short
|
||||||
|
doc.Long = strings.Join(long, "\n")
|
||||||
|
doc.Examples = strings.Join(examples, "\n")
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return doc
|
||||||
|
}
|
||||||
|
|
||||||
|
type doc struct {
|
||||||
|
Name string
|
||||||
|
Short string
|
||||||
|
Long string
|
||||||
|
Examples string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d doc) String() string {
|
||||||
|
var parts []string
|
||||||
|
|
||||||
|
if d.Short != "" {
|
||||||
|
parts = append(parts,
|
||||||
|
fmt.Sprintf("var %sShort=`%s`", d.Name, d.Short))
|
||||||
|
}
|
||||||
|
if d.Long != "" {
|
||||||
|
parts = append(parts,
|
||||||
|
fmt.Sprintf("var %sLong=`%s`", d.Name, d.Long))
|
||||||
|
}
|
||||||
|
if d.Examples != "" {
|
||||||
|
parts = append(parts,
|
||||||
|
fmt.Sprintf("var %sExamples=`%s`", d.Name, d.Examples))
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(parts, "\n") + "\n"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user