From 3646ff6d6606153795ff8fa615835a7a983c8407 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 20 Apr 2025 18:45:15 +0100 Subject: [PATCH] appview: diff: organize changed-files into file-tree introduces the filetree package. eventually we will have a sticky side-panel style layout for any page displaying diffs (probably makes most sense when we have split diffs), and this file-tree will move there. --- appview/filetree/filetree.go | 62 +++++++++++++++++++ appview/pages/funcmap.go | 2 + appview/pages/pages.go | 11 ++-- .../pages/templates/repo/fragments/diff.html | 21 ++----- .../templates/repo/fragments/filetree.html | 27 ++++++++ .../templates/repo/fragments/interdiff.html | 9 +-- appview/state/pull.go | 4 +- patchutil/interdiff.go | 8 +++ types/diff.go | 14 +++++ 9 files changed, 128 insertions(+), 30 deletions(-) create mode 100644 appview/filetree/filetree.go create mode 100644 appview/pages/templates/repo/fragments/filetree.html diff --git a/appview/filetree/filetree.go b/appview/filetree/filetree.go new file mode 100644 index 00000000..01fb56b3 --- /dev/null +++ b/appview/filetree/filetree.go @@ -0,0 +1,62 @@ +package filetree + +import ( + "path/filepath" + "sort" + "strings" +) + +type FileTreeNode struct { + Name string + Path string + IsDirectory bool + Children map[string]*FileTreeNode +} + +// NewNode creates a new node +func newNode(name, path string, isDir bool) *FileTreeNode { + return &FileTreeNode{ + Name: name, + Path: path, + IsDirectory: isDir, + Children: make(map[string]*FileTreeNode), + } +} + +func FileTree(files []string) *FileTreeNode { + rootNode := newNode("", "", true) + + sort.Strings(files) + + for _, file := range files { + if file == "" { + continue + } + + parts := strings.Split(filepath.Clean(file), "/") + if len(parts) == 0 { + continue + } + + currentNode := rootNode + currentPath := "" + + for i, part := range parts { + if currentPath == "" { + currentPath = part + } else { + currentPath = filepath.Join(currentPath, part) + } + + isDir := i < len(parts)-1 + + if _, exists := currentNode.Children[part]; !exists { + currentNode.Children[part] = newNode(part, currentPath, isDir) + } + + currentNode = currentNode.Children[part] + } + } + + return rootNode +} diff --git a/appview/pages/funcmap.go b/appview/pages/funcmap.go index ed2399ab..490b98ab 100644 --- a/appview/pages/funcmap.go +++ b/appview/pages/funcmap.go @@ -13,6 +13,7 @@ import ( "time" "github.com/dustin/go-humanize" + "tangled.sh/tangled.sh/core/appview/filetree" "tangled.sh/tangled.sh/core/appview/pages/markup" ) @@ -174,6 +175,7 @@ func funcMap() template.FuncMap { return template.HTML(data) }, "cssContentHash": CssContentHash, + "fileTree": filetree.FileTree, } } diff --git a/appview/pages/pages.go b/appview/pages/pages.go index 3f32e0a7..190d8cd0 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -505,11 +505,12 @@ func (p *Pages) RepoLog(w io.Writer, params RepoLogParams) error { } type RepoCommitParams struct { - LoggedInUser *auth.User - RepoInfo RepoInfo - Active string - types.RepoCommitResponse + LoggedInUser *auth.User + RepoInfo RepoInfo + Active string EmailToDidOrHandle map[string]string + + types.RepoCommitResponse } func (p *Pages) RepoCommit(w io.Writer, params RepoCommitParams) error { @@ -784,7 +785,7 @@ type RepoPullPatchParams struct { DidHandleMap map[string]string RepoInfo RepoInfo Pull *db.Pull - Diff types.NiceDiff + Diff *types.NiceDiff Round int Submission *db.PullSubmission } diff --git a/appview/pages/templates/repo/fragments/diff.html b/appview/pages/templates/repo/fragments/diff.html index e237f56b..605c2477 100644 --- a/appview/pages/templates/repo/fragments/diff.html +++ b/appview/pages/templates/repo/fragments/diff.html @@ -3,6 +3,7 @@ {{ $diff := index . 1 }} {{ $commit := $diff.Commit }} {{ $stat := $diff.Stat }} +{{ $fileTree := fileTree $diff.ChangedFiles }} {{ $diff := $diff.Diff }} {{ $this := $commit.This }} @@ -14,17 +15,7 @@ Changed files {{ block "statPill" $stat }} {{ end }} -
- {{ range $diff }} - - {{ end }} -
+ {{ block "fileTree" $fileTree }} {{ end }} @@ -38,7 +29,7 @@
-
+
{{ $markerstyle := "diff-type p-1 mr-1 font-mono text-sm rounded select-none" }} {{ if .IsNew }} ADDED @@ -55,7 +46,7 @@ {{ block "statPill" .Stats }} {{ end }}
-
+
{{ if .IsDelete }} {{ .Name.Old }} @@ -102,10 +93,6 @@

This file has been copied.

- {{ else if .IsRename }} -

- This file has been renamed. -

{{ else if .IsBinary }}

This is a binary file and will not be displayed. diff --git a/appview/pages/templates/repo/fragments/filetree.html b/appview/pages/templates/repo/fragments/filetree.html new file mode 100644 index 00000000..9268610a --- /dev/null +++ b/appview/pages/templates/repo/fragments/filetree.html @@ -0,0 +1,27 @@ +{{ define "fileTree" }} + {{ if and .Name .IsDirectory }} +

+ + + {{ i "folder" "w-3 h-3 fill-current" }} + {{ .Name }} + + +
+ {{ range $child := .Children }} + {{ block "fileTree" $child }} {{ end }} + {{ end }} +
+
+ {{ else if .Name }} +
+ {{ else }} + {{ range $child := .Children }} + {{ block "fileTree" $child }} {{ end }} + {{ end }} + {{ end }} +{{ end }} + diff --git a/appview/pages/templates/repo/fragments/interdiff.html b/appview/pages/templates/repo/fragments/interdiff.html index f9fd6e5b..90959f4e 100644 --- a/appview/pages/templates/repo/fragments/interdiff.html +++ b/appview/pages/templates/repo/fragments/interdiff.html @@ -1,6 +1,7 @@ {{ define "repo/fragments/interdiff" }} {{ $repo := index . 0 }} {{ $x := index . 1 }} +{{ $fileTree := fileTree $x.AffectedFiles }} {{ $diff := $x.Files }}
@@ -8,13 +9,7 @@
files
-
- -
+ {{ block "fileTree" $fileTree }} {{ end }}
diff --git a/appview/state/pull.go b/appview/state/pull.go index 064f707f..790d8a81 100644 --- a/appview/state/pull.go +++ b/appview/state/pull.go @@ -284,6 +284,8 @@ func (s *State) RepoPullPatch(w http.ResponseWriter, r *http.Request) { } } + diff := pull.Submissions[roundIdInt].AsNiceDiff(pull.TargetBranch) + s.pages.RepoPullPatchPage(w, pages.RepoPullPatchParams{ LoggedInUser: user, DidHandleMap: didHandleMap, @@ -291,7 +293,7 @@ func (s *State) RepoPullPatch(w http.ResponseWriter, r *http.Request) { Pull: pull, Round: roundIdInt, Submission: pull.Submissions[roundIdInt], - Diff: pull.Submissions[roundIdInt].AsNiceDiff(pull.TargetBranch), + Diff: &diff, }) } diff --git a/patchutil/interdiff.go b/patchutil/interdiff.go index 6f4072bc..716a9a3d 100644 --- a/patchutil/interdiff.go +++ b/patchutil/interdiff.go @@ -11,6 +11,14 @@ type InterdiffResult struct { Files []*InterdiffFile } +func (i *InterdiffResult) AffectedFiles() []string { + files := make([]string, len(i.Files)) + for _, f := range i.Files { + files = append(files, f.Name) + } + return files +} + func (i *InterdiffResult) String() string { var b strings.Builder for _, f := range i.Files { diff --git a/types/diff.go b/types/diff.go index e45d68d3..a9a809b4 100644 --- a/types/diff.go +++ b/types/diff.go @@ -59,3 +59,17 @@ type DiffTree struct { Patch string `json:"patch"` Diff []*gitdiff.File `json:"diff"` } + +func (d *NiceDiff) ChangedFiles() []string { + files := make([]string, len(d.Diff)) + + for i, f := range d.Diff { + if f.IsDelete { + files[i] = f.Name.Old + } else { + files[i] = f.Name.New + } + } + + return files +} -- 2.51.2