forked from tangled.org/core
this repo has no description
at master 2.7 kB view raw
1package xrpc 2 3import ( 4 "encoding/json" 5 "net/http" 6 "net/url" 7 "strconv" 8 9 "tangled.sh/tangled.sh/core/knotserver/git" 10 "tangled.sh/tangled.sh/core/types" 11 xrpcerr "tangled.sh/tangled.sh/core/xrpc/errors" 12) 13 14func (x *Xrpc) RepoLog(w http.ResponseWriter, r *http.Request) { 15 repo := r.URL.Query().Get("repo") 16 repoPath, err := x.parseRepoParam(repo) 17 if err != nil { 18 writeError(w, err.(xrpcerr.XrpcError), http.StatusBadRequest) 19 return 20 } 21 22 refParam := r.URL.Query().Get("ref") 23 if refParam == "" { 24 writeError(w, xrpcerr.NewXrpcError( 25 xrpcerr.WithTag("InvalidRequest"), 26 xrpcerr.WithMessage("missing ref parameter"), 27 ), http.StatusBadRequest) 28 return 29 } 30 31 path := r.URL.Query().Get("path") 32 cursor := r.URL.Query().Get("cursor") 33 34 limit := 50 // default 35 if limitStr := r.URL.Query().Get("limit"); limitStr != "" { 36 if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 100 { 37 limit = l 38 } 39 } 40 41 ref, err := url.QueryUnescape(refParam) 42 if err != nil { 43 writeError(w, xrpcerr.NewXrpcError( 44 xrpcerr.WithTag("InvalidRequest"), 45 xrpcerr.WithMessage("invalid ref parameter"), 46 ), http.StatusBadRequest) 47 return 48 } 49 50 gr, err := git.Open(repoPath, ref) 51 if err != nil { 52 writeError(w, xrpcerr.NewXrpcError( 53 xrpcerr.WithTag("RefNotFound"), 54 xrpcerr.WithMessage("repository or ref not found"), 55 ), http.StatusNotFound) 56 return 57 } 58 59 offset := 0 60 if cursor != "" { 61 if o, err := strconv.Atoi(cursor); err == nil && o >= 0 { 62 offset = o 63 } 64 } 65 66 commits, err := gr.Commits(offset, limit) 67 if err != nil { 68 x.Logger.Error("fetching commits", "error", err.Error()) 69 writeError(w, xrpcerr.NewXrpcError( 70 xrpcerr.WithTag("PathNotFound"), 71 xrpcerr.WithMessage("failed to read commit log"), 72 ), http.StatusNotFound) 73 return 74 } 75 76 total, err := gr.TotalCommits() 77 if err != nil { 78 x.Logger.Error("fetching total commits", "error", err.Error()) 79 writeError(w, xrpcerr.NewXrpcError( 80 xrpcerr.WithTag("InternalServerError"), 81 xrpcerr.WithMessage("failed to fetch total commits"), 82 ), http.StatusNotFound) 83 return 84 } 85 86 // Create response using existing types.RepoLogResponse 87 response := types.RepoLogResponse{ 88 Commits: commits, 89 Ref: ref, 90 Page: (offset / limit) + 1, 91 PerPage: limit, 92 Total: total, 93 } 94 95 if path != "" { 96 response.Description = path 97 } 98 99 response.Log = true 100 101 // Write JSON response directly 102 w.Header().Set("Content-Type", "application/json") 103 if err := json.NewEncoder(w).Encode(response); err != nil { 104 x.Logger.Error("failed to encode response", "error", err) 105 writeError(w, xrpcerr.NewXrpcError( 106 xrpcerr.WithTag("InternalServerError"), 107 xrpcerr.WithMessage("failed to encode response"), 108 ), http.StatusInternalServerError) 109 return 110 } 111}