diff --git a/README.md b/README.md index 5116b9be..18f7b8c5 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ Documentation is hosted live at https://go-acme.github.io/lego/. Detailed documentation is available [here](https://go-acme.github.io/lego/dns). + + | | | | | |---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------| | [Alibaba Cloud DNS](https://go-acme.github.io/lego/dns/alidns/) | [Amazon Lightsail](https://go-acme.github.io/lego/dns/lightsail/) | [Amazon Route 53](https://go-acme.github.io/lego/dns/route53/) | [Aurora DNS](https://go-acme.github.io/lego/dns/auroradns/) | @@ -52,11 +54,13 @@ Detailed documentation is available [here](https://go-acme.github.io/lego/dns). | [Exoscale](https://go-acme.github.io/lego/dns/exoscale/) | [External program](https://go-acme.github.io/lego/dns/exec/) | [FastDNS](https://go-acme.github.io/lego/dns/fastdns/) | [Gandi Live DNS (v5)](https://go-acme.github.io/lego/dns/gandiv5/) | | [Gandi](https://go-acme.github.io/lego/dns/gandi/) | [Glesys](https://go-acme.github.io/lego/dns/glesys/) | [Go Daddy](https://go-acme.github.io/lego/dns/godaddy/) | [Google Cloud](https://go-acme.github.io/lego/dns/gcloud/) | | [Hosting.de](https://go-acme.github.io/lego/dns/hostingde/) | [HTTP request](https://go-acme.github.io/lego/dns/httpreq/) | [Internet Initiative Japan](https://go-acme.github.io/lego/dns/iij/) | [INWX](https://go-acme.github.io/lego/dns/inwx/) | -| [Joker](https://go-acme.github.io/lego/dns/joker/) | [Joohoi's ACME-DNS](https://go-acme.github.io/lego/dns/acme-dns) | [Linode (deprecated)](https://go-acme.github.io/lego/dns/linode/) | [Linode (v4)](https://go-acme.github.io/lego/dns/linodev4/) | +| [Joker](https://go-acme.github.io/lego/dns/joker/) | [Joohoi's ACME-DNS](https://go-acme.github.io/lego/dns/acme-dns/) | [Linode (deprecated)](https://go-acme.github.io/lego/dns/linode/) | [Linode (v4)](https://go-acme.github.io/lego/dns/linodev4/) | | [Liquid Web](https://go-acme.github.io/lego/dns/liquidweb/) | [Manual](https://go-acme.github.io/lego/dns/manual/) | [MyDNS.jp](https://go-acme.github.io/lego/dns/mydnsjp/) | [Name.com](https://go-acme.github.io/lego/dns/namedotcom/) | | [Namecheap](https://go-acme.github.io/lego/dns/namecheap/) | [Namesilo](https://go-acme.github.io/lego/dns/namesilo/) | [Netcup](https://go-acme.github.io/lego/dns/netcup/) | [NIFCloud](https://go-acme.github.io/lego/dns/nifcloud/) | | [NS1](https://go-acme.github.io/lego/dns/ns1/) | [Open Telekom Cloud](https://go-acme.github.io/lego/dns/otc/) | [Oracle Cloud](https://go-acme.github.io/lego/dns/oraclecloud/) | [OVH](https://go-acme.github.io/lego/dns/ovh/) | | [PowerDNS](https://go-acme.github.io/lego/dns/pdns/) | [Rackspace](https://go-acme.github.io/lego/dns/rackspace/) | [RFC2136](https://go-acme.github.io/lego/dns/rfc2136/) | [Sakura Cloud](https://go-acme.github.io/lego/dns/sakuracloud/) | | [Scaleway](https://go-acme.github.io/lego/dns/scaleway/) | [Selectel](https://go-acme.github.io/lego/dns/selectel/) | [Servercow](https://go-acme.github.io/lego/dns/servercow/) | [Stackpath](https://go-acme.github.io/lego/dns/stackpath/) | -| [TransIP](https://go-acme.github.io/lego/dns/transip/) | [VegaDNS](https://go-acme.github.io/lego/dns/vegadns/) | [Vscale](https://go-acme.github.io/lego/dns/vscale/) | [Versio](https://go-acme.github.io/lego/dns/versio/) | +| [TransIP](https://go-acme.github.io/lego/dns/transip/) | [VegaDNS](https://go-acme.github.io/lego/dns/vegadns/) | [Versio.[nl/eu/uk]](https://go-acme.github.io/lego/dns/versio/) | [Vscale](https://go-acme.github.io/lego/dns/vscale/) | | [Vultr](https://go-acme.github.io/lego/dns/vultr/) | [Zone.ee](https://go-acme.github.io/lego/dns/zoneee/) | | | + + diff --git a/internal/dnsdocs/generator.go b/internal/dnsdocs/generator.go index 5158ba60..056ad001 100644 --- a/internal/dnsdocs/generator.go +++ b/internal/dnsdocs/generator.go @@ -3,11 +3,17 @@ package main //go:generate go run . import ( + "bufio" "bytes" + "errors" + "fmt" "go/format" + "io" + "io/ioutil" "log" "os" "path/filepath" + "sort" "strings" "text/template" @@ -21,6 +27,12 @@ const ( cliTemplate = root + "internal/dnsdocs/dns.go.tmpl" cliOutput = root + "cmd/zz_gen_cmd_dnshelp.go" docOutput = root + "docs/content/dns" + readmePath = root + "README.md" +) + +const ( + startLine = "" + endLine = "" ) type Model struct { @@ -63,6 +75,14 @@ func main() { if err != nil { log.Fatal(err) } + + // 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) } func walker(prs *Providers) func(string, os.FileInfo, error) error { @@ -134,3 +154,133 @@ func generateCLIHelp(models *Providers) error { _, err = file.Write(source) return err } + +func generateReadMe(models *Providers) error { + max, lines := extractTableData(models) + + 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) + err = writeDNSTable(buffer, lines, max) + 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") + } + + return ioutil.WriteFile(readmePath, buffer.Bytes(), 0666) +} + +func extractTableData(models *Providers) (int, [][]string) { + readmePattern := "[%s](https://go-acme.github.io/lego/dns/%s/)" + + items := []string{fmt.Sprintf(readmePattern, "Manual", "manual")} + + var max int + + for _, pvd := range models.Providers { + item := fmt.Sprintf(readmePattern, strings.ReplaceAll(pvd.Name, "|", "/"), pvd.Code) + items = append(items, item) + + if max < len(item) { + max = len(item) + } + } + + 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} + + case i == len(models.Providers)-1: + 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) + } + + return max, lines +} + +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 +}