all repos — vite @ f6f93aecaa1e0e8b1927d84656a0011dc73c6402

a fast (this time, actually) and minimal static site generator

build.go (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
package main

import (
	"fmt"
	"github.com/cross-cpm/go-shutil"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"text/template"
)

var cfg = parseConfig()

func execute(cmds []string) {
	for _, cmd := range cmds {
		out, err := exec.Command(cmd).Output()
		printMsg("running:", cmd)
		if err != nil {
			printErr(err)
			fmt.Println(string(out))
		}
	}
}

func processTemplate(tmplPath string) *template.Template {
	tmplFile := filepath.Join("templates", tmplPath)
	tmpl, err := template.ParseFiles(tmplFile)
	if err != nil {
		printErr(err)
	}

	return tmpl
}

func handleMd(mdPath string) {
	content, err := ioutil.ReadFile(mdPath)
	if err != nil {
		printErr(err)
	}

	restContent, fm := parseFrontmatter(content)
	bodyHtml := mdRender(restContent)
	relPath, _ := filepath.Rel("pages/", mdPath)

	var buildPath string
	if strings.HasSuffix(relPath, "_index.md") {
		dir, _ := filepath.Split(relPath)
		buildPath = filepath.Join("build", dir)
	} else {
		buildPath = filepath.Join(
			"build",
			strings.TrimSuffix(relPath, filepath.Ext(relPath)),
		)
	}

	os.MkdirAll(buildPath, 0755)

	fm.Body = string(bodyHtml)

	// combine config and matter structs
	combined := struct {
		Cfg Config
		Fm  Matter
	}{cfg, fm}

	htmlFile, err := os.Create(filepath.Join(buildPath, "index.html"))
	if err != nil {
		printErr(err)
		return
	}
	if fm.Template == "" {
		fm.Template = "text.html"
	}
	tmpl := processTemplate(fm.Template)
	err = tmpl.Execute(htmlFile, combined)
	if err != nil {
		printErr(err)
		return
	}
	htmlFile.Close()
}

func viteBuild() {
	printMsg("executing pre-build actions...")
	execute(cfg.Prebuild)
	err := filepath.Walk("./pages", func(path string, info os.FileInfo, err error) error {
		if err != nil {
			printErr(err)
			return err
		}
		if filepath.Ext(path) == ".md" {
			handleMd(path)
		} else {
			f, err := os.Stat(path)
			if err != nil {
				printErr(err)
			}
			mode := f.Mode()
			if mode.IsRegular() {
				options := shutil.CopyOptions{}
				relPath, _ := filepath.Rel("pages/", path)
				options.FollowSymlinks = true
				shutil.CopyFile(
					path,
					filepath.Join("build", relPath),
					&options,
				)
			}
		}
		return nil
	})
	if err != nil {
		printErr(err)
	}

	_, err = shutil.CopyTree("static", filepath.Join("build", "static"), nil)
	if err != nil {
		printErr(err)
	}
	printMsg("site build complete")
	printMsg("executing post-build actions...")
	execute(cfg.Postbuild)
}