From 8ff578974295d803618c56f1766a829f3e54da0f Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Fri, 18 Jul 2025 20:32:56 +0000 Subject: [PATCH] appview/pages: initial support for split diffs Signed-off-by: oppiliappan --- types/diff.go | 26 ++++++++++++++++++++++++++ appview/pages/pages.go | 3 +++ appview/pulls/pulls.go | 6 ++++++ appview/repo/repo.go | 13 ++++++++++++- appview/pages/templates/repo/commit.html | 2 +- appview/pages/templates/repo/compare/compare.html | 2 +- appview/pages/templates/repo/fragments/diff.html | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------- appview/pages/templates/repo/fragments/diffChangedFiles.html | 2 +- appview/pages/templates/repo/fragments/interdiffFiles.html | 2 +- appview/pages/templates/repo/pulls/patch.html | 2 +- appview/pages/templates/repo/pulls/pull.html | 1 - 11 file(s) changed, 170 insertion(s)(+), 46 deletion(s)(-) diff --git a/types/diff.go b/types/diff.go --- a/types/diff.go +++ b/types/diff.go @@ -5,6 +5,10 @@ "github.com/go-git/go-git/v5/plumbing/object" ) +type DiffOpts struct { + Split bool `json:"split"` +} + type TextFragment struct { Header string `json:"comment"` Lines []gitdiff.Line `json:"lines"` @@ -76,4 +80,26 @@ } return files +} + +// used by html elements as a unique ID for hrefs +func (d *Diff) Id() string { + return d.Name.New +} + +func (d *Diff) Split() *SplitDiff { + fragments := make([]SplitFragment, len(d.TextFragments)) + for i, fragment := range d.TextFragments { + leftLines, rightLines := SeparateLines(&fragment) + fragments[i] = SplitFragment{ + Header: fragment.Header(), + LeftLines: leftLines, + RightLines: rightLines, + } + } + + return &SplitDiff{ + Name: d.Id(), + TextFragments: fragments, + } } diff --git a/appview/pages/pages.go b/appview/pages/pages.go --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -527,6 +527,7 @@ Active string EmailToDidOrHandle map[string]string Pipeline *db.Pipeline + DiffOpts types.DiffOpts // singular because it's always going to be just one VerifiedCommit commitverify.VerifiedCommits @@ -859,6 +860,7 @@ Round int Submission *db.PullSubmission OrderedReactionKinds []db.ReactionKind + DiffOpts types.DiffOpts } // this name is a mouthful @@ -964,6 +966,7 @@ Base string Head string Diff *types.NiceDiff + DiffOpts types.DiffOpts Active string } diff --git a/appview/pulls/pulls.go b/appview/pulls/pulls.go --- a/appview/pulls/pulls.go +++ b/appview/pulls/pulls.go @@ -355,6 +355,11 @@ return } + var diffOpts types.DiffOpts + if d := r.URL.Query().Get("diff"); d == "split" { + diffOpts.Split = true + } + pull, ok := r.Context().Value("pull").(*db.Pull) if !ok { log.Println("failed to get pull") @@ -395,6 +400,7 @@ Round: roundIdInt, Submission: pull.Submissions[roundIdInt], Diff: &diff, + DiffOpts: diffOpts, }) } diff --git a/appview/repo/repo.go b/appview/repo/repo.go --- a/appview/repo/repo.go +++ b/appview/repo/repo.go @@ -268,6 +268,11 @@ protocol = "https" } + var diffOpts types.DiffOpts + if d := r.URL.Query().Get("diff"); d == "split" { + diffOpts.Split = true + } + if !plumbing.IsHash(ref) { rp.pages.Error404(w) return @@ -321,8 +326,8 @@ EmailToDidOrHandle: emailToDidOrHandle(rp, emailToDidMap), VerifiedCommit: vc, Pipeline: pipeline, + DiffOpts: diffOpts, }) - return } func (rp *Repo) RepoTree(w http.ResponseWriter, r *http.Request) { @@ -1269,6 +1274,11 @@ return } + var diffOpts types.DiffOpts + if d := r.URL.Query().Get("diff"); d == "split" { + diffOpts.Split = true + } + // if user is navigating to one of // /compare/{base}/{head} // /compare/{base}...{head} @@ -1331,6 +1341,7 @@ Base: base, Head: head, Diff: &diff, + DiffOpts: diffOpts, }) } diff --git a/appview/pages/templates/repo/commit.html b/appview/pages/templates/repo/commit.html --- a/appview/pages/templates/repo/commit.html +++ b/appview/pages/templates/repo/commit.html @@ -119,7 +119,7 @@ {{ end }} {{ define "contentAfter" }} - {{ template "repo/fragments/diff" (list .RepoInfo.FullName .Diff) }} + {{ template "repo/fragments/diff" (list .RepoInfo.FullName .Diff .DiffOpts) }} {{end}} {{ define "contentAfterLeft" }} diff --git a/appview/pages/templates/repo/compare/compare.html b/appview/pages/templates/repo/compare/compare.html --- a/appview/pages/templates/repo/compare/compare.html +++ b/appview/pages/templates/repo/compare/compare.html @@ -50,7 +50,7 @@ {{ end }} {{ define "contentAfter" }} - {{ template "repo/fragments/diff" (list .RepoInfo.FullName .Diff) }} + {{ template "repo/fragments/diff" (list .RepoInfo.FullName .Diff .DiffOpts) }} {{end}} {{ define "contentAfterLeft" }} diff --git a/appview/pages/templates/repo/fragments/diff.html b/appview/pages/templates/repo/fragments/diff.html --- a/appview/pages/templates/repo/fragments/diff.html +++ b/appview/pages/templates/repo/fragments/diff.html @@ -1,8 +1,11 @@ {{ define "repo/fragments/diff" }} {{ $repo := index . 0 }} {{ $diff := index . 1 }} +{{ $opts := index . 2 }} + {{ $commit := $diff.Commit }} {{ $diff := $diff.Diff }} +{{ $isSplit := $opts.Split }} {{ $this := $commit.This }} {{ $parent := $commit.Parent }} @@ -85,45 +88,11 @@ This is a binary file and will not be displayed.

{{ else }} - {{ $name := .Name.New }} -
{{- range .TextFragments -}}
···
- {{- $oldStart := .OldPosition -}} - {{- $newStart := .NewPosition -}} - {{- $lineNrStyle := "min-w-[3.5rem] flex-shrink-0 select-none text-right bg-white dark:bg-gray-800 scroll-mt-10 target:border target:border-amber-500 target:rounded " -}} - {{- $linkStyle := "text-gray-400 dark:text-gray-500 hover:underline" -}} - {{- $lineNrSepStyle1 := "" -}} - {{- $lineNrSepStyle2 := "pr-2" -}} - {{- range .Lines -}} - {{- if eq .Op.String "+" -}} -
-
- -
{{ .Op.String }}
-
{{ .Line }}
-
- {{- $newStart = add64 $newStart 1 -}} - {{- end -}} - {{- if eq .Op.String "-" -}} -
- -
-
{{ .Op.String }}
-
{{ .Line }}
-
- {{- $oldStart = add64 $oldStart 1 -}} - {{- end -}} - {{- if eq .Op.String " " -}} -
- - -
{{ .Op.String }}
-
{{ .Line }}
-
- {{- $newStart = add64 $newStart 1 -}} - {{- $oldStart = add64 $oldStart 1 -}} - {{- end -}} - {{- end -}} - {{- end -}}
+ {{ if $isSplit }} + {{- template "repo/fragments/splitDiff" .Split -}} + {{ else }} + {{- template "repo/fragments/unifiedDiff" . -}} + {{ end }} {{- end -}} @@ -134,6 +103,115 @@ {{ end }} {{ end }} +{{ end }} + +{{ define "unifiedDiffLines" }} +{{ $name := .Name.New }} +
{{- range .TextFragments -}}
···
+ {{- $oldStart := .OldPosition -}} + {{- $newStart := .NewPosition -}} + {{- $lineNrStyle := "min-w-[3.5rem] flex-shrink-0 select-none text-right bg-white dark:bg-gray-800 target:bg-yellow-200 target:dark:bg-yellow-600" -}} + {{- $linkStyle := "text-gray-400 dark:text-gray-500 hover:underline" -}} + {{- $lineNrSepStyle1 := "" -}} + {{- $lineNrSepStyle2 := "pr-2 border-r border-gray-200 dark:border-gray-700" -}} + {{- $containerStyle := "flex min-w-full items-center target:border target:rounded-sm target:border-yellow-200 target:dark:border-yellow-700 scroll-mt-20" -}} + {{- $addStyle := "bg-green-100 dark:bg-green-800/30 text-green-700 dark:text-green-400 " -}} + {{- $delStyle := "bg-red-100 dark:bg-red-800/30 text-red-700 dark:text-red-400 " -}} + {{- $ctxStyle := "bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400" -}} + {{- $opStyle := "w-5 flex-shrink-0 select-none text-center" -}} + {{- range .Lines -}} + {{- if eq .Op.String "+" -}} +
+
+ +
{{ .Op.String }}
+
{{ .Line }}
+
+ {{- $newStart = add64 $newStart 1 -}} + {{- end -}} + {{- if eq .Op.String "-" -}} +
+ +
+
{{ .Op.String }}
+
{{ .Line }}
+
+ {{- $oldStart = add64 $oldStart 1 -}} + {{- end -}} + {{- if eq .Op.String " " -}} +
+ + +
{{ .Op.String }}
+
{{ .Line }}
+
+ {{- $newStart = add64 $newStart 1 -}} + {{- $oldStart = add64 $oldStart 1 -}} + {{- end -}} + {{- end -}} + {{- end -}}
+{{ end }} + +{{ define "splitDiffLines" }} +{{ $name := .Name.New }} +{{- $lineNrStyle := "min-w-[3.5rem] flex-shrink-0 select-none text-right bg-white dark:bg-gray-800" -}} +{{- $linkStyle := "text-gray-400 dark:text-gray-500 hover:underline" -}} +{{- $lineNrSepStyle := "pr-2 border-r border-gray-200 dark:border-gray-700" -}} +{{- $containerStyle := "flex min-w-full items-center target:border target:rounded-sm target:border-yellow-200 target:dark:border-yellow-700 scroll-mt-20" -}} +{{- $emptyStyle := "bg-gray-200/30 dark:bg-gray-700/30" -}} +{{- $addStyle := "bg-green-100 dark:bg-green-800/30 text-green-700 dark:text-green-400" -}} +{{- $delStyle := "bg-red-100 dark:bg-red-800/30 text-red-700 dark:text-red-400 " -}} +{{- $ctxStyle := "bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400" -}} +{{- $opStyle := "w-5 flex-shrink-0 select-none text-center" -}} +
+
{{- range .TextFragments -}}
···
+ {{- range .LeftLines -}} + {{- if .IsEmpty -}} +
+
+
+ +
+ {{- else if eq .Op.String "-" -}} +
+ +
{{ .Op.String }}
+
{{ .Content }}
+
+ {{- else if eq .Op.String " " -}} +
+ +
{{ .Op.String }}
+
{{ .Content }}
+
+ {{- end -}} + {{- end -}} + {{- end -}}
+ +
{{- range .TextFragments -}}
···
+ {{- range .RightLines -}} + {{- if .IsEmpty -}} +
+
+
+ +
+ {{- else if eq .Op.String "+" -}} +
+ +
{{ .Op.String }}
+
{{ .Content }}
+
+ {{- else if eq .Op.String " " -}} +
+ +
{{ .Op.String }}
+
{{ .Content }}
+
+ {{- end -}} + {{- end -}} + {{- end -}}
+
{{ end }} {{ define "statPill" }} @@ -148,3 +226,4 @@ {{ end }} {{ end }} + diff --git a/appview/pages/templates/repo/fragments/diffChangedFiles.html b/appview/pages/templates/repo/fragments/diffChangedFiles.html --- a/appview/pages/templates/repo/fragments/diffChangedFiles.html +++ b/appview/pages/templates/repo/fragments/diffChangedFiles.html @@ -2,7 +2,7 @@ {{ $stat := .Stat }} {{ $fileTree := fileTree .ChangedFiles }}
-
+
Changed files diff --git a/appview/pages/templates/repo/fragments/interdiffFiles.html b/appview/pages/templates/repo/fragments/interdiffFiles.html --- a/appview/pages/templates/repo/fragments/interdiffFiles.html +++ b/appview/pages/templates/repo/fragments/interdiffFiles.html @@ -1,6 +1,6 @@ {{ define "repo/fragments/interdiffFiles" }} {{ $fileTree := fileTree .AffectedFiles }} -
+
files diff --git a/appview/pages/templates/repo/pulls/patch.html b/appview/pages/templates/repo/pulls/patch.html --- a/appview/pages/templates/repo/pulls/patch.html +++ b/appview/pages/templates/repo/pulls/patch.html @@ -74,7 +74,7 @@ {{ end }} {{ define "contentAfter" }} - {{ template "repo/fragments/diff" (list .RepoInfo.FullName .Diff) }} + {{ template "repo/fragments/diff" (list .RepoInfo.FullName .Diff .DiffOpts) }} {{end}} {{ define "contentAfterLeft" }} diff --git a/appview/pages/templates/repo/pulls/pull.html b/appview/pages/templates/repo/pulls/pull.html --- a/appview/pages/templates/repo/pulls/pull.html +++ b/appview/pages/templates/repo/pulls/pull.html @@ -179,7 +179,6 @@ {{ end }}
-
{{ end }} {{ end }} {{ end }} -- tangled.sh