Repository: gohugoio/hugo (language: go)

Issue:
I have a rebuild testcase with a bundled YAML files transformed via transform.Unmarshal that fails



Discussion / hints:

Fix patch:
diff --git a/tpl/internal/go_templates/texttemplate/hugo_template.go b/tpl/internal/go_templates/texttemplate/hugo_template.go
index 4db40ce82cf..276367a7c38 100644
--- a/tpl/internal/go_templates/texttemplate/hugo_template.go
+++ b/tpl/internal/go_templates/texttemplate/hugo_template.go
@@ -44,6 +44,7 @@ type ExecHelper interface {
 	GetFunc(ctx context.Context, tmpl Preparer, name string) (reflect.Value, reflect.Value, bool)
 	GetMethod(ctx context.Context, tmpl Preparer, receiver reflect.Value, name string) (method reflect.Value, firstArg reflect.Value)
 	GetMapValue(ctx context.Context, tmpl Preparer, receiver, key reflect.Value) (reflect.Value, bool)
+	OnCalled(ctx context.Context, tmpl Preparer, name string, args []reflect.Value, result reflect.Value)
 }
 
 // Executer executes a given template.
@@ -356,7 +357,14 @@ func (s *state) evalCall(dot, fun reflect.Value, isBuiltin bool, node parse.Node
 		s.at(node)
 		s.errorf("error calling %s: %w", name, err)
 	}
-	return unwrap(v)
+	vv := unwrap(v)
+
+	// Added for Hugo
+	if s.helper != nil {
+		s.helper.OnCalled(s.ctx, s.prep, name, argv, vv)
+	}
+
+	return vv
 }
 
 func isTrue(val reflect.Value) (truth, ok bool) {
diff --git a/tpl/tplimpl/template_funcs.go b/tpl/tplimpl/template_funcs.go
index 8997c83d615..9d14b9e56b2 100644
--- a/tpl/tplimpl/template_funcs.go
+++ b/tpl/tplimpl/template_funcs.go
@@ -150,6 +150,30 @@ func (t *templateExecHelper) GetMethod(ctx context.Context, tmpl texttemplate.Pr
 	return fn, zero
 }
 
+func (t *templateExecHelper) OnCalled(ctx context.Context, tmpl texttemplate.Preparer, name string, args []reflect.Value, result reflect.Value) {
+	if !t.running {
+		return
+	}
+
+	// This switch is mostly for speed.
+	switch name {
+	case "Unmarshal":
+	default:
+		return
+	}
+	idm := tpl.Context.GetDependencyManagerInCurrentScope(ctx)
+	if idm == nil {
+		return
+	}
+
+	for _, arg := range args {
+		identity.WalkIdentitiesShallow(arg.Interface(), func(level int, id identity.Identity) bool {
+			idm.AddIdentity(id)
+			return false
+		})
+	}
+}
+
 func (t *templateExecHelper) trackDependencies(ctx context.Context, tmpl texttemplate.Preparer, name string, receiver reflect.Value) context.Context {
 	if tmpl == nil {
 		panic("must provide a template")


Test patch:
diff --git a/hugolib/rebuild_test.go b/hugolib/rebuild_test.go
index d29215a011b..cf98f55da71 100644
--- a/hugolib/rebuild_test.go
+++ b/hugolib/rebuild_test.go
@@ -77,6 +77,27 @@ func TestRebuildEditTextFileInLeafBundle(t *testing.T) {
 	b.AssertRenderCountContent(1)
 }
 
+func TestRebuiEditUnmarshaledYamlFileInLeafBundle(t *testing.T) {
+	files := `
+-- hugo.toml --
+baseURL = "https://example.com"
+disableLiveReload = true
+disableKinds = ["taxonomy", "term", "sitemap", "robotsTXT", "404", "rss"]
+-- content/mybundle/index.md --
+-- content/mybundle/mydata.yml --
+foo: bar
+-- layouts/_default/single.html --
+MyData: {{ .Resources.Get "mydata.yml" | transform.Unmarshal }}|
+`
+	b := TestRunning(t, files)
+
+	b.AssertFileContent("public/mybundle/index.html", "MyData: map[foo:bar]")
+
+	b.EditFileReplaceAll("content/mybundle/mydata.yml", "bar", "bar edited").Build()
+
+	b.AssertFileContent("public/mybundle/index.html", "MyData: map[foo:bar edited]")
+}
+
 func TestRebuildEditTextFileInHomeBundle(t *testing.T) {
 	b := TestRunning(t, rebuildFilesSimple)
 	b.AssertFileContent("public/index.html", "Home Content.")
diff --git a/tpl/internal/go_templates/texttemplate/hugo_template_test.go b/tpl/internal/go_templates/texttemplate/hugo_template_test.go
index c68b747dd90..920d96fac54 100644
--- a/tpl/internal/go_templates/texttemplate/hugo_template_test.go
+++ b/tpl/internal/go_templates/texttemplate/hugo_template_test.go
@@ -64,6 +64,9 @@ func (e *execHelper) GetMethod(ctx context.Context, tmpl Preparer, receiver refl
 	return m, reflect.ValueOf("v2")
 }
 
+func (e *execHelper) OnCalled(ctx context.Context, tmpl Preparer, name string, args []reflect.Value, returnValue reflect.Value) {
+}
+
 func TestTemplateExecutor(t *testing.T) {
 	c := qt.New(t)