2019-03-08 20:47:06 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
//go:generate go run .
|
|
|
|
|
|
|
|
import (
|
2020-03-09 10:43:27 +02:00
|
|
|
"bufio"
|
2019-03-08 20:47:06 +02:00
|
|
|
"bytes"
|
2020-03-09 10:43:27 +02:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2019-03-08 20:47:06 +02:00
|
|
|
"go/format"
|
2020-03-09 10:43:27 +02:00
|
|
|
"io"
|
2019-03-08 20:47:06 +02:00
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2020-03-09 10:43:27 +02:00
|
|
|
"sort"
|
2019-03-08 20:47:06 +02:00
|
|
|
"strings"
|
|
|
|
"text/template"
|
|
|
|
|
2024-10-14 13:14:05 +02:00
|
|
|
"github.com/go-acme/lego/v4/internal/dns/descriptors"
|
2019-03-08 20:47:06 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2024-10-14 13:14:05 +02:00
|
|
|
root = "../../../"
|
|
|
|
|
|
|
|
mdTemplate = root + "internal/dns/docs/dns.md.tmpl"
|
|
|
|
cliTemplate = root + "internal/dns/docs/dns.go.tmpl"
|
2019-03-08 20:47:06 +02:00
|
|
|
cliOutput = root + "cmd/zz_gen_cmd_dnshelp.go"
|
|
|
|
docOutput = root + "docs/content/dns"
|
2020-03-09 10:43:27 +02:00
|
|
|
readmePath = root + "README.md"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
startLine = "<!-- START DNS PROVIDERS LIST -->"
|
|
|
|
endLine = "<!-- END DNS PROVIDERS LIST -->"
|
2019-03-08 20:47:06 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
2024-10-14 13:14:05 +02:00
|
|
|
models, err := descriptors.GetProviderInformation(root)
|
2019-03-08 20:47:06 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-10-14 13:14:05 +02:00
|
|
|
for _, m := range models.Providers {
|
|
|
|
// generate documentation
|
|
|
|
err = generateDocumentation(m)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-08 20:47:06 +02:00
|
|
|
// generate CLI help
|
|
|
|
err = generateCLIHelp(models)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2020-03-09 10:43:27 +02:00
|
|
|
|
|
|
|
// generate README.md
|
|
|
|
err = generateReadMe(models)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("Documentation for %d DNS providers has been generated.\n", len(models.Providers)+1)
|
2019-03-08 20:47:06 +02:00
|
|
|
}
|
|
|
|
|
2024-10-14 13:14:05 +02:00
|
|
|
func generateDocumentation(m descriptors.Provider) error {
|
2019-03-08 20:47:06 +02:00
|
|
|
filename := filepath.Join(docOutput, "zz_gen_"+m.Code+".md")
|
|
|
|
|
|
|
|
file, err := os.Create(filename)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-10-14 13:14:05 +02:00
|
|
|
defer func() { _ = file.Close() }()
|
|
|
|
|
2019-03-08 20:47:06 +02:00
|
|
|
return template.Must(template.ParseFiles(mdTemplate)).Execute(file, m)
|
|
|
|
}
|
|
|
|
|
2024-10-14 13:14:05 +02:00
|
|
|
func generateCLIHelp(models *descriptors.Providers) error {
|
2021-11-03 21:39:12 +02:00
|
|
|
filename := filepath.Clean(cliOutput)
|
2019-03-08 20:47:06 +02:00
|
|
|
|
|
|
|
file, err := os.Create(filename)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-10-14 13:14:05 +02:00
|
|
|
defer func() { _ = file.Close() }()
|
|
|
|
|
2019-03-08 20:47:06 +02:00
|
|
|
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
|
|
|
|
}
|
2020-03-09 10:43:27 +02:00
|
|
|
|
2024-10-14 13:14:05 +02:00
|
|
|
func generateReadMe(models *descriptors.Providers) error {
|
2024-05-09 21:31:20 +02:00
|
|
|
maximum, lines := extractTableData(models)
|
2020-03-09 10:43:27 +02:00
|
|
|
|
|
|
|
file, err := os.Open(readmePath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() { _ = file.Close() }()
|
|
|
|
|
|
|
|
var skip bool
|
|
|
|
|
|
|
|
buffer := bytes.NewBufferString("")
|
|
|
|
|
|
|
|
fileScanner := bufio.NewScanner(file)
|
|
|
|
for fileScanner.Scan() {
|
|
|
|
text := fileScanner.Text()
|
|
|
|
|
|
|
|
if text == startLine {
|
|
|
|
_, _ = fmt.Fprintln(buffer, text)
|
2024-05-09 21:31:20 +02:00
|
|
|
err = writeDNSTable(buffer, lines, maximum)
|
2020-03-09 10:43:27 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
skip = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if text == endLine {
|
|
|
|
skip = false
|
|
|
|
}
|
|
|
|
|
|
|
|
if skip {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
_, _ = fmt.Fprintln(buffer, text)
|
|
|
|
}
|
|
|
|
|
|
|
|
if fileScanner.Err() != nil {
|
|
|
|
return fileScanner.Err()
|
|
|
|
}
|
|
|
|
|
|
|
|
if skip {
|
|
|
|
return errors.New("missing end tag")
|
|
|
|
}
|
|
|
|
|
2021-08-25 11:44:11 +02:00
|
|
|
return os.WriteFile(readmePath, buffer.Bytes(), 0o666)
|
2020-03-09 10:43:27 +02:00
|
|
|
}
|
|
|
|
|
2024-10-14 13:14:05 +02:00
|
|
|
func extractTableData(models *descriptors.Providers) (int, [][]string) {
|
2020-03-09 10:43:27 +02:00
|
|
|
readmePattern := "[%s](https://go-acme.github.io/lego/dns/%s/)"
|
|
|
|
|
|
|
|
items := []string{fmt.Sprintf(readmePattern, "Manual", "manual")}
|
|
|
|
|
2024-05-09 21:31:20 +02:00
|
|
|
var maximum int
|
2020-03-09 10:43:27 +02:00
|
|
|
|
|
|
|
for _, pvd := range models.Providers {
|
|
|
|
item := fmt.Sprintf(readmePattern, strings.ReplaceAll(pvd.Name, "|", "/"), pvd.Code)
|
|
|
|
items = append(items, item)
|
|
|
|
|
2024-05-09 21:31:20 +02:00
|
|
|
if maximum < len(item) {
|
|
|
|
maximum = len(item)
|
2020-03-09 10:43:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const nbCol = 4
|
|
|
|
|
|
|
|
sort.Slice(items, func(i, j int) bool {
|
|
|
|
return strings.ToLower(items[i]) < strings.ToLower(items[j])
|
|
|
|
})
|
|
|
|
|
|
|
|
var lines [][]string
|
|
|
|
var line []string
|
|
|
|
|
|
|
|
for i, item := range items {
|
|
|
|
switch {
|
|
|
|
case len(line) == nbCol:
|
|
|
|
lines = append(lines, line)
|
|
|
|
line = []string{item}
|
|
|
|
|
2020-03-09 11:06:13 +02:00
|
|
|
case i == len(items)-1:
|
2020-03-09 10:43:27 +02:00
|
|
|
line = append(line, item)
|
|
|
|
for j := len(line); j < nbCol; j++ {
|
|
|
|
line = append(line, "")
|
|
|
|
}
|
|
|
|
lines = append(lines, line)
|
|
|
|
|
|
|
|
default:
|
|
|
|
line = append(line, item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(line) < nbCol {
|
|
|
|
for j := len(line); j < nbCol; j++ {
|
|
|
|
line = append(line, "")
|
|
|
|
}
|
|
|
|
lines = append(lines, line)
|
|
|
|
}
|
|
|
|
|
2024-05-09 21:31:20 +02:00
|
|
|
return maximum, lines
|
2020-03-09 10:43:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func writeDNSTable(w io.Writer, lines [][]string, size int) error {
|
|
|
|
_, err := fmt.Fprintf(w, "\n")
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = fmt.Fprintf(w, "|%[1]s|%[1]s|%[1]s|%[1]s|\n", strings.Repeat(" ", size+2))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = fmt.Fprintf(w, "|%[1]s|%[1]s|%[1]s|%[1]s|\n", strings.Repeat("-", size+2))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
linePattern := fmt.Sprintf("| %%-%[1]ds | %%-%[1]ds | %%-%[1]ds | %%-%[1]ds |\n", size)
|
|
|
|
for _, line := range lines {
|
|
|
|
_, err = fmt.Fprintf(w, linePattern, line[0], line[1], line[2], line[3])
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = fmt.Fprintf(w, "\n")
|
|
|
|
return err
|
|
|
|
}
|