From 09c09ac44d8bc1753938dd04b6519bb2c2db7bcd Mon Sep 17 00:00:00 2001 From: Jakob Steiner Date: Wed, 20 Mar 2024 14:49:27 +0100 Subject: [PATCH] chore(ui): add reloading templates after changes in dev mode (#170) Signed-off-by: Jakob Steiner --- go.mod | 2 +- internal/web/server.go | 22 ++++++++++++++++++++-- internal/web/templates.go | 34 ++++++++++++++++++++++++++-------- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index d82063945..ed04cbfdd 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/fatih/color v1.16.0 github.com/fluxcd/helm-controller/api v0.37.4 github.com/fluxcd/source-controller/api v1.2.4 + github.com/fsnotify/fsnotify v1.7.0 github.com/go-logr/logr v1.4.1 github.com/google/go-containerregistry v0.19.1 github.com/gorilla/mux v1.8.1 @@ -38,7 +39,6 @@ require ( github.com/fluxcd/pkg/apis/acl v0.1.0 // indirect github.com/fluxcd/pkg/apis/kustomize v1.3.0 // indirect github.com/fluxcd/pkg/apis/meta v1.3.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect diff --git a/internal/web/server.go b/internal/web/server.go index c15067946..4062ff33b 100644 --- a/internal/web/server.go +++ b/internal/web/server.go @@ -14,6 +14,7 @@ import ( "strings" "syscall" + "github.com/glasskube/glasskube/internal/config" "github.com/glasskube/glasskube/internal/controller/owners" "github.com/glasskube/glasskube/internal/dependency" "github.com/glasskube/glasskube/internal/dependency/adapter/goclient" @@ -49,7 +50,17 @@ import ( //go:embed root //go:embed templates -var embededFs embed.FS +var embeddedFs embed.FS +var webFs fs.FS = embeddedFs + +func init() { + if config.IsDevBuild() { + if _, err := os.Lstat(templatesBaseDir); err == nil { + fmt.Println("using DirFS") + webFs = os.DirFS(templatesBaseDir) + } + } +} type ServerOptions struct { Host string @@ -135,7 +146,14 @@ func (s *server) Start(ctx context.Context) error { s.startInformer(ctx) } - root, err := fs.Sub(embededFs, "root") + if config.IsDevBuild() { + if err := watchTemplates(); err != nil { + fmt.Fprintf(os.Stderr, "templates will not be parsed after changes: %v\n", err) + } + } + parseTemplates() + + root, err := fs.Sub(webFs, "root") if err != nil { return err } diff --git a/internal/web/templates.go b/internal/web/templates.go index 8d772b261..b18089417 100644 --- a/internal/web/templates.go +++ b/internal/web/templates.go @@ -6,15 +6,14 @@ import ( "os" "path" - "github.com/glasskube/glasskube/internal/web/components/alert" - + "github.com/fsnotify/fsnotify" "github.com/glasskube/glasskube/api/v1alpha1" - "github.com/glasskube/glasskube/internal/repo" - + "github.com/glasskube/glasskube/internal/web/components/alert" "github.com/glasskube/glasskube/internal/web/components/pkg_detail_btns" "github.com/glasskube/glasskube/internal/web/components/pkg_overview_btn" "github.com/glasskube/glasskube/internal/web/components/pkg_update_alert" + "go.uber.org/multierr" ) var ( @@ -30,12 +29,31 @@ var ( pkgUpdateModalTmpl *template.Template pkgUpdateAlertTmpl *template.Template alertTmpl *template.Template + templatesBaseDir = "internal/web" templatesDir = "templates" componentsDir = path.Join(templatesDir, "components") pagesDir = path.Join(templatesDir, "pages") ) -func init() { +func watchTemplates() error { + watcher, err := fsnotify.NewWatcher() + err = multierr.Combine( + err, + watcher.Add(path.Join(templatesBaseDir, componentsDir)), + watcher.Add(path.Join(templatesBaseDir, templatesDir, "layout")), + watcher.Add(path.Join(templatesBaseDir, pagesDir)), + ) + if err == nil { + go func() { + for range watcher.Events { + parseTemplates() + } + }() + } + return err +} + +func parseTemplates() { templateFuncs := template.FuncMap{ "ForPkgOverviewBtn": pkg_overview_btn.ForPkgOverviewBtn, "ForPkgDetailBtns": pkg_detail_btns.ForPkgDetailBtns, @@ -57,7 +75,7 @@ func init() { } baseTemplate = template.Must(template.New("base.html"). Funcs(templateFuncs). - ParseFS(embededFs, path.Join(templatesDir, "layout", "base.html"))) + ParseFS(webFs, path.Join(templatesDir, "layout", "base.html"))) pkgsPageTmpl = pageTmpl("packages.html") pkgPageTmpl = pageTmpl("package.html") supportPageTmpl = pageTmpl("support.html") @@ -74,7 +92,7 @@ func init() { func pageTmpl(fileName string) *template.Template { return template.Must( template.Must(baseTemplate.Clone()).ParseFS( - embededFs, + webFs, path.Join(pagesDir, fileName), path.Join(componentsDir, "*.html"))) } @@ -82,7 +100,7 @@ func pageTmpl(fileName string) *template.Template { func componentTmpl(id string, fileName string) *template.Template { return template.Must( template.New(id).ParseFS( - embededFs, + webFs, path.Join(componentsDir, fileName))) }