mirror of
https://github.com/terraform-docs/terraform-docs.git
synced 2026-03-27 04:48:33 +07:00
Refactor docs to be published on website
Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>
This commit is contained in:
66
scripts/docs/format.tmpl
Normal file
66
scripts/docs/format.tmpl
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: "{{ .Name }}"
|
||||
description: "{{ .Description }}."
|
||||
menu:
|
||||
docs:
|
||||
parent: "{{ .Parent }}"
|
||||
weight: {{ .Weight }}
|
||||
toc: true
|
||||
---
|
||||
|
||||
## Synopsis
|
||||
|
||||
{{ .Synopsis }}.
|
||||
|
||||
{{- if .Runnable -}}
|
||||
{{ printf "\n" }}
|
||||
```console
|
||||
{{ .UseLine }}
|
||||
```
|
||||
{{- end }}
|
||||
|
||||
{{- if .Options -}}
|
||||
{{ printf "\n" }}
|
||||
## Options
|
||||
|
||||
```console
|
||||
{{ .Options -}}
|
||||
```
|
||||
{{- end }}
|
||||
|
||||
{{- if .InheritedOptions -}}
|
||||
{{ printf "\n" }}
|
||||
## Inherited Options
|
||||
|
||||
```console
|
||||
{{ .InheritedOptions -}}
|
||||
```
|
||||
{{- end }}
|
||||
|
||||
{{- if not .HasChildren -}}
|
||||
{{ printf "\n" }}
|
||||
## Example
|
||||
|
||||
Given the [`examples`][examples] module:
|
||||
|
||||
```shell
|
||||
{{ .Usage }}
|
||||
```
|
||||
|
||||
generates the following output:
|
||||
|
||||
{{ .Example }}
|
||||
[examples]: https://github.com/terraform-docs/terraform-docs/tree/master/examples
|
||||
{{- else -}}
|
||||
{{ printf "\n" }}
|
||||
## Subcommands
|
||||
|
||||
{{- printf "\n" -}}
|
||||
{{- range .Subcommands -}}
|
||||
{{- printf "\n" -}}
|
||||
- [{{ .Name }}]({{"{{"}}< ref "{{ .Link }}" >{{"}}"}})
|
||||
{{- range .Children -}}
|
||||
{{ printf "\n " }}- [{{ .Name }}]({{"{{"}}< ref "{{ .Link }}" >{{"}}"}})
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
"text/template"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@@ -29,35 +29,47 @@ import (
|
||||
)
|
||||
|
||||
// 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.
|
||||
// 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.
|
||||
|
||||
var basedir = "/docs"
|
||||
var formatdir = "/formats"
|
||||
var (
|
||||
baseWeight = 950
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := generate(cmd.NewCommand(), "", "FORMATS_GUIDE")
|
||||
if err != nil {
|
||||
if err := generate(cmd.NewCommand(), baseWeight, "terraform-docs"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func generate(cmd *cobra.Command, subdir string, basename string) error {
|
||||
func ignore(cmd *cobra.Command) bool {
|
||||
switch {
|
||||
case !cmd.IsAvailableCommand():
|
||||
return true
|
||||
case cmd.IsAdditionalHelpTopicCommand():
|
||||
return true
|
||||
case cmd.Annotations["kind"] == "":
|
||||
return true
|
||||
case cmd.Annotations["kind"] != "formatter":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func generate(cmd *cobra.Command, weight int, basename string) error {
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||
if ignore(c) {
|
||||
continue
|
||||
}
|
||||
if c.Annotations["kind"] == "" || c.Annotations["kind"] != "formatter" {
|
||||
continue
|
||||
}
|
||||
b := strings.Replace(strings.Replace(c.CommandPath(), " ", "-", -1), "terraform-docs-", "", -1)
|
||||
if err := generate(c, formatdir, b); err != nil {
|
||||
b := extractFilename(c.CommandPath())
|
||||
baseWeight++
|
||||
if err := generate(c, baseWeight, b); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
filename := filepath.Join("."+basedir, subdir, basename+".md")
|
||||
filename := filepath.Join("docs", "reference", basename+".md")
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -67,94 +79,98 @@ func generate(cmd *cobra.Command, subdir string, basename string) error {
|
||||
if _, err := io.WriteString(f, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := generateMarkdown(cmd, f); err != nil {
|
||||
if err := generateMarkdown(cmd, weight, f); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateMarkdown(cmd *cobra.Command, w io.Writer) error {
|
||||
type reference struct {
|
||||
Name string
|
||||
Command string
|
||||
Description string
|
||||
Parent string
|
||||
Synopsis string
|
||||
Runnable bool
|
||||
HasChildren bool
|
||||
UseLine string
|
||||
Options string
|
||||
InheritedOptions string
|
||||
Usage string
|
||||
Example string
|
||||
Subcommands []command
|
||||
Weight int
|
||||
}
|
||||
|
||||
type command struct {
|
||||
Name string
|
||||
Link string
|
||||
Children []command
|
||||
}
|
||||
|
||||
func generateMarkdown(cmd *cobra.Command, weight int, w io.Writer) error {
|
||||
cmd.InitDefaultHelpCmd()
|
||||
cmd.InitDefaultHelpFlag()
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
name := cmd.CommandPath()
|
||||
command := cmd.CommandPath()
|
||||
name := strings.Replace(command, "terraform-docs ", "", -1)
|
||||
|
||||
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()))
|
||||
parent := "reference"
|
||||
if cmd.Parent() != nil {
|
||||
parent = cmd.Parent().Name()
|
||||
}
|
||||
|
||||
if len(cmd.Example) > 0 {
|
||||
buf.WriteString("### Examples\n\n")
|
||||
buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.Example))
|
||||
ref := &reference{
|
||||
Name: name,
|
||||
Command: command,
|
||||
Description: short,
|
||||
Parent: parent,
|
||||
Synopsis: long,
|
||||
Runnable: cmd.Runnable(),
|
||||
HasChildren: len(cmd.Commands()) > 0,
|
||||
UseLine: cmd.UseLine(),
|
||||
Weight: weight,
|
||||
}
|
||||
|
||||
if err := printOptions(buf, cmd, name); err != nil {
|
||||
return err
|
||||
// Options
|
||||
if f := cmd.NonInheritedFlags(); f.HasAvailableFlags() {
|
||||
ref.Options = f.FlagUsages()
|
||||
}
|
||||
|
||||
if len(cmd.Commands()) == 0 {
|
||||
if err := printExample(buf, name); err != nil {
|
||||
return err
|
||||
}
|
||||
// Inherited Options
|
||||
if f := cmd.InheritedFlags(); f.HasAvailableFlags() {
|
||||
ref.InheritedOptions = f.FlagUsages()
|
||||
}
|
||||
|
||||
if ref.HasChildren {
|
||||
subcommands(ref, cmd.Commands())
|
||||
} else {
|
||||
if err := printSeeAlso(buf, cmd.Commands()); err != nil {
|
||||
return err
|
||||
}
|
||||
example(ref) //nolint:errcheck
|
||||
}
|
||||
|
||||
if !cmd.DisableAutoGenTag {
|
||||
buf.WriteString("###### Auto generated by spf13/cobra on " + time.Now().Format("2-Jan-2006") + "\n")
|
||||
}
|
||||
_, err := buf.WriteTo(w)
|
||||
return err
|
||||
file := "format.tmpl"
|
||||
paths := []string{filepath.Join("scripts", "docs", file)}
|
||||
|
||||
t := template.Must(template.New(file).ParseFiles(paths...))
|
||||
|
||||
return t.Execute(w, ref)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func getFlags(name string) string {
|
||||
switch strings.Replace(name, "terraform-docs ", "", -1) {
|
||||
func example(ref *reference) error {
|
||||
flag := ""
|
||||
switch ref.Name {
|
||||
case "pretty":
|
||||
return " --no-color"
|
||||
flag = " --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")
|
||||
ref.Usage = fmt.Sprintf("%s%s ./examples/", ref.Command, flag)
|
||||
|
||||
settings := print.DefaultSettings()
|
||||
settings.ShowColor = false
|
||||
@@ -168,20 +184,23 @@ func printExample(buf *bytes.Buffer, name string) error {
|
||||
},
|
||||
}
|
||||
|
||||
name = strings.Replace(name, "terraform-docs ", "", -1)
|
||||
printer, err := format.Factory(name, settings)
|
||||
printer, err := format.Factory(ref.Name, settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tfmodule, err := terraform.LoadWithOptions(options)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
output, err := printer.Print(tfmodule, settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
segments := strings.Split(output, "\n")
|
||||
buf := new(bytes.Buffer)
|
||||
for _, s := range segments {
|
||||
if s == "" {
|
||||
buf.WriteString("\n")
|
||||
@@ -189,34 +208,35 @@ func printExample(buf *bytes.Buffer, name string) error {
|
||||
buf.WriteString(fmt.Sprintf(" %s\n", s))
|
||||
}
|
||||
}
|
||||
buf.WriteString("\n")
|
||||
ref.Example = buf.String()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func printSeeAlso(buf *bytes.Buffer, children []*cobra.Command) error {
|
||||
buf.WriteString("### SEE ALSO\n\n")
|
||||
func subcommands(ref *reference, children []*cobra.Command) {
|
||||
subs := []command{}
|
||||
for _, child := range children {
|
||||
if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() {
|
||||
if ignore(child) {
|
||||
continue
|
||||
}
|
||||
if child.Annotations["kind"] == "" || child.Annotations["kind"] != "formatter" {
|
||||
continue
|
||||
}
|
||||
cname := child.CommandPath()
|
||||
link := strings.Replace(strings.Replace(cname, " ", "-", -1)+".md", "terraform-docs-", "", -1)
|
||||
buf.WriteString(fmt.Sprintf("* [%s](%s%s/%s)\t - %s\n", cname, basedir, formatdir, link, child.Short))
|
||||
subchild := []command{}
|
||||
for _, c := range child.Commands() {
|
||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||
continue
|
||||
}
|
||||
if c.Annotations["kind"] == "" || c.Annotations["kind"] != "formatter" {
|
||||
if ignore(c) {
|
||||
continue
|
||||
}
|
||||
cname := c.CommandPath()
|
||||
link := strings.Replace(strings.Replace(cname, " ", "-", -1)+".md", "terraform-docs-", "", -1)
|
||||
buf.WriteString(fmt.Sprintf(" * [%s](%s%s/%s)\t - %s\n", cname, basedir, formatdir, link, c.Short))
|
||||
link := extractFilename(cname)
|
||||
subchild = append(subchild, command{Name: cname, Link: link})
|
||||
}
|
||||
cname := child.CommandPath()
|
||||
link := extractFilename(cname)
|
||||
subs = append(subs, command{Name: cname, Link: link, Children: subchild})
|
||||
}
|
||||
buf.WriteString("\n")
|
||||
return nil
|
||||
ref.Subcommands = subs
|
||||
}
|
||||
|
||||
func extractFilename(s string) string {
|
||||
s = strings.Replace(s, " ", "-", -1)
|
||||
s = strings.Replace(s, "terraform-docs-", "", -1)
|
||||
return s
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user