226 lines
4.9 KiB
Go
226 lines
4.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"flag"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
)
|
|
|
|
const (
|
|
pageDir = "content/plugins/"
|
|
)
|
|
|
|
type page struct {
|
|
header meta
|
|
content string
|
|
}
|
|
|
|
type meta struct {
|
|
Title string `toml:"title"`
|
|
Description string `toml:"description"`
|
|
Weight int `toml:"weight"`
|
|
Tags []string `toml:"tags"`
|
|
Categories []string `toml:"categories"`
|
|
Date string `toml:"date"`
|
|
}
|
|
|
|
var (
|
|
pluginDir = flag.String("plugindir", ".coredns/plugin", "directory where to find coredns")
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
// Current pages
|
|
pages, err := getPages(pageDir)
|
|
if err != nil {
|
|
log.Fatalf("Failed getting all page contents: %s", err)
|
|
}
|
|
|
|
// Incoming content
|
|
plugins, err := getContent(*pluginDir)
|
|
if err != nil {
|
|
log.Fatalf("Failed getting all plugin contents: %s", err)
|
|
}
|
|
|
|
neg, pos := compare(plugins, pages)
|
|
|
|
if neg == nil && pos == nil {
|
|
log.Printf("Nothing to update.")
|
|
}
|
|
|
|
// Remove any plugin files not present upstream
|
|
for _, p := range neg {
|
|
path := path.Join(pageDir, p)
|
|
err := os.Remove(path + ".md")
|
|
if err != nil {
|
|
log.Fatalf("Error deleting file file %s: %s", path, err)
|
|
}
|
|
log.Printf("Removed content file: %s", path+".md")
|
|
}
|
|
|
|
// Overwrite/create necessary content files with toml header
|
|
for _, p := range pos {
|
|
h := plugins[p].header
|
|
h.Date = time.Now().UTC().Format("2006-01-02T15:04:05.877581")
|
|
h.Tags = []string{"plugin", h.Title}
|
|
h.Categories = []string{"plugin"}
|
|
|
|
var buf bytes.Buffer
|
|
err := toml.NewEncoder(&buf).Encode(h)
|
|
if err != nil {
|
|
log.Fatalf("Error creating TOML header data: %s", err)
|
|
}
|
|
|
|
headerData := buf.String()
|
|
contentData := plugins[p].content
|
|
filePath := path.Join(pageDir, p)
|
|
fileContent := strings.Join([]string{"", headerData, contentData}, "+++\n")
|
|
err = ioutil.WriteFile(filePath+".md", []byte(fileContent), 0644)
|
|
if err != nil {
|
|
log.Fatalf("Error writing file: %s", err)
|
|
}
|
|
log.Printf("Wrote content changes %s to %s", path.Join(*pluginDir, p, "README.md"), filePath)
|
|
}
|
|
}
|
|
|
|
// Get current content pages from hugo content directory
|
|
// Returned map doesn't include header data as this isn't needed currently
|
|
func getPages(pageDir string) (pages map[string]page, err error) {
|
|
pages = make(map[string]page)
|
|
pd, err := ioutil.ReadDir(pageDir)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, p := range pd {
|
|
if p.IsDir() {
|
|
continue
|
|
}
|
|
|
|
path := path.Join(pageDir, p.Name())
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer file.Close()
|
|
|
|
var content string
|
|
headerSeparator := 0
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
for scanner.Scan() {
|
|
if headerSeparator == 2 {
|
|
content += scanner.Text() + "\n"
|
|
}
|
|
|
|
if scanner.Text() == "+++" {
|
|
headerSeparator++
|
|
}
|
|
}
|
|
pageData := page{content: content}
|
|
pages[strings.Replace(p.Name(), ".md", "", -1)] = pageData
|
|
}
|
|
return pages, nil
|
|
}
|
|
|
|
// Get latest content from coreDNS code directory
|
|
func getContent(pluginDir string) (plugins map[string]page, err error) {
|
|
plugins = make(map[string]page)
|
|
pl, err := ioutil.ReadDir(pluginDir)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
weight := 0
|
|
|
|
for _, p := range pl {
|
|
if !p.IsDir() {
|
|
continue
|
|
}
|
|
if getBlacklist()[p.Name()] {
|
|
continue
|
|
}
|
|
weight++
|
|
|
|
path := path.Join(pluginDir, p.Name(), "README.md")
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer file.Close()
|
|
|
|
var header meta
|
|
var content string
|
|
headerStarted := false
|
|
contentStarted := false
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
for scanner.Scan() {
|
|
if contentStarted {
|
|
content += scanner.Text() + "\n"
|
|
}
|
|
|
|
if headerStarted && scanner.Text() != "" {
|
|
rawHeader := strings.Split(scanner.Text(), " - ")
|
|
title := strings.Replace(rawHeader[0], "*", "", -1)
|
|
header.Title = title
|
|
header.Description = strings.Join([]string{"*", title, "* ", rawHeader[1]}, "")
|
|
header.Weight = weight
|
|
headerStarted = false
|
|
contentStarted = true
|
|
}
|
|
|
|
if scanner.Text() == "## Name" {
|
|
headerStarted = true
|
|
}
|
|
}
|
|
pluginData := page{header: header, content: content}
|
|
plugins[p.Name()] = pluginData
|
|
}
|
|
return plugins, nil
|
|
}
|
|
|
|
// Compare current and incoming state
|
|
// Return a negative list to delete
|
|
// Return a positive list to create/overwrite
|
|
func compare(plugins map[string]page, pages map[string]page) (neg []string, pos []string) {
|
|
// Prepare list of pages to delete
|
|
for k := range pages {
|
|
if _, ok := plugins[k]; !ok {
|
|
neg = append(neg, k)
|
|
}
|
|
}
|
|
|
|
// Prepare list of pages to create
|
|
for k := range plugins {
|
|
// New pages to create
|
|
if _, ok := pages[k]; !ok {
|
|
pos = append(pos, k)
|
|
}
|
|
|
|
// Check necessity for an update
|
|
if plugins[k].content != pages[k].content {
|
|
pos = append(pos, k)
|
|
}
|
|
}
|
|
return neg, pos
|
|
}
|
|
|
|
// Return directory blacklist
|
|
func getBlacklist() map[string]bool {
|
|
var bl = map[string]bool{
|
|
"test": true,
|
|
"pkg": true,
|
|
"deprecated": true,
|
|
}
|
|
return bl
|
|
}
|