forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
at master 2.6 kB view raw
1package xrpc 2 3import ( 4 "fmt" 5 "net/http" 6 7 "github.com/bluekeyes/go-gitdiff/gitdiff" 8 "tangled.org/core/knotserver/git" 9 "tangled.org/core/types" 10 xrpcerr "tangled.org/core/xrpc/errors" 11) 12 13func (x *Xrpc) RepoCompare(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 rev1 := r.URL.Query().Get("rev1") 22 if rev1 == "" { 23 writeError(w, xrpcerr.NewXrpcError( 24 xrpcerr.WithTag("InvalidRequest"), 25 xrpcerr.WithMessage("missing rev1 parameter"), 26 ), http.StatusBadRequest) 27 return 28 } 29 30 rev2 := r.URL.Query().Get("rev2") 31 if rev2 == "" { 32 writeError(w, xrpcerr.NewXrpcError( 33 xrpcerr.WithTag("InvalidRequest"), 34 xrpcerr.WithMessage("missing rev2 parameter"), 35 ), http.StatusBadRequest) 36 return 37 } 38 39 gr, err := git.PlainOpen(repoPath) 40 if err != nil { 41 writeError(w, xrpcerr.RepoNotFoundError, http.StatusNoContent) 42 return 43 } 44 45 commit1, err := gr.ResolveRevision(rev1) 46 if err != nil { 47 x.Logger.Error("error resolving revision 1", "msg", err.Error()) 48 writeError(w, xrpcerr.NewXrpcError( 49 xrpcerr.WithTag("RevisionNotFound"), 50 xrpcerr.WithMessage(fmt.Sprintf("error resolving revision %s", rev1)), 51 ), http.StatusBadRequest) 52 return 53 } 54 55 commit2, err := gr.ResolveRevision(rev2) 56 if err != nil { 57 x.Logger.Error("error resolving revision 2", "msg", err.Error()) 58 writeError(w, xrpcerr.NewXrpcError( 59 xrpcerr.WithTag("RevisionNotFound"), 60 xrpcerr.WithMessage(fmt.Sprintf("error resolving revision %s", rev2)), 61 ), http.StatusBadRequest) 62 return 63 } 64 65 rawPatch, formatPatch, err := gr.FormatPatch(commit1, commit2) 66 if err != nil { 67 x.Logger.Error("error comparing revisions", "msg", err.Error()) 68 writeError(w, xrpcerr.NewXrpcError( 69 xrpcerr.WithTag("CompareError"), 70 xrpcerr.WithMessage("error comparing revisions"), 71 ), http.StatusBadRequest) 72 return 73 } 74 75 var combinedPatch []*gitdiff.File 76 var combinedPatchRaw string 77 // we need the combined patch 78 if len(formatPatch) >= 2 { 79 diffTree, err := gr.DiffTree(commit1, commit2) 80 if err != nil { 81 x.Logger.Error("error comparing revisions", "msg", err.Error()) 82 } else { 83 combinedPatch = diffTree.Diff 84 combinedPatchRaw = diffTree.Patch 85 } 86 } 87 88 response := types.RepoFormatPatchResponse{ 89 Rev1: commit1.Hash.String(), 90 Rev2: commit2.Hash.String(), 91 FormatPatch: formatPatch, 92 FormatPatchRaw: rawPatch, 93 CombinedPatch: combinedPatch, 94 CombinedPatchRaw: combinedPatchRaw, 95 } 96 97 writeJson(w, response) 98}