Browse Source

Migrate to Go1.16 embed (drop rice)

pull/3/head
James Mills 3 months ago
parent
commit
1f532ecd46
Signed by: prologic GPG Key ID: AC4C014F1440EBD6
  1. 2
      .dockerignore
  2. 3
      Makefile
  3. 2
      go.mod
  4. 10
      go.sum
  5. 20
      internal/handlers.go
  6. 5
      internal/router.go
  7. 36
      internal/server.go
  8. 70
      internal/templates.go

2
.dockerignore

@ -13,5 +13,3 @@ Dockerfile
/cmd/yarns/yarns
/data/cache
/internal/rice-box.go

3
Makefile

@ -27,12 +27,9 @@ build: server
generate:
@if [ x"$(DEBUG)" = x"1" ]; then \
echo 'Running in debug mode...'; \
rm -f -v ./internal/rice-box.go; \
else \
minify -b -o ./internal/static/css/yarns.min.css ./internal/static/css/[0-9]*-*.css; \
minify -b -o ./internal/static/js/yarns.min.js ./internal/static/js/[0-9]*-*.js; \
rm -f ./internal/rice-box.go; \
rice -i ./internal embed-go; \
fi
install: build

2
go.mod

@ -6,7 +6,6 @@ require (
git.mills.io/prologic/bitcask v1.0.0
git.mills.io/prologic/observe v0.0.0-20210712230028-fc31c7aa2bd1
git.mills.io/yarnsocial/yarn v0.0.0-20210907161233-11a3c9b00df2
github.com/GeertJohan/go.rice v1.0.2
github.com/Masterminds/sprig v2.22.0+incompatible
github.com/NYTimes/gziphandler v1.1.1
github.com/andreadipersio/securecookie v0.0.0-20131119095127-e3c3b33544ec
@ -66,7 +65,6 @@ require (
github.com/blevesearch/zapx/v14 v14.2.2 // indirect
github.com/blevesearch/zapx/v15 v15.2.2 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/daaku/go.zipexe v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.12.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect

10
go.sum

@ -52,9 +52,6 @@ git.mills.io/yarnsocial/yarn v0.0.0-20210907161233-11a3c9b00df2/go.mod h1:l8G8lQ
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k=
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
github.com/GeertJohan/go.rice v1.0.2 h1:PtRw+Tg3oa3HYwiDBZyvOJ8LdIyf6lAovJJtr7YOAYk=
github.com/GeertJohan/go.rice v1.0.2/go.mod h1:af5vUNlDNkCjOZeSGFgIJxDje9qdjsO6hshx0gTmZt4=
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
@ -83,7 +80,6 @@ github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81 h1:uHogIJ9bXH75ZYrXnVShH
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81/go.mod h1:6ZvnjTZX1LNo1oLpfaJK8h+MXqHxcBFBIwkgsv+xlv0=
github.com/abusizhishen/read-file-last-line v0.0.0-20200717025516-5bf8361f20a5/go.mod h1:5TeKRpTU7IS2HxGPDRGIkecjowjzTIagFB3ROmwKsFE=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -201,8 +197,6 @@ github.com/creasty/defaults v1.5.1/go.mod h1:FPZ+Y0WNrbqOVw+c6av63eyHUAl6pMHZwqL
github.com/creasty/defaults v1.5.2 h1:/VfB6uxpyp6h0fr7SPp7n8WJBoV8jfxQXPCnkVSjyls=
github.com/creasty/defaults v1.5.2/go.mod h1:FPZ+Y0WNrbqOVw+c6av63eyHUAl6pMHZwqLPvXUZGfY=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY=
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -430,7 +424,6 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod
github.com/james4k/fmatter v0.0.0-20150827042251-377c8ea6259d h1:+j8+Mdui1SE9TchF4Oxne37OWOYaLG91xFzLWehKPqE=
github.com/james4k/fmatter v0.0.0-20150827042251-377c8ea6259d/go.mod h1:lxdGBh4Mr76rBen37GEal03CF0eF1qF5DSk2qfrrdo0=
github.com/jawher/mow.cli v1.1.0/go.mod h1:aNaQlc7ozF3vw6IJ2dHjp2ZFiA4ozMIYY6PyuRJwlUg=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
@ -542,7 +535,6 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nicksnyder/go-i18n/v2 v2.1.2/go.mod h1:d++QJC9ZVf7pa48qrsRWhMJ5pSHIPmS3OLqK1niyLxs=
github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc=
github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022/go.mod h1:x4NsS+uc7ecH/Cbm9xKQ6XzmJM57rWTkjywjfB2yQ18=
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
@ -725,8 +717,6 @@ github.com/unrolled/logger v0.0.0-20201216141554-31a3694fe979 h1:47+K4wN0S8L3fUw
github.com/unrolled/logger v0.0.0-20201216141554-31a3694fe979/go.mod h1:X5DBNY1yIVkuLwJP3BXlCoQCa5mGg7hPJPIA0Blwc44=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/vcraescu/go-paginator v1.0.0 h1:ilNmRhlgG8N44LuxfGoPI2u8guXMA6gUqaPGA5BmRFs=
github.com/vcraescu/go-paginator v1.0.0/go.mod h1:caZCjjt2qcA1O2aDzW7lwAcK4Rxw3LNvdEVF/ONxZWw=
github.com/wblakecaldwell/profiler v0.0.0-20150908040756-6111ef1313a1 h1:Dz/PRieZRmOhDfOlkVpY1LYYIfNoTJjlDirAlagOr0s=

20
internal/handlers.go

@ -1,13 +1,13 @@
package internal
import (
"embed"
"fmt"
"html/template"
"net/http"
"strings"
"time"
rice "github.com/GeertJohan/go.rice"
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser"
@ -21,6 +21,9 @@ const (
MaxFailedLogins = 3 // By default 3 failed login attempts per 5 minutes
)
//go:embed pages/*.md
var pages embed.FS
func (s *Server) NotFoundHandler(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Accept") == "application/json" {
w.Header().Set("Content-Type", "application/json")
@ -40,17 +43,22 @@ type FrontMatter struct {
// PageHandler ...
func (s *Server) PageHandler(name string) httprouter.Handle {
box := rice.MustFindBox("pages")
mdTpl := box.MustString(fmt.Sprintf("%s.md", name))
var mdTpl string
if b, err := pages.ReadFile(fmt.Sprintf("pages/%s.md", name)); err == nil {
mdTpl = string(b)
} else {
log.WithError(err).Errorf("error finding page %s", name)
panic(err)
}
return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
ctx := NewContext(s.config, s.db, r)
md, err := RenderString(mdTpl, ctx)
md, err := RenderHTML(mdTpl, ctx)
if err != nil {
log.WithError(err).Errorf("error rendering page %s", name)
ctx.Error = true
ctx.Message = "Error loading help page! Please contact support."
ctx.Message = "Error rendering page"
s.render("error", w, ctx)
return
}
@ -60,7 +68,7 @@ func (s *Server) PageHandler(name string) httprouter.Handle {
if err != nil {
log.WithError(err).Error("error parsing front matter")
ctx.Error = true
ctx.Message = "Error loading page! Please contact support."
ctx.Message = "Error parsing apge frontmatter"
s.render("error", w, ctx)
return
}

5
internal/router.go

@ -1,6 +1,7 @@
package internal
import (
"io/fs"
"net/http"
"github.com/julienschmidt/httprouter"
@ -136,12 +137,12 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
// ServeFilesWithCacheControl ...
func (r *Router) ServeFilesWithCacheControl(path string, root http.FileSystem) {
func (r *Router) ServeFilesWithCacheControl(path string, root fs.FS) {
if len(path) < 10 || path[len(path)-10:] != "/*filepath" {
panic("path must end with /*filepath in path '" + path + "'")
}
fileServer := http.FileServer(root)
fileServer := http.FileServer(http.FS(root))
r.GET(path, func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
w.Header().Set("Vary", "Accept-Encoding")

36
internal/server.go

@ -2,7 +2,9 @@ package internal
import (
"context"
"embed"
"fmt"
"io/fs"
"net/http"
"os"
"os/signal"
@ -11,7 +13,6 @@ import (
"time"
"git.mills.io/prologic/observe"
rice "github.com/GeertJohan/go.rice"
"github.com/NYTimes/gziphandler"
"github.com/gabstv/merger"
"github.com/justinas/nosurf"
@ -25,6 +26,15 @@ import (
var (
metrics *observe.Metrics
//go:embed static/css
staticCSS embed.FS
//go:embed static/js
staticJS embed.FS
//go:embed static/img
staticIMG embed.FS
)
func init() {
@ -276,12 +286,24 @@ func (s *Server) initRoutes() {
s.router.ServeFiles("/img/*filepath", http.Dir("./internal/static/img"))
s.router.ServeFiles("/js/*filepath", http.Dir("./internal/static/js"))
} else {
cssBox := rice.MustFindBox("static/css").HTTPBox()
imgBox := rice.MustFindBox("static/img").HTTPBox()
jsBox := rice.MustFindBox("static/js").HTTPBox()
s.router.ServeFilesWithCacheControl("/css/:commit/*filepath", cssBox)
s.router.ServeFilesWithCacheControl("/img/:commit/*filepath", imgBox)
s.router.ServeFilesWithCacheControl("/js/:commit/*filepath", jsBox)
cssFS, err := fs.Sub(staticCSS, "static/css")
if err != nil {
log.Fatal("error getting SubFS for static/css")
}
jsFS, err := fs.Sub(staticJS, "static/js")
if err != nil {
log.Fatal("error getting SubFS for static/js")
}
imgFS, err := fs.Sub(staticIMG, "static/img")
if err != nil {
log.Fatal("error getting SubFS for static/img")
}
s.router.ServeFilesWithCacheControl("/css/:commit/*filepath", cssFS)
s.router.ServeFilesWithCacheControl("/img/:commit/*filepath", imgFS)
s.router.ServeFilesWithCacheControl("/js/:commit/*filepath", jsFS)
}
s.router.NotFound = http.HandlerFunc(s.NotFoundHandler)

70
internal/templates.go

@ -2,27 +2,30 @@ package internal
import (
"bytes"
"embed"
"fmt"
"html/template"
"io"
"os"
"io/fs"
"path/filepath"
"strings"
"sync"
text_template "text/template"
rice "github.com/GeertJohan/go.rice"
"github.com/Masterminds/sprig"
humanize "github.com/dustin/go-humanize"
log "github.com/sirupsen/logrus"
)
const (
templatesPath = "templates"
baseTemplate = "base.html"
partialsTemplate = "_partials.html"
baseTemplate = "templates/base.html"
partialsTemplate = "templates/_partials.html"
baseName = "base"
)
//go:embed templates/*.html
var templates embed.FS
type TemplateManager struct {
sync.RWMutex
@ -57,20 +60,14 @@ func (m *TemplateManager) LoadTemplates() error {
m.Lock()
defer m.Unlock()
box, err := rice.FindBox("templates")
if err != nil {
log.WithError(err).Errorf("error finding templates")
return fmt.Errorf("error finding templates: %w", err)
}
err = box.Walk("", func(path string, info os.FileInfo, err error) error {
err := fs.WalkDir(templates, "templates", func(path string, info fs.DirEntry, err error) error {
if err != nil {
log.WithError(err).Error("error talking templates")
log.WithError(err).Error("error walking templates")
return fmt.Errorf("error walking templates: %w", err)
}
fname := info.Name()
if !info.IsDir() && fname != baseTemplate {
if !info.IsDir() && path != baseTemplate {
// Skip _partials.html and also editor swap files, to improve the development
// cycle. Editors often add suffixes to their swap files, e.g "~" or ".swp"
// (Vim) and those files are not parsable as templates, causing panics.
@ -82,9 +79,23 @@ func (m *TemplateManager) LoadTemplates() error {
t := template.New(name).Option("missingkey=zero")
t.Funcs(m.funcMap)
template.Must(t.Parse(box.MustString(fname)))
template.Must(t.Parse(box.MustString(partialsTemplate)))
template.Must(t.Parse(box.MustString(baseTemplate)))
if f, err := templates.ReadFile(path); err == nil {
template.Must(t.Parse(string(f)))
} else {
return err
}
if f, err := templates.ReadFile(partialsTemplate); err == nil {
template.Must(t.Parse(string(f)))
} else {
return err
}
if f, err := templates.ReadFile(baseTemplate); err == nil {
template.Must(t.Parse(string(f)))
} else {
return err
}
m.templates[name] = t
}
@ -94,7 +105,6 @@ func (m *TemplateManager) LoadTemplates() error {
log.WithError(err).Error("error loading templates")
return fmt.Errorf("error loading templates: %w", err)
}
return nil
}
@ -136,3 +146,27 @@ func (m *TemplateManager) Exec(name string, ctx *Context) (io.WriterTo, error) {
return buf, nil
}
// RenderHTML ...
func RenderHTML(tpl string, ctx *Context) (string, error) {
t := template.Must(template.New("tpl").Parse(tpl))
buf := bytes.NewBuffer([]byte{})
err := t.Execute(buf, ctx)
if err != nil {
return "", err
}
return buf.String(), nil
}
// RenderPlainText ...
func RenderPlainText(tpl string, ctx *Context) (string, error) {
t := text_template.Must(text_template.New("tpl").Parse(tpl))
buf := bytes.NewBuffer([]byte{})
err := t.Execute(buf, ctx)
if err != nil {
return "", err
}
return buf.String(), nil
}

Loading…
Cancel
Save