aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <[email protected]>2024-11-03 10:41:34 +0100
committerBjørn Erik Pedersen <[email protected]>2024-11-03 13:33:31 +0100
commit30d9aea8607e8143968d73d11a8c1c0e51d34343 (patch)
tree7e1be54881670eb402de1007f6b7bdf7e4ae3506
parent1f23b4949c70a2a8f2084fa937e19e93a9fe890a (diff)
downloadhugo-30d9aea8607e8143968d73d11a8c1c0e51d34343.tar.gz
hugo-30d9aea8607e8143968d73d11a8c1c0e51d34343.zip
Fix stale pages on rebuilds in GetPage with short refs
Fixes #13004
-rw-r--r--hugolib/content_map_page.go12
-rw-r--r--hugolib/rendershortcodes_test.go35
-rw-r--r--hugolib/site.go1
-rw-r--r--lazy/init.go2
-rw-r--r--lazy/once.go12
5 files changed, 51 insertions, 11 deletions
diff --git a/hugolib/content_map_page.go b/hugolib/content_map_page.go
index c3f06a592..5e8646b21 100644
--- a/hugolib/content_map_page.go
+++ b/hugolib/content_map_page.go
@@ -37,6 +37,7 @@ import (
"github.com/gohugoio/hugo/hugolib/doctree"
"github.com/gohugoio/hugo/hugolib/pagesfromdata"
"github.com/gohugoio/hugo/identity"
+ "github.com/gohugoio/hugo/lazy"
"github.com/gohugoio/hugo/media"
"github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/resources"
@@ -109,6 +110,11 @@ type pageMap struct {
cfg contentMapConfig
}
+// Invoked on rebuilds.
+func (m *pageMap) Reset() {
+ m.pageReverseIndex.Reset()
+}
+
// pageTrees holds pages and resources in a tree structure for all sites/languages.
// Each site gets its own tree set via the Shape method.
type pageTrees struct {
@@ -958,9 +964,7 @@ type contentTreeReverseIndex struct {
}
func (c *contentTreeReverseIndex) Reset() {
- c.contentTreeReverseIndexMap = &contentTreeReverseIndexMap{
- m: make(map[any]contentNodeI),
- }
+ c.init.ResetWithLock().Unlock()
}
func (c *contentTreeReverseIndex) Get(key any) contentNodeI {
@@ -972,7 +976,7 @@ func (c *contentTreeReverseIndex) Get(key any) contentNodeI {
}
type contentTreeReverseIndexMap struct {
- init sync.Once
+ init lazy.OnceMore
m map[any]contentNodeI
}
diff --git a/hugolib/rendershortcodes_test.go b/hugolib/rendershortcodes_test.go
index 9a31b6536..0eebf46eb 100644
--- a/hugolib/rendershortcodes_test.go
+++ b/hugolib/rendershortcodes_test.go
@@ -445,3 +445,38 @@ code_p3
b.AssertNoRenderShortcodesArtifacts()
b.AssertFileContentEquals("public/p1/index.html", "<p>Content p1 id-100.</p>\n<code>codep2</code><p>Foo.\n</p>\n<code>code_p3_edited</code><p></p>\n<code>code_p1</code><code>code_p1_2</code><code>code_p1_3</code>")
}
+
+// Issue 13004.
+func TestRenderShortcodesIncludeShortRefEdit(t *testing.T) {
+ t.Parallel()
+
+ files := `
+-- hugo.toml --
+disableLiveReload = true
+disableKinds = ["home", "taxonomy", "term", "section", "rss", "sitemap", "robotsTXT", "404"]
+-- content/first/p1.md --
+---
+title: "p1"
+---
+## p1-h1
+{{% include "p2" %}}
+-- content/second/p2.md --
+---
+title: "p2"
+---
+### p2-h1
+
+This is some **markup**.
+-- layouts/shortcodes/include.html --
+{{ $p := site.GetPage (.Get 0) -}}
+{{ $p.RenderShortcodes -}}
+-- layouts/_default/single.html --
+{{ .Content }}
+`
+ b := TestRunning(t, files)
+ b.AssertNoRenderShortcodesArtifacts()
+ b.AssertFileContentEquals("public/first/p1/index.html", "<h2 id=\"p1-h1\">p1-h1</h2>\n<p></p>\n<h3 id=\"p2-h1\">p2-h1</h3>\n<p>This is some <strong>markup</strong>.\n</p>\n")
+ b.EditFileReplaceAll("content/second/p2.md", "p2-h1", "p2-h1-edited").Build()
+ b.AssertNoRenderShortcodesArtifacts()
+ b.AssertFileContentEquals("public/first/p1/index.html", "<h2 id=\"p1-h1\">p1-h1</h2>\n<p></p>\n<h3 id=\"p2-h1-edited\">p2-h1-edited</h3>\n<p>This is some <strong>markup</strong>.\n</p>\n")
+}
diff --git a/hugolib/site.go b/hugolib/site.go
index 24ee5dcc5..c5a4956e2 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -1351,6 +1351,7 @@ func (s *Site) getLanguagePermalinkLang(alwaysInSubDir bool) string {
func (s *Site) resetBuildState(sourceChanged bool) {
s.relatedDocsHandler = s.relatedDocsHandler.Clone()
s.init.Reset()
+ s.pageMap.Reset()
}
func (s *Site) errorCollator(results <-chan error, errs chan<- error) {
diff --git a/lazy/init.go b/lazy/init.go
index 7b88a5351..bef3867a9 100644
--- a/lazy/init.go
+++ b/lazy/init.go
@@ -36,7 +36,7 @@ type Init struct {
prev *Init
children []*Init
- init onceMore
+ init OnceMore
out any
err error
f func(context.Context) (any, error)
diff --git a/lazy/once.go b/lazy/once.go
index c6abcd884..dac689df3 100644
--- a/lazy/once.go
+++ b/lazy/once.go
@@ -18,19 +18,19 @@ import (
"sync/atomic"
)
-// onceMore is similar to sync.Once.
+// OnceMore is similar to sync.Once.
//
// Additional features are:
// * it can be reset, so the action can be repeated if needed
// * it has methods to check if it's done or in progress
-type onceMore struct {
+type OnceMore struct {
mu sync.Mutex
lock uint32
done uint32
}
-func (t *onceMore) Do(f func()) {
+func (t *OnceMore) Do(f func()) {
if atomic.LoadUint32(&t.done) == 1 {
return
}
@@ -53,15 +53,15 @@ func (t *onceMore) Do(f func()) {
f()
}
-func (t *onceMore) InProgress() bool {
+func (t *OnceMore) InProgress() bool {
return atomic.LoadUint32(&t.lock) == 1
}
-func (t *onceMore) Done() bool {
+func (t *OnceMore) Done() bool {
return atomic.LoadUint32(&t.done) == 1
}
-func (t *onceMore) ResetWithLock() *sync.Mutex {
+func (t *OnceMore) ResetWithLock() *sync.Mutex {
t.mu.Lock()
defer atomic.StoreUint32(&t.done, 0)
return &t.mu