vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Open every folder in a change request's file tree
43f98bcd93c6ae44d4a7e20f715408d9d324e201 · Keenan Nemetz · 13d ago · parent 2841d922
Open every folder in a change request's file tree The review tree folded every directory except the one holding the selected file, so a change that touched several folders hid most of its files behind a click each. The tree is an index of what the change touches, so it should show all of it at once. Every directory node now starts open. A folder can still be collapsed by hand, and the browser's tree sync keeps opening the ancestors of a file it navigates to.
server/web/request_files_test.go +18−7
| @@ -21,20 +21,22 @@ func findTreeNode(nodes []*treeNode, path string) *treeNode { | |||
| 21 | 21 | return nil | |
| 22 | 22 | } | |
| 23 | 23 | ||
| 24 | func TestBuildReviewTreeStatusesAndActiveAncestors(t *testing.T) { | ||
| 24 | func TestBuildReviewTreeStatusesAndOpenDirectories(t *testing.T) { | ||
| 25 | 25 | files := []diffFile{ | |
| 26 | 26 | {NewPath: "docs/new.md"}, | |
| 27 | 27 | {OldPath: "old.go", NewPath: "new.go"}, | |
| 28 | 28 | {OldPath: "removed.txt"}, | |
| 29 | 29 | {OldPath: "keep.go", NewPath: "keep.go"}, | |
| 30 | {NewPath: "other/deep/file.go"}, | ||
| 30 | 31 | } | |
| 31 | 32 | tree := buildReviewTree(files, "docs/new.md") | |
| 32 | 33 | ||
| 33 | 34 | for path, want := range map[string]string{ | |
| 34 | "docs/new.md": "A", | ||
| 35 | "new.go": "R", | ||
| 36 | "removed.txt": "D", | ||
| 37 | "keep.go": "M", | ||
| 35 | "docs/new.md": "A", | ||
| 36 | "new.go": "R", | ||
| 37 | "removed.txt": "D", | ||
| 38 | "keep.go": "M", | ||
| 39 | "other/deep/file.go": "A", | ||
| 38 | 40 | } { | |
| 39 | 41 | node := findTreeNode(tree, path) | |
| 40 | 42 | if node == nil { | |
| @@ -47,8 +49,17 @@ func TestBuildReviewTreeStatusesAndActiveAncestors(t *testing.T) { | |||
| 47 | 49 | if node := findTreeNode(tree, "docs/new.md"); !node.Active { | |
| 48 | 50 | t.Fatal("the selected file is not active") | |
| 49 | 51 | } | |
| 50 | if docs := findTreeNode(tree, "docs"); docs == nil || !docs.Open { | ||
| 51 | t.Fatal("the selected file's directory is not open") | ||
| 52 | // Every directory starts open, not just the one on the path to the selected | ||
| 53 | // file: the tree is an index of the change, so a nested file is visible without | ||
| 54 | // unfolding each folder first. | ||
| 55 | for _, dir := range []string{"docs", "other", "other/deep"} { | ||
| 56 | node := findTreeNode(tree, dir) | ||
| 57 | if node == nil || node.Type != "tree" { | ||
| 58 | t.Fatalf("tree is missing the directory %s", dir) | ||
| 59 | } | ||
| 60 | if !node.Open { | ||
| 61 | t.Fatalf("the directory %s starts collapsed", dir) | ||
| 62 | } | ||
| 52 | 63 | } | |
| 53 | 64 | // Deleted files keep their old path; renamed files take the new one. | |
| 54 | 65 | if findTreeNode(tree, "old.go") != nil { | |