diff --git a/appview/reporesolver/resolver.go b/appview/reporesolver/resolver.go index 2a924cb9..c7fe61ed 100644 --- a/appview/reporesolver/resolver.go +++ b/appview/reporesolver/resolver.go @@ -63,7 +63,7 @@ func (rr *RepoResolver) GetRepoInfo(r *http.Request, user *oauth.User) repoinfo. } // get dir/ref - currentDir := path.Dir(extractPathAfterRef(r.URL.EscapedPath())) + currentDir := extractCurrentDir(r.URL.EscapedPath()) ref := chi.URLParam(r, "ref") repoAt := repo.RepoAt() @@ -132,6 +132,31 @@ func (rr *RepoResolver) GetRepoInfo(r *http.Request, user *oauth.User) repoinfo. 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 // after the ref. for example: // diff --git a/appview/reporesolver/resolver_test.go b/appview/reporesolver/resolver_test.go new file mode 100644 index 00000000..5a620aaf --- /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) + } + } +}