1package xrpc
2
3import (
4 "encoding/json"
5 "net/http"
6 "net/url"
7
8 "tangled.sh/tangled.sh/core/knotserver/git"
9 "tangled.sh/tangled.sh/core/types"
10 xrpcerr "tangled.sh/tangled.sh/core/xrpc/errors"
11)
12
13func (x *Xrpc) RepoDiff(w http.ResponseWriter, r *http.Request) {
14 repo := r.URL.Query().Get("repo")
15 repoPath, err := x.parseRepoParam(repo)
16 if err != nil {
17 writeError(w, err.(xrpcerr.XrpcError), http.StatusBadRequest)
18 return
19 }
20
21 refParam := r.URL.Query().Get("ref")
22 if refParam == "" {
23 writeError(w, xrpcerr.NewXrpcError(
24 xrpcerr.WithTag("InvalidRequest"),
25 xrpcerr.WithMessage("missing ref parameter"),
26 ), http.StatusBadRequest)
27 return
28 }
29
30 ref, _ := url.QueryUnescape(refParam)
31
32 gr, err := git.Open(repoPath, ref)
33 if err != nil {
34 writeError(w, xrpcerr.NewXrpcError(
35 xrpcerr.WithTag("RefNotFound"),
36 xrpcerr.WithMessage("repository or ref not found"),
37 ), http.StatusNotFound)
38 return
39 }
40
41 diff, err := gr.Diff()
42 if err != nil {
43 x.Logger.Error("getting diff", "error", err.Error())
44 writeError(w, xrpcerr.NewXrpcError(
45 xrpcerr.WithTag("RefNotFound"),
46 xrpcerr.WithMessage("failed to generate diff"),
47 ), http.StatusInternalServerError)
48 return
49 }
50
51 resp := types.RepoCommitResponse{
52 Ref: ref,
53 Diff: diff,
54 }
55
56 w.Header().Set("Content-Type", "application/json")
57 if err := json.NewEncoder(w).Encode(resp); err != nil {
58 x.Logger.Error("failed to encode response", "error", err)
59 writeError(w, xrpcerr.NewXrpcError(
60 xrpcerr.WithTag("InternalServerError"),
61 xrpcerr.WithMessage("failed to encode response"),
62 ), http.StatusInternalServerError)
63 return
64 }
65}