diff --git a/tpl/strings/strings.go b/tpl/strings/strings.go index cd233b0a4..e6f7aed80 100644 --- a/tpl/strings/strings.go +++ b/tpl/strings/strings.go @@ -27,6 +27,7 @@ import ( "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/tpl" + "github.com/rogpeppe/go-internal/diff" "github.com/spf13/cast" ) @@ -172,6 +173,15 @@ func (ns *Namespace) ContainsNonSpace(s any) bool { return false } +// Diff returns an anchored diff of the two texts old and new in the “unified +// diff” format. If old and new are identical, Diff returns an empty string. +func (ns *Namespace) Diff(oldname string, old any, newname string, new any) string { + oldb := []byte(cast.ToString(old)) + newb := []byte(cast.ToString(new)) + + return string(diff.Diff(oldname, oldb, newname, newb)) +} + // HasPrefix tests whether the input s begins with prefix. func (ns *Namespace) HasPrefix(s, prefix any) (bool, error) { ss, err := cast.ToStringE(s) diff --git a/tpl/strings/strings_test.go b/tpl/strings/strings_test.go index 43334a8e8..92767925a 100644 --- a/tpl/strings/strings_test.go +++ b/tpl/strings/strings_test.go @@ -17,10 +17,9 @@ import ( "html/template" "testing" + qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/config/testconfig" "github.com/gohugoio/hugo/deps" - - qt "github.com/frankban/quicktest" "github.com/spf13/cast" ) @@ -808,3 +807,26 @@ func TestRepeat(t *testing.T) { c.Assert(result, qt.Equals, test.expect) } } + +func TestDiff(t *testing.T) { + t.Parallel() + c := qt.New(t) + + for _, tt := range []struct { + oldname string + old any + newname string + new any + expect string + }{ + {"old", "foo\n", "new", "bar\n", "diff old new\n--- old\n+++ new\n@@ -1,1 +1,1 @@\n-foo\n+bar\n"}, + {"old", "foo\n", "new", "foo\n", ""}, + {"old", "foo\n", "new", "", "diff old new\n--- old\n+++ new\n@@ -1,1 +0,0 @@\n-foo\n"}, + {"old", "foo\n", "new", nil, "diff old new\n--- old\n+++ new\n@@ -1,1 +0,0 @@\n-foo\n"}, + {"old", "", "new", "", ""}, + } { + + result := ns.Diff(tt.oldname, tt.old, tt.newname, tt.new) + c.Assert(result, qt.Equals, tt.expect) + } +}