Monorepo for Tangled
tangled.org
1package xrpc
2
3import (
4 "net/http"
5 "strconv"
6
7 "tangled.org/core/knotserver/git"
8 "tangled.org/core/types"
9 xrpcerr "tangled.org/core/xrpc/errors"
10)
11
12func (x *Xrpc) RepoLog(w http.ResponseWriter, r *http.Request) {
13 repo := r.URL.Query().Get("repo")
14 repoPath, err := x.parseRepoParam(repo)
15 if err != nil {
16 writeError(w, err.(xrpcerr.XrpcError), http.StatusBadRequest)
17 return
18 }
19
20 ref := r.URL.Query().Get("ref")
21
22 cursor := r.URL.Query().Get("cursor")
23
24 limit := 50 // default
25 if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
26 if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 100 {
27 limit = l
28 }
29 }
30
31 gr, err := git.Open(repoPath, ref)
32 if err != nil {
33 writeError(w, xrpcerr.RefNotFoundError, http.StatusNotFound)
34 return
35 }
36
37 offset := 0
38 if cursor != "" {
39 if o, err := strconv.Atoi(cursor); err == nil && o >= 0 {
40 offset = o
41 }
42 }
43
44 commits, err := gr.Commits(offset, limit)
45 if err != nil {
46 x.Logger.Error("fetching commits", "error", err.Error())
47 writeError(w, xrpcerr.NewXrpcError(
48 xrpcerr.WithTag("PathNotFound"),
49 xrpcerr.WithMessage("failed to read commit log"),
50 ), http.StatusNotFound)
51 return
52 }
53
54 total, err := gr.TotalCommits()
55 if err != nil {
56 x.Logger.Error("fetching total commits", "error", err.Error())
57 writeError(w, xrpcerr.NewXrpcError(
58 xrpcerr.WithTag("InternalServerError"),
59 xrpcerr.WithMessage("failed to fetch total commits"),
60 ), http.StatusNotFound)
61 return
62 }
63
64 tcommits := make([]types.Commit, len(commits))
65 for i, c := range commits {
66 tcommits[i].FromGoGitCommit(c)
67 }
68
69 // Create response using existing types.RepoLogResponse
70 response := types.RepoLogResponse{
71 Commits: tcommits,
72 Ref: ref,
73 Page: (offset / limit) + 1,
74 Total: total,
75 }
76
77 x.writeJson(w, response)
78}