summaryrefslogtreecommitdiffstats
path: root/hugolib
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2023-05-21 14:25:16 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2023-05-22 14:14:35 +0200
commit2c3d4dfb745799b5de11f9ec0463a4ace19e97de (patch)
tree22f8dfe5b6f0bd39d66757119c2ea2ce5f83743d /hugolib
parent1292d5a26af55ffd22512a01ae3a82c769e9bb01 (diff)
Add cache busting config to support Tailwind 3
Fixes #10974
Diffstat (limited to 'hugolib')
-rw-r--r--hugolib/alias.go2
-rw-r--r--hugolib/filesystems/basefs.go25
-rw-r--r--hugolib/hugo_sites_build_test.go3
-rw-r--r--hugolib/site.go62
4 files changed, 50 insertions, 42 deletions
diff --git a/hugolib/alias.go b/hugolib/alias.go
index 1bc0e5424..d10f140bd 100644
--- a/hugolib/alias.go
+++ b/hugolib/alias.go
@@ -82,8 +82,6 @@ func (s *Site) writeDestAlias(path, permalink string, outputFormat output.Format
func (s *Site) publishDestAlias(allowRoot bool, path, permalink string, outputFormat output.Format, p page.Page) (err error) {
handler := newAliasHandler(s.Tmpl(), s.Log, allowRoot)
- s.Log.Debugln("creating alias:", path, "redirecting to", permalink)
-
targetPath, err := handler.targetPathAlias(path)
if err != nil {
return err
diff --git a/hugolib/filesystems/basefs.go b/hugolib/filesystems/basefs.go
index b90111e26..ed0d36de1 100644
--- a/hugolib/filesystems/basefs.go
+++ b/hugolib/filesystems/basefs.go
@@ -76,6 +76,8 @@ type BaseFs struct {
theBigFs *filesystemsCollector
+ workingDir string
+
// Locks.
buildMu Lockable // <project>/.hugo_build.lock
}
@@ -201,6 +203,27 @@ func (fs *BaseFs) ResolveJSConfigFile(name string) string {
return ""
}
+// MakePathRelative creates a relative path from the given filename.
+// It returns both the component name (e.g. layouts) and the path relative to that.
+func (fs *BaseFs) MakePathRelative(filename string) (string, string) {
+ for _, sfs := range fs.FileSystems() {
+ if sfs.Contains(filename) {
+ if s, found := sfs.MakePathRelative(filename); found {
+ return sfs.Name, s
+ }
+ }
+ }
+ // May be a static file.
+ if s := fs.MakeStaticPathRelative(filename); s != "" {
+ return files.ComponentFolderStatic, s
+ }
+ // Fall back to relative to the working dir.
+ if strings.HasPrefix(filename, fs.workingDir) {
+ return "", strings.TrimPrefix(filename, fs.workingDir)
+ }
+ return "", ""
+}
+
// SourceFilesystems contains the different source file systems. These can be
// composite file systems (theme and project etc.), and they have all root
// set to the source type the provides: data, i18n, static, layouts.
@@ -235,6 +258,7 @@ type SourceFilesystems struct {
func (s *SourceFilesystems) FileSystems() []*SourceFilesystem {
return []*SourceFilesystem{
s.Content,
+ s.Assets,
s.Data,
s.I18n,
s.Layouts,
@@ -466,6 +490,7 @@ func NewBase(p *paths.Paths, logger loggers.Logger, options ...func(*BaseFs) err
WorkDir: fs.WorkingDirReadOnly,
PublishFs: publishFs,
PublishFsStatic: publishFsStatic,
+ workingDir: p.Cfg.BaseConfig().WorkingDir,
buildMu: buildMu,
}
diff --git a/hugolib/hugo_sites_build_test.go b/hugolib/hugo_sites_build_test.go
index 7b884515c..b2798c863 100644
--- a/hugolib/hugo_sites_build_test.go
+++ b/hugolib/hugo_sites_build_test.go
@@ -8,6 +8,7 @@ import (
"time"
qt "github.com/frankban/quicktest"
+ "github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/htesting"
"github.com/gohugoio/hugo/resources/page"
@@ -1393,7 +1394,7 @@ other = %q
}
func TestRebuildOnAssetChange(t *testing.T) {
- b := newTestSitesBuilder(t).Running()
+ b := newTestSitesBuilder(t).Running().WithLogger(loggers.NewInfoLogger())
b.WithTemplatesAdded("index.html", `
{{ (resources.Get "data.json").Content }}
`)
diff --git a/hugolib/site.go b/hugolib/site.go
index 301d66dac..8e220f633 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -22,7 +22,6 @@ import (
"net/url"
"path"
"path/filepath"
- "regexp"
"runtime"
"sort"
"strings"
@@ -36,8 +35,6 @@ import (
"github.com/gohugoio/hugo/common/paths"
- "github.com/gohugoio/hugo/resources"
-
"github.com/gohugoio/hugo/identity"
"github.com/gohugoio/hugo/markup/converter/hooks"
@@ -45,6 +42,7 @@ import (
"github.com/gohugoio/hugo/markup/converter"
"github.com/gohugoio/hugo/hugofs/files"
+ hglob "github.com/gohugoio/hugo/hugofs/glob"
"github.com/gohugoio/hugo/common/maps"
@@ -483,16 +481,6 @@ func (s *Site) translateFileEvents(events []fsnotify.Event) []fsnotify.Event {
return filtered
}
-var (
- // These are only used for cache busting, so false positives are fine.
- // We also deliberately do not match for file suffixes to also catch
- // directory names.
- // TODO(bep) consider this when completing the relevant PR rewrite on this.
- cssFileRe = regexp.MustCompile("(css|sass|scss)")
- cssConfigRe = regexp.MustCompile(`(postcss|tailwind)\.config\.js`)
- jsFileRe = regexp.MustCompile("(js|ts|jsx|tsx)")
-)
-
// reBuild partially rebuilds a site given the filesystem events.
// It returns whatever the content source was changed.
// TODO(bep) clean up/rewrite this method.
@@ -524,24 +512,16 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
logger = helpers.NewDistinctErrorLogger()
)
- var cachePartitions []string
- // Special case
- // TODO(bep) I have a ongoing branch where I have redone the cache. Consider this there.
- var (
- evictCSSRe *regexp.Regexp
- evictJSRe *regexp.Regexp
- )
+ var cacheBusters []func(string) bool
+ bcfg := s.conf.Build
for _, ev := range events {
- if assetsFilename, _ := s.BaseFs.Assets.MakePathRelative(ev.Name); assetsFilename != "" {
- cachePartitions = append(cachePartitions, resources.ResourceKeyPartitions(assetsFilename)...)
- if evictCSSRe == nil {
- if cssFileRe.MatchString(assetsFilename) || cssConfigRe.MatchString(assetsFilename) {
- evictCSSRe = cssFileRe
- }
- }
- if evictJSRe == nil && jsFileRe.MatchString(assetsFilename) {
- evictJSRe = jsFileRe
+ component, relFilename := s.BaseFs.MakePathRelative(ev.Name)
+ if relFilename != "" {
+ p := hglob.NormalizePath(path.Join(component, relFilename))
+ g, err := bcfg.MatchCacheBuster(s.Log, p)
+ if err == nil && g != nil {
+ cacheBusters = append(cacheBusters, g)
}
}
@@ -586,17 +566,23 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
return err
}
- // These in memory resource caches will be rebuilt on demand.
- for _, s := range s.h.Sites {
- s.ResourceSpec.ResourceCache.DeletePartitions(cachePartitions...)
- if evictCSSRe != nil {
- s.ResourceSpec.ResourceCache.DeleteMatches(evictCSSRe)
- }
- if evictJSRe != nil {
- s.ResourceSpec.ResourceCache.DeleteMatches(evictJSRe)
+ var cacheBusterOr func(string) bool
+ if len(cacheBusters) > 0 {
+ cacheBusterOr = func(s string) bool {
+ for _, cb := range cacheBusters {
+ if cb(s) {
+ return true
+ }
+ }
+ return false
}
}
+ // These in memory resource caches will be rebuilt on demand.
+ if len(cacheBusters) > 0 {
+ s.h.ResourceSpec.ResourceCache.DeleteMatches(cacheBusterOr)
+ }
+
if tmplChanged || i18nChanged {
s.h.init.Reset()
var prototype *deps.Deps
@@ -1024,7 +1010,6 @@ func (s *Site) lookupLayouts(layouts ...string) tpl.Template {
}
func (s *Site) renderAndWriteXML(ctx context.Context, statCounter *uint64, name string, targetPath string, d any, templ tpl.Template) error {
- s.Log.Debugf("Render XML for %q to %q", name, targetPath)
renderBuffer := bp.GetBuffer()
defer bp.PutBuffer(renderBuffer)
@@ -1046,7 +1031,6 @@ func (s *Site) renderAndWriteXML(ctx context.Context, statCounter *uint64, name
}
func (s *Site) renderAndWritePage(statCounter *uint64, name string, targetPath string, p *pageState, templ tpl.Template) error {
- s.Log.Debugf("Render %s to %q", name, targetPath)
s.h.IncrPageRender()
renderBuffer := bp.GetBuffer()
defer bp.PutBuffer(renderBuffer)