From 5d3553d7d13c9d82de13a26cc4a3dc1bd70c8020 Mon Sep 17 00:00:00 2001 From: moshyfawn Date: Wed, 07 Jan 2026 04:15:28 +0000 Subject: [PATCH] appview/reporesolver: fix current directory extraction for tree paths path.Dir on extractPathAfterRef returned the parent directory, which broke relative link resolution in markdown when viewing directories. extractCurrentDir now handles blob and tree paths separately: blob paths return the parent dir, tree paths return the directory itself Signed-off-by: moshyfawn --- appview/reporesolver/resolver.go | 27 ++++++++++++++++++++++++++- appview/reporesolver/resolver_test.go | 22 ++++++++++++++++++++++ 2 file(s) changed, 48 insertion(s)(+), 1 deletion(s)(-) diff --git a/appview/reporesolver/resolver.go b/appview/reporesolver/resolver.go --- a/appview/reporesolver/resolver.go +++ b/appview/reporesolver/resolver.go @@ -63,7 +63,7 @@ } // get dir/ref - currentDir := path.Dir(extractPathAfterRef(r.URL.EscapedPath())) + currentDir := extractCurrentDir(r.URL.EscapedPath()) ref := chi.URLParam(r, "ref") repoAt := repo.RepoAt() @@ -130,6 +130,31 @@ } return repoInfo +} + +// extractCurrentDir gets the current directory for markdown link resolution. +// for blob paths, returns the parent dir. for tree paths, returns the path itself. +// +// /@user/repo/blob/main/docs/README.md => docs +// /@user/repo/tree/main/docs => docs +func extractCurrentDir(fullPath string) string { + fullPath = strings.TrimPrefix(fullPath, "/") + + blobPattern := regexp.MustCompile(`blob/[^/]+/(.*)$`) + if matches := blobPattern.FindStringSubmatch(fullPath); len(matches) > 1 { + return path.Dir(matches[1]) + } + + treePattern := regexp.MustCompile(`tree/[^/]+/(.*)$`) + if matches := treePattern.FindStringSubmatch(fullPath); len(matches) > 1 { + dir := strings.TrimSuffix(matches[1], "/") + if dir == "" { + return "." + } + return dir + } + + return "." } // extractPathAfterRef gets the actual repository path diff --git a/appview/reporesolver/resolver_test.go b/appview/reporesolver/resolver_test.go new file mode 100644 --- /dev/null +++ b/appview/reporesolver/resolver_test.go @@ -0,0 +1,22 @@ +package reporesolver + +import "testing" + +func TestExtractCurrentDir(t *testing.T) { + tests := []struct { + path string + want string + }{ + {"/@user/repo/blob/main/docs/README.md", "docs"}, + {"/@user/repo/blob/main/README.md", "."}, + {"/@user/repo/tree/main/docs", "docs"}, + {"/@user/repo/tree/main/docs/", "docs"}, + {"/@user/repo/tree/main", "."}, + } + + for _, tt := range tests { + if got := extractCurrentDir(tt.path); got != tt.want { + t.Errorf("extractCurrentDir(%q) = %q, want %q", tt.path, got, tt.want) + } + } +} -- tangled.sh