mirror of
https://github.com/terraform-docs/terraform-docs.git
synced 2026-03-27 04:48:33 +07:00
docs: Auto generate formats document from examples (#192)
* Auto generate formats document from examples * fix lint issues
This commit is contained in:
188
scripts/docs/generate.go
Normal file
188
scripts/docs/generate.go
Normal file
@@ -0,0 +1,188 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/segmentio/terraform-docs/cmd"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/json"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/markdown/document"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/markdown/table"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/pretty"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/yaml"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// These are practiaclly a copy/paste of https://github.com/spf13/cobra/blob/master/doc/md_docs.go
|
||||
// The reason we've decided to bring them over and not use them directly from cobra module was
|
||||
// that we wanted to inject custom "Example" section with generated output based on the "examples"
|
||||
// folder.
|
||||
|
||||
func main() {
|
||||
for _, c := range cmd.FormatterCmds() {
|
||||
err := generate(c, "./docs/formats")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generate(cmd *cobra.Command, dir string) error {
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||
continue
|
||||
}
|
||||
if err := generate(c, dir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cmdpath := strings.Replace(cmd.CommandPath(), "terraform-docs ", "", -1)
|
||||
basename := strings.Replace(cmdpath, " ", "-", -1) + ".md"
|
||||
filename := filepath.Join(dir, basename)
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close() //nolint:errcheck
|
||||
|
||||
if _, err := io.WriteString(f, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := generateMarkdown(cmd, f); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateMarkdown(cmd *cobra.Command, w io.Writer) error {
|
||||
cmd.InitDefaultHelpCmd()
|
||||
cmd.InitDefaultHelpFlag()
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
name := cmd.CommandPath()
|
||||
|
||||
short := cmd.Short
|
||||
long := cmd.Long
|
||||
if len(long) == 0 {
|
||||
long = short
|
||||
}
|
||||
|
||||
buf.WriteString("## " + name + "\n\n")
|
||||
buf.WriteString(short + "\n\n")
|
||||
buf.WriteString("### Synopsis\n\n")
|
||||
buf.WriteString(long + "\n\n")
|
||||
|
||||
if cmd.Runnable() {
|
||||
buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.UseLine()))
|
||||
}
|
||||
|
||||
if len(cmd.Example) > 0 {
|
||||
buf.WriteString("### Examples\n\n")
|
||||
buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.Example))
|
||||
}
|
||||
|
||||
if err := printOptions(buf, cmd, name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := printExample(buf, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !cmd.DisableAutoGenTag {
|
||||
buf.WriteString("###### Auto generated by spf13/cobra on " + time.Now().Format("2-Jan-2006") + "\n")
|
||||
}
|
||||
_, err = buf.WriteTo(w)
|
||||
return err
|
||||
}
|
||||
|
||||
func printOptions(buf *bytes.Buffer, cmd *cobra.Command, name string) error {
|
||||
flags := cmd.NonInheritedFlags()
|
||||
flags.SetOutput(buf)
|
||||
if flags.HasAvailableFlags() {
|
||||
buf.WriteString("### Options\n\n```\n")
|
||||
flags.PrintDefaults()
|
||||
buf.WriteString("```\n\n")
|
||||
}
|
||||
|
||||
parentFlags := cmd.InheritedFlags()
|
||||
parentFlags.SetOutput(buf)
|
||||
if parentFlags.HasAvailableFlags() {
|
||||
buf.WriteString("### Options inherited from parent commands\n\n```\n")
|
||||
parentFlags.PrintDefaults()
|
||||
buf.WriteString("```\n\n")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type printer func(*tfconf.Module, *print.Settings) (string, error)
|
||||
|
||||
func getPrinter(name string) printer {
|
||||
switch strings.Replace(name, "terraform-docs ", "", -1) {
|
||||
case "json":
|
||||
return json.Print
|
||||
case "markdown document":
|
||||
return document.Print
|
||||
case "markdown table":
|
||||
return table.Print
|
||||
case "pretty":
|
||||
return pretty.Print
|
||||
case "yaml":
|
||||
return yaml.Print
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getFlags(name string) string {
|
||||
switch strings.Replace(name, "terraform-docs ", "", -1) {
|
||||
case "pretty":
|
||||
return " --no-color"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func printExample(buf *bytes.Buffer, name string) error {
|
||||
buf.WriteString("### Example\n\n")
|
||||
buf.WriteString("Given the [`examples`](/examples/) module:\n\n")
|
||||
buf.WriteString("```shell\n")
|
||||
buf.WriteString(fmt.Sprintf("%s%s ./examples/\n", name, getFlags(name)))
|
||||
buf.WriteString("```\n\n")
|
||||
buf.WriteString("generates the following output:\n\n")
|
||||
|
||||
module, err := tfconf.CreateModule("./examples")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// fmt.Println(name)
|
||||
if fn := getPrinter(name); fn != nil {
|
||||
settings := print.NewSettings()
|
||||
settings.ShowColor = false
|
||||
|
||||
output, err := fn(module, settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
segments := strings.Split(output, "\n")
|
||||
for _, s := range segments {
|
||||
if s == "" {
|
||||
buf.WriteString("\n")
|
||||
} else {
|
||||
buf.WriteString(fmt.Sprintf(" %s\n", s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("\n\n")
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user