mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-30 22:39:58 +02:00
@@ -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
|
||||
|
@@ -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,
|
||||
}
|
||||
|
||||
|
@@ -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 }}
|
||||
`)
|
||||
|
@@ -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,15 +566,21 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
|
||||
return err
|
||||
}
|
||||
|
||||
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.
|
||||
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)
|
||||
}
|
||||
if len(cacheBusters) > 0 {
|
||||
s.h.ResourceSpec.ResourceCache.DeleteMatches(cacheBusterOr)
|
||||
}
|
||||
|
||||
if tmplChanged || i18nChanged {
|
||||
@@ -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)
|
||||
|
Reference in New Issue
Block a user