From ab3ee4366bd7333d98aaabc67602b6d4432bb4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20K=C3=A1n=C4=9B?= Date: Sun, 25 Apr 2021 15:17:39 +0200 Subject: [PATCH] Embed static files and HTML templates into the binary --- cmd/web/helpers.go | 34 +++++++++++++++++++--------------- cmd/web/main.go | 10 ++++++++-- go.mod | 2 +- go.sum | 3 --- ui/embed.go | 9 +++++++++ 5 files changed, 37 insertions(+), 21 deletions(-) create mode 100644 ui/embed.go diff --git a/cmd/web/helpers.go b/cmd/web/helpers.go index dafa51b..ea7b034 100644 --- a/cmd/web/helpers.go +++ b/cmd/web/helpers.go @@ -8,20 +8,28 @@ import ( "github.com/julienschmidt/httprouter" "html/template" "io" + "io/fs" "net" "net/http" "path/filepath" "runtime/debug" + "strings" "time" "vkane.cz/tinyquiz/pkg/model" "vkane.cz/tinyquiz/pkg/model/ent" "vkane.cz/tinyquiz/pkg/rtcomm" + "vkane.cz/tinyquiz/ui" ) -func newTemplateCache(dir string) (map[string]*template.Template, error) { +func newTemplateCache() (map[string]*template.Template, error) { cache := map[string]*template.Template{} - pages, err := filepath.Glob(filepath.Join(dir, "*.page.tmpl.html")) + templates, err := fs.Sub(ui.HTMLTemplates, "html") + if err != nil { + return nil, err + } + + pages, err := fs.Glob(templates, "*.page.tmpl.html") if err != nil { return nil, err } @@ -29,27 +37,23 @@ func newTemplateCache(dir string) (map[string]*template.Template, error) { for _, page := range pages { name := filepath.Base(page) - ts, err := template.ParseFiles(page) + ts, err := template.ParseFS(templates, page) if err != nil { return nil, err } - if layouts, err := filepath.Glob(filepath.Join(dir, "*.layout.tmpl.html")); err == nil && len(layouts) > 0 { - ts, err = ts.ParseFiles(layouts...) - if err != nil { - return nil, err - } - } else if err != nil { + tsL, err := ts.ParseFS(templates, "*.layout.tmpl.html") + if err != nil && !strings.HasPrefix(err.Error(), "template: pattern matches no files") { return nil, err + } else if err == nil { + ts = tsL } - if partials, err := filepath.Glob(filepath.Join(dir, "*.partial.tmpl.html")); err == nil && len(partials) > 0 { - ts, err = ts.ParseFiles(partials...) - if err != nil { - return nil, err - } - } else if err != nil { + tsP, err := ts.ParseFS(templates, "*.partial.tmpl.html") + if err != nil && !strings.HasPrefix(err.Error(), "template: pattern matches no files") { return nil, err + } else if err == nil { + ts = tsP } cache[name] = ts diff --git a/cmd/web/main.go b/cmd/web/main.go index 4a89a45..119ea6d 100644 --- a/cmd/web/main.go +++ b/cmd/web/main.go @@ -3,6 +3,7 @@ package main import ( "context" "html/template" + "io/fs" "log" "net/http" "net/url" @@ -12,6 +13,7 @@ import ( "vkane.cz/tinyquiz/pkg/model/ent" "vkane.cz/tinyquiz/pkg/model/ent/migrate" rtcomm "vkane.cz/tinyquiz/pkg/rtcomm" + "vkane.cz/tinyquiz/ui" "github.com/julienschmidt/httprouter" _ "github.com/lib/pq" @@ -75,7 +77,7 @@ func main() { rtClients: rtcomm.NewClients(), } - if tc, err := newTemplateCache("./ui/html/"); err == nil { + if tc, err := newTemplateCache(); err == nil { app.templateCache = tc } else { errorLog.Fatal(err) @@ -109,7 +111,11 @@ func main() { mux.GET("/ws/:playerUid", app.processWebSocket) - mux.ServeFiles("/static/*filepath", http.Dir("./ui/static/")) + if static, err := fs.Sub(ui.StaticFiles, "static"); err == nil { + mux.ServeFiles("/static/*filepath", http.FS(static)) + } else { + errorLog.Fatal(err) + } var srv = &http.Server{ Addr: addr, diff --git a/go.mod b/go.mod index 5016753..99f049e 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module vkane.cz/tinyquiz -go 1.14 +go 1.16 require ( entgo.io/ent v0.8.0 diff --git a/go.sum b/go.sum index 0f48c4a..bb09cbe 100644 --- a/go.sum +++ b/go.sum @@ -137,10 +137,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= @@ -367,7 +365,6 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/ui/embed.go b/ui/embed.go new file mode 100644 index 0000000..7153206 --- /dev/null +++ b/ui/embed.go @@ -0,0 +1,9 @@ +package ui + +import "embed" + +//go:embed html/*.tmpl.html +var HTMLTemplates embed.FS + +//go:embed static +var StaticFiles embed.FS