lego/internal/dnsdocs/generator.go
Ludovic Fernandez 62fea05e21
Automatic generation of documentation (#818)
* generate a detailed CLI help
* generate a documentation site
* new readme
2019-03-08 19:47:06 +01:00

137 lines
2.6 KiB
Go

package main
//go:generate go run .
import (
"bytes"
"go/format"
"log"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/BurntSushi/toml"
)
const (
root = "../../"
dnsPackage = root + "providers/dns"
mdTemplate = root + "internal/dnsdocs/dns.md.tmpl"
cliTemplate = root + "internal/dnsdocs/dns.go.tmpl"
cliOutput = root + "cmd/zz_gen_cmd_dnshelp.go"
docOutput = root + "docs/content/dns"
)
type Model struct {
Name string // Real name of the DNS provider
Code string // DNS code
URL string // DNS provider URL
Description string // Provider summary
Example string // CLI example
Configuration *Configuration // Environment variables
Links *Links // Links
Additional string // Extra documentation
GeneratedFrom string // Source file
}
type Configuration struct {
Credentials map[string]string
Additional map[string]string
}
type Links struct {
API string
GoClient string
}
type Providers struct {
Providers []Model
}
func main() {
models := &Providers{}
err := filepath.Walk(dnsPackage, walker(models))
if err != nil {
log.Fatal(err)
}
// generate CLI help
err = generateCLIHelp(models)
if err != nil {
log.Fatal(err)
}
}
func walker(prs *Providers) func(string, os.FileInfo, error) error {
return func(path string, _ os.FileInfo, err error) error {
if err != nil {
return err
}
if filepath.Ext(path) == ".toml" {
m := Model{}
m.GeneratedFrom, err = filepath.Rel(root, path)
if err != nil {
return err
}
_, err := toml.DecodeFile(path, &m)
if err != nil {
return err
}
prs.Providers = append(prs.Providers, m)
// generate documentation
return generateDocumentation(m)
}
return nil
}
}
func generateDocumentation(m Model) error {
filename := filepath.Join(docOutput, "zz_gen_"+m.Code+".md")
file, err := os.Create(filename)
if err != nil {
return err
}
return template.Must(template.ParseFiles(mdTemplate)).Execute(file, m)
}
func generateCLIHelp(models *Providers) error {
filename := filepath.Join(cliOutput)
file, err := os.Create(filename)
if err != nil {
return err
}
tlt := template.New(filepath.Base(cliTemplate)).Funcs(map[string]interface{}{
"safe": func(src string) string {
return strings.ReplaceAll(src, "`", "'")
},
})
b := &bytes.Buffer{}
err = template.Must(tlt.ParseFiles(cliTemplate)).Execute(b, models)
if err != nil {
return err
}
// gofmt
source, err := format.Source(b.Bytes())
if err != nil {
return err
}
_, err = file.Write(source)
return err
}