From aa2c01a9f3a764331451caa96caa29c8ca20f51c Mon Sep 17 00:00:00 2001 From: Rodrigo Silva Mendoza Date: Fri, 3 Jan 2025 17:26:35 -0700 Subject: [PATCH] add the ability to fetch blobs directly, for use by CLI and later on the frontend --- cmd/zoekt-fileviewer/fileview.go | 24 ++++++++++++++++++++++++ cmd/zoekt-fileviewer/main.go | 25 ++++++++++++------------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/cmd/zoekt-fileviewer/fileview.go b/cmd/zoekt-fileviewer/fileview.go index 5b35ffdc9..fcb58921c 100644 --- a/cmd/zoekt-fileviewer/fileview.go +++ b/cmd/zoekt-fileviewer/fileview.go @@ -5,6 +5,7 @@ import ( "bytes" "errors" "fmt" + "io" "log" "net/url" "os" @@ -192,6 +193,15 @@ func gitCatBlob(obj string, repoPath string) (string, error) { return string(out), nil } +func gitCatBlobDirect(obj string, repoPath string, w io.Writer) error { + cmd := exec.Command("git", "-C", repoPath, "cat-file", "blob", obj) + cmd.Stdout = w + if err := cmd.Run(); err != nil { + return err + } + return nil +} + // used to get the "real" name of "HEAD" func GitRevParseAbbrev(rev string, repoPath string) (string, error) { out, err := exec.Command("git", "-C", repoPath, "rev-parse", "--abbrev-ref", rev).Output() @@ -1189,6 +1199,20 @@ func GitBlameBlob(relativePath string, repo RepoConfig, commit string) (*BlameRe var fileDoesNotExistError = errors.New("This file does not exist at this point in history") +func GetPlainBlob(relativePath, repoPath, repoName, commit string, w io.Writer) error { + commitHash := commit + out, err := gitCommitHash(commit, repoPath) + if err == nil { + commitHash = out[:strings.Index(out, "\n")] + } + cleanPath := path.Clean(relativePath) + if cleanPath == "." { + cleanPath = "" + } + obj := commitHash + ":" + cleanPath + return gitCatBlobDirect(obj, repoPath, w) +} + // Used to support zoekt "preview file" actions. // Since we don't want to maintain repoConfig for zoekt // repos, we tell this function explicitly where the repo diff --git a/cmd/zoekt-fileviewer/main.go b/cmd/zoekt-fileviewer/main.go index c56a55e65..70e792b40 100644 --- a/cmd/zoekt-fileviewer/main.go +++ b/cmd/zoekt-fileviewer/main.go @@ -33,6 +33,7 @@ const ( GitListTagsRoute = V2 + "/getAllTagsForZoekt/:parent/:repo/+/" GetSyntaxHighlightedFileForZoektRoute = V2 + "/getSyntaxHighlightedFileForZoekt/:parent/:repo/+/" GitLsTreeRoute = V2 + "/getDirectoryTreeForZoekt/:parent/:repo/+/" + GitPlainBlobRoute = V2 + "/getPlainGitBlob/:parent/:repo/+/" ) func main() { @@ -111,12 +112,8 @@ func (s *Server) setupRoutes() error { s.router.Get(GitListTagsRoute, http.HandlerFunc(s.ServeListAllTagsForZoekt)) s.router.Get(GetSyntaxHighlightedFileForZoektRoute, http.HandlerFunc(s.ServeSyntaxHighlightedFileForZoekt)) s.router.Get(GitLsTreeRoute, http.HandlerFunc(s.ServeGitLsTreeForZoekt)) + s.router.Get(GitPlainBlobRoute, http.HandlerFunc(s.HandleFileReq)) - // m.Add("GET", "/api/v2/getSyntaxHighlightedFileForZoekt/:parent/:repo/+/", srv.Handler(srv.ServeSyntaxHighlightedFileForZoekt)) - // m.Add("GET", "/api/v2/getDirectoryTreeForZoekt/:parent/:repo/+/", srv.Handler(srv.ServeGitLsTreeForZoekt)) - // m.Add("GET", "/api/v2/getGitLogForZoekt/:parent/:repo/+/", srv.Handler(srv.ServeGitLogForZoekt)) - // m.Add("GET", "/api/v2/getAllBranchesForZoekt/:parent/:repo/+/", srv.Handler(srv.ServeListAllBranchesForZoekt)) - // m.Add("GET", "/api/v2/getAllTagsForZoekt/:parent/:repo/+/", srv.Handler(srv.ServeListAllTagsForZoekt)) handler := requestIDMiddleware(logMiddleware(s.router)) s.server = &http.Server{ @@ -338,12 +335,14 @@ func (s *Server) ServeListAllTagsForZoekt(w http.ResponseWriter, r *http.Request replyJSON(context.Background(), w, 200, tags) } -// get all tags, get all branches, getgitlog, getdirectorytreeforzoekt, -// getsyntaxhighlightedfileforzoekt +func (s *Server) HandleFileReq(w http.ResponseWriter, r *http.Request) { + parent := r.URL.Query().Get(":parent") + repo := r.URL.Query().Get(":repo") + repoRevAndPath := pat.Tail(GitPlainBlobRoute, r.URL.Path) + revision, path := parseRevisionAndPath(repoRevAndPath) + repoPath := fmt.Sprintf("%s/%s/%s.git", s.config.ZoektRepoCache, parent, repo) -// m.Add("GET", "/api/v2/getSyntaxHighlightedFileForZoekt/:parent/:repo/+/", srv.Handler(srv.ServeSyntaxHighlightedFileForZoekt)) -// m.Add("GET", "/api/v2/getDirectoryTreeForZoekt/:parent/:repo/+/", srv.Handler(srv.ServeGitLsTreeForZoekt)) -// m.Add("GET", "/api/v2/getGitLogForZoekt/:parent/:repo/+/", srv.Handler(srv.ServeGitLogForZoekt)) -// m.Add("GET", "/api/v2/getAllBranchesForZoekt/:parent/:repo/+/", srv.Handler(srv.ServeListAllBranchesForZoekt)) -// m.Add("GET", "/api/v2/getAllTagsForZoekt/:parent/:repo/+/", srv.Handler(srv.ServeListAllTagsForZoekt)) -// m.Add("GET", "/api/v2/getDirectoryTreeForZoekt/", srv.Handler(srv.TestHandler)) + if err := GetPlainBlob(path, repoPath, parent+"/"+repo, revision, w); err != nil { + http.Error(w, "Failed to fetch git blob", 500) + } +}