Repository: gohugoio/hugo (language: go)

Issue:
Server hanges of resources included in shortcode/hook isn't always tracked correctly
E.g. in a `shortcode`.

* Include `(resources.Get "mytext.txt").Content`
* Edit `assets/mytext.txt`.

If the `content` with the `shortcode` gets rendered from the the home page first, the changes to will `assets/mytext.txt` not be picked up correctly.


Discussion / hints:

Fix patch:
diff --git a/hugolib/page__content.go b/hugolib/page__content.go
index 4ec91f7b5cd..b5527a28103 100644
--- a/hugolib/page__content.go
+++ b/hugolib/page__content.go
@@ -863,6 +863,10 @@ type cachedContentScope struct {
 }
 
 func (c *cachedContentScope) prepareContext(ctx context.Context) context.Context {
+	// A regular page's shortcode etc. may be rendered by e.g. the home page,
+	// so we need to track any changes to this content's page.
+	ctx = tpl.Context.DependencyManagerScopedProvider.Set(ctx, c.pco.po.p)
+
 	// The markup scope is recursive, so if already set to a non zero value, preserve that value.
 	if s := hugo.GetMarkupScope(ctx); s != "" || s == c.scope {
 		return ctx
diff --git a/identity/finder.go b/identity/finder.go
index 91fac72378b..b1a08d061a4 100644
--- a/identity/finder.go
+++ b/identity/finder.go
@@ -122,17 +122,21 @@ func (f *Finder) Contains(id, in Identity, maxDepth int) FinderResult {
 
 	defer putSearchID(sid)
 
-	if r := f.checkOne(sid, in, 0); r > 0 {
+	r := FinderNotFound
+	if i := f.checkOne(sid, in, 0); i > r {
+		r = i
+	}
+	if r == FinderFound {
 		return r
 	}
 
 	m := GetDependencyManager(in)
 	if m != nil {
-		if r := f.checkManager(sid, m, 0); r > 0 {
-			return r
+		if i := f.checkManager(sid, m, 0); i > r {
+			r = i
 		}
 	}
-	return FinderNotFound
+	return r
 }
 
 func (f *Finder) checkMaxDepth(sid *searchID, level int) FinderResult {
@@ -279,15 +283,18 @@ func (f *Finder) search(sid *searchID, m Manager, depth int) FinderResult {
 	var r FinderResult
 	m.forEeachIdentity(
 		func(v Identity) bool {
-			if r > 0 {
-				panic("should be terminated")
+			i := f.checkOne(sid, v, depth)
+			if i > r {
+				r = i
 			}
-			r = f.checkOne(sid, v, depth)
-			if r > 0 {
+			if r == FinderFound {
 				return true
 			}
 			m := GetDependencyManager(v)
-			if r = f.checkManager(sid, m, depth+1); r > 0 {
+			if i := f.checkManager(sid, m, depth+1); i > r {
+				r = i
+			}
+			if r == FinderFound {
 				return true
 			}
 			return false
diff --git a/tpl/template.go b/tpl/template.go
index 18a31e2314c..39c6b4f1cc5 100644
--- a/tpl/template.go
+++ b/tpl/template.go
@@ -172,7 +172,6 @@ type contextKey string
 var Context = struct {
 	DependencyManagerScopedProvider    hcontext.ContextDispatcher[identity.DependencyManagerScopedProvider]
 	GetDependencyManagerInCurrentScope func(context.Context) identity.Manager
-	SetDependencyManagerInCurrentScope func(context.Context, identity.Manager) context.Context
 	DependencyScope                    hcontext.ContextDispatcher[int]
 	Page                               hcontext.ContextDispatcher[page]
 	IsInGoldmark                       hcontext.ContextDispatcher[bool]


Test patch:
diff --git a/hugolib/rebuild_test.go b/hugolib/rebuild_test.go
index 2219fe81226..ff1f8267e8a 100644
--- a/hugolib/rebuild_test.go
+++ b/hugolib/rebuild_test.go
@@ -21,8 +21,13 @@ const rebuildFilesSimple = `
 baseURL = "https://example.com"
 disableKinds = ["term", "taxonomy", "sitemap", "robotstxt", "404"]
 disableLiveReload = true
+[outputFormats]
+  [outputFormats.rss]
+	weight = 10
+  [outputFormats.html]
+	weight = 20
 [outputs]
-home = ["html"]
+home = ["rss", "html"]
 section = ["html"]
 page = ["html"]
 -- content/mysection/_index.md --
@@ -58,6 +63,21 @@ Home Text Content.
 title: "myothersectionpage"
 ---
 myothersectionpage Content.
+-- content/mythirdsection/mythirdsectionpage.md --
+---
+title: "mythirdsectionpage"
+---
+mythirdsectionpage Content.
+{{< myshortcodetext >}}
+§§§ myothertext
+foo
+§§§
+-- assets/mytext.txt --
+Assets My Text.
+-- assets/myshortcodetext.txt --
+Assets My Shortcode Text.
+-- assets/myothertext.txt --
+Assets My Other Text.
 -- layouts/_default/single.html --
 Single: {{ .Title }}|{{ .Content }}$
 Resources: {{ range $i, $e := .Resources }}{{ $i }}:{{ .RelPermalink }}|{{ .Content }}|{{ end }}$
@@ -68,6 +88,13 @@ Len Resources: {{ len .Resources }}|
 Resources: {{ range $i, $e := .Resources }}{{ $i }}:{{ .RelPermalink }}|{{ .Content }}|{{ end }}$
 -- layouts/shortcodes/foo.html --
 Foo.
+-- layouts/shortcodes/myshortcodetext.html --
+{{ warnf "mytext %s" now}}
+{{ $r := resources.Get "myshortcodetext.txt" }}
+My Shortcode Text: {{ $r.Content }}|{{ $r.Permalink }}|
+-- layouts/_default/_markup/render-codeblock-myothertext.html --
+{{ $r := resources.Get "myothertext.txt" }}
+My Other Text: {{ $r.Content }}|{{ $r.Permalink }}|
 
 `
 
@@ -83,6 +110,34 @@ func TestRebuildEditTextFileInLeafBundle(t *testing.T) {
 	b.AssertRenderCountContent(1)
 }
 
+func TestRebuildEditTextFileInShortcode(t *testing.T) {
+	t.Parallel()
+	for i := 0; i < 3; i++ {
+		b := TestRunning(t, rebuildFilesSimple)
+		b.AssertFileContent("public/mythirdsection/mythirdsectionpage/index.html",
+			"Text: Assets My Shortcode Text.")
+		b.EditFileReplaceAll("assets/myshortcodetext.txt", "My Shortcode Text", "My Shortcode Text Edited").Build()
+		fmt.Println(b.LogString())
+		b.AssertFileContent("public/mythirdsection/mythirdsectionpage/index.html",
+			"Text: Assets My Shortcode Text Edited.")
+
+	}
+}
+
+func TestRebuildEditTextFileInHook(t *testing.T) {
+	t.Parallel()
+	for i := 0; i < 3; i++ {
+		b := TestRunning(t, rebuildFilesSimple)
+		b.AssertFileContent("public/mythirdsection/mythirdsectionpage/index.html",
+			"Text: Assets My Other Text.")
+		b.AssertFileContent("public/myothertext.txt", "Assets My Other Text.")
+		b.EditFileReplaceAll("assets/myothertext.txt", "My Other Text", "My Other Text Edited").Build()
+		b.AssertFileContent("public/mythirdsection/mythirdsectionpage/index.html",
+			"Text: Assets My Other Text Edited.")
+
+	}
+}
+
 func TestRebuiEditUnmarshaledYamlFileInLeafBundle(t *testing.T) {
 	files := `
 -- hugo.toml --
@@ -140,8 +195,8 @@ func TestRebuildRenameTextFileInLeafBundle(t *testing.T) {
 
 		b.RenameFile("content/mysection/mysectionbundle/mysectionbundletext.txt", "content/mysection/mysectionbundle/mysectionbundletext2.txt").Build()
 		b.AssertFileContent("public/mysection/mysectionbundle/index.html", "mysectionbundletext2", "My Section Bundle Text 2 Content.", "Len Resources: 2|")
-		b.AssertRenderCountPage(5)
-		b.AssertRenderCountContent(6)
+		b.AssertRenderCountPage(8)
+		b.AssertRenderCountContent(8)
 	})
 }
 
@@ -161,8 +216,8 @@ func TestRebuilEditContentFileThenAnother(t *testing.T) {
 
 	b.EditFileReplaceAll("content/myothersection/myothersectionpage.md", "myothersectionpage Content.", "myothersectionpage Content Edited.").Build()
 	b.AssertFileContent("public/myothersection/myothersectionpage/index.html", "myothersectionpage Content Edited")
-	b.AssertRenderCountPage(1)
-	b.AssertRenderCountContent(1)
+	b.AssertRenderCountPage(2)
+	b.AssertRenderCountContent(2)
 }
 
 func TestRebuildRenameTextFileInBranchBundle(t *testing.T) {
@@ -171,7 +226,7 @@ func TestRebuildRenameTextFileInBranchBundle(t *testing.T) {
 
 	b.RenameFile("content/mysection/mysectiontext.txt", "content/mysection/mysectiontext2.txt").Build()
 	b.AssertFileContent("public/mysection/index.html", "mysectiontext2", "My Section")
-	b.AssertRenderCountPage(2)
+	b.AssertRenderCountPage(3)
 	b.AssertRenderCountContent(2)
 }
 
@@ -181,14 +236,14 @@ func TestRebuildRenameTextFileInHomeBundle(t *testing.T) {
 
 	b.RenameFile("content/hometext.txt", "content/hometext2.txt").Build()
 	b.AssertFileContent("public/index.html", "hometext2", "Home Text Content.")
-	b.AssertRenderCountPage(3)
+	b.AssertRenderCountPage(5)
 }
 
 func TestRebuildRenameDirectoryWithLeafBundle(t *testing.T) {
 	b := TestRunning(t, rebuildFilesSimple)
 	b.RenameDir("content/mysection/mysectionbundle", "content/mysection/mysectionbundlerenamed").Build()
 	b.AssertFileContent("public/mysection/mysectionbundlerenamed/index.html", "My Section Bundle")
-	b.AssertRenderCountPage(1)
+	b.AssertRenderCountPage(2)
 }
 
 func TestRebuildRenameDirectoryWithBranchBundle(t *testing.T) {
@@ -197,7 +252,7 @@ func TestRebuildRenameDirectoryWithBranchBundle(t *testing.T) {
 	b.AssertFileContent("public/mysectionrenamed/index.html", "My Section")
 	b.AssertFileContent("public/mysectionrenamed/mysectionbundle/index.html", "My Section Bundle")
 	b.AssertFileContent("public/mysectionrenamed/mysectionbundle/mysectionbundletext.txt", "My Section Bundle Text 2 Content.")
-	b.AssertRenderCountPage(3)
+	b.AssertRenderCountPage(5)
 }
 
 func TestRebuildRenameDirectoryWithRegularPageUsedInHome(t *testing.T) {
@@ -296,7 +351,7 @@ func TestRebuildRenameDirectoryWithBranchBundleFastRender(t *testing.T) {
 	b.AssertFileContent("public/mysectionrenamed/index.html", "My Section")
 	b.AssertFileContent("public/mysectionrenamed/mysectionbundle/index.html", "My Section Bundle")
 	b.AssertFileContent("public/mysectionrenamed/mysectionbundle/mysectionbundletext.txt", "My Section Bundle Text 2 Content.")
-	b.AssertRenderCountPage(3)
+	b.AssertRenderCountPage(5)
 }
 
 func TestRebuilErrorRecovery(t *testing.T) {
@@ -1239,7 +1294,7 @@ Single.
 		return strings.Replace(s, "red", "blue", 1)
 	}).Build()
 
-	b.AssertRenderCountPage(3)
+	b.AssertRenderCountPage(4)
 
 	b.AssertFileContent("public/index.html", "Home.", "<style>body {\n\tbackground: blue;\n}</style>")
 }