diff options
author | Bjørn Erik Pedersen <[email protected]> | 2024-11-03 10:41:34 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2024-11-03 13:33:31 +0100 |
commit | 30d9aea8607e8143968d73d11a8c1c0e51d34343 (patch) | |
tree | 7e1be54881670eb402de1007f6b7bdf7e4ae3506 | |
parent | 1f23b4949c70a2a8f2084fa937e19e93a9fe890a (diff) | |
download | hugo-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.go | 12 | ||||
-rw-r--r-- | hugolib/rendershortcodes_test.go | 35 | ||||
-rw-r--r-- | hugolib/site.go | 1 | ||||
-rw-r--r-- | lazy/init.go | 2 | ||||
-rw-r--r-- | lazy/once.go | 12 |
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 |