Skip to content

Commit

Permalink
refac: generate Go code to render themes (#39)
Browse files Browse the repository at this point in the history
Fixes #38
  • Loading branch information
matm authored Mar 7, 2023
1 parent a8b740f commit 2b78593
Show file tree
Hide file tree
Showing 12 changed files with 465 additions and 240 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ jobs:
with:
go-version: 1.11

- name: Build code generation tool
run: go build -v ./cmd/generator

- name: Generate code
run: go generate ./...

- name: Build
run: go build -v ./cmd/gocov-html

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/gocov-html
/generator
*.swp
/*.css
// Generated Go files
*_gen.go
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
v 1.3
- refac: generate Go code to render themes. #38
- doc: fix semver in README. #36

v 1.2
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
BIN=gocov-html
MAIN_CMD=github.com/matm/${BIN}/cmd/${BIN}

GENERATOR_BIN=generator
GENERATOR_CMD=github.com/matm/${BIN}/cmd/${GENERATOR_BIN}

include version.mk
include build.mk
5 changes: 4 additions & 1 deletion build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,13 @@ cleardist:
@rm -rf ${DISTDIR} && mkdir -p ${BINDIR} && mkdir -p ${BUILDDIR}

build:
@go build ${GENERATOR_CMD}
@go generate ./...
@go build -ldflags "all=$(GO_LDFLAGS)" ${MAIN_CMD}

test:
@go test ./...

clean:
@rm -rf ${BIN} ${BUILDDIR} ${DISTDIR}
@find pkg -name \*_gen.go -delete
@rm -rf ${BIN} ${GENERATOR_BIN} ${BUILDDIR} ${DISTDIR}
158 changes: 158 additions & 0 deletions cmd/generator/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package main

import (
"bytes"
"fmt"
"go/ast"
"go/parser"
"go/token"
"io/ioutil"
"log"
"os"
"path"
"strings"
"text/template"

"github.com/matm/gocov-html/pkg/types"
)

const tmpl = `// Code generated by "go run generator.go". DO NOT EDIT.
package themes
import (
"text/template"
"time"
"github.com/matm/gocov-html/pkg/types"
)
func (t defaultTheme) Data() *types.TemplateData {
td:= &types.TemplateData{
When: time.Now().Format(time.RFC822Z),
ProjectURL: types.ProjectURL,
}
{{if .Style}}
td.Style = {{.Style}}
{{end}}
{{if .Script}}
td.Script = {{.Script}}
{{end}}
return td
}
func (t defaultTheme) Template() *template.Template {
tmpl := {{.Template}}
p := template.Must(template.New("theme").Parse(tmpl))
return p
}
`

func inspect(name string, theme *string, assets *types.StaticAssets) error {
fset := token.NewFileSet()
token, err := parser.ParseFile(fset, name, nil, parser.ParseComments)
if err != nil {
return err
}
ast.Inspect(token, func(n ast.Node) bool {
fn, ok := n.(*ast.FuncDecl)
if ok {
switch fn.Name.Name {
case "Name":
*theme = fn.Body.List[0].(*ast.ReturnStmt).Results[0].(*ast.BasicLit).Value
*theme = strings.Replace(*theme, `"`, "", -1)
case "Assets":
es := fn.Body.List[0].(*ast.ReturnStmt).Results[0].(*ast.CompositeLit).Elts
for _, e := range es {
kv := e.(*ast.KeyValueExpr)
id := kv.Key.(*ast.Ident)
switch id.Name {
case "Stylesheets":
elems := kv.Value.(*ast.CompositeLit).Elts
for _, elem := range elems {
sheet := elem.(*ast.BasicLit).Value
assets.Stylesheets = append(assets.Stylesheets, strings.Replace(sheet, `"`, "", -1))
}
case "Index":
tmplName := kv.Value.(*ast.BasicLit).Value
assets.Index = strings.Replace(tmplName, `"`, "", -1)
case "Scripts":
elems := kv.Value.(*ast.CompositeLit).Elts
for _, elem := range elems {
script := elem.(*ast.BasicLit).Value
assets.Scripts = append(assets.Scripts, strings.Replace(script, `"`, "", -1))
}
}
}
}
return false
}
return true
})
return nil
}

func render(name, theme string, assets types.StaticAssets) error {
baseThemeDir := path.Join("..", "..", "themes", theme)
out := strings.Replace(name, ".go", "_gen.go", 1)
outFile, err := os.Create(out)
if err != nil {
return err
}
defer outFile.Close()
index, err := ioutil.ReadFile(path.Join(baseThemeDir, assets.Index))
if err != nil {
return err
}
// Contains all stylesheets' data.
var allStyles bytes.Buffer
for _, css := range assets.Stylesheets {
style, err := ioutil.ReadFile(path.Join(baseThemeDir, css))
if err != nil {
return err
}
fmt.Fprintf(&allStyles, "`%s`", style)
}

// Contains all scripts' data.
var allScripts bytes.Buffer
for _, script := range assets.Scripts {
js, err := ioutil.ReadFile(path.Join(baseThemeDir, script))
if err != nil {
return err
}
fmt.Fprintf(&allScripts, "`%s`", js)
}
t, err := template.New("").Parse(tmpl)
if err != nil {
return err
}
type data struct {
Script string
Style string
Template string
}
err = t.Execute(outFile, &data{
Script: allScripts.String(),
Style: allStyles.String(),
Template: "`" + string(index) + "`"},
)
return err
}

func main() {
name := os.Getenv("GOFILE")
if name == "" {
fmt.Println("Must be run by the \"go generate\" tool, like \"go generate ./...\"")
os.Exit(1)
}
assets := new(types.StaticAssets)
theme := new(string)
err := inspect(name, theme, assets)
if err != nil {
log.Fatal(err)
}
if err := render(name, *theme, *assets); err != nil {
log.Fatal(err)
}
}
2 changes: 1 addition & 1 deletion cmd/gocov-html/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func main() {
}

if *showDefaultCSS {
fmt.Println(themes.Current().Data().CSS)
fmt.Println(themes.Current().Data().Style)
return
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/cov/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func printReport(w io.Writer, r *report) error {
theme := themes.Current()
data := theme.Data()

css := data.CSS
css := data.Style
if len(r.stylesheet) > 0 {
// Inline CSS.
f, err := os.Open(r.stylesheet)
Expand All @@ -124,7 +124,7 @@ func printReport(w io.Writer, r *report) error {
reportPackages[i] = buildReportPackage(pkg)
}

data.CSS = css
data.Style = css
data.Packages = reportPackages

if len(reportPackages) > 1 {
Expand Down
Loading

0 comments on commit 2b78593

Please sign in to comment.