forked from tangled.org/core
this repo has no description
at master 2.1 kB view raw
1package xrpc 2 3import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "net/http" 8 9 securejoin "github.com/cyphar/filepath-securejoin" 10 "tangled.org/core/api/tangled" 11 "tangled.org/core/knotserver/git" 12 xrpcerr "tangled.org/core/xrpc/errors" 13) 14 15func (x *Xrpc) MergeCheck(w http.ResponseWriter, r *http.Request) { 16 l := x.Logger.With("handler", "MergeCheck") 17 fail := func(e xrpcerr.XrpcError) { 18 l.Error("failed", "kind", e.Tag, "error", e.Message) 19 writeError(w, e, http.StatusBadRequest) 20 } 21 22 var data tangled.RepoMergeCheck_Input 23 if err := json.NewDecoder(r.Body).Decode(&data); err != nil { 24 fail(xrpcerr.GenericError(err)) 25 return 26 } 27 28 did := data.Did 29 name := data.Name 30 31 if did == "" || name == "" { 32 fail(xrpcerr.GenericError(fmt.Errorf("did and name are required"))) 33 return 34 } 35 36 relativeRepoPath, err := securejoin.SecureJoin(did, name) 37 if err != nil { 38 fail(xrpcerr.GenericError(err)) 39 return 40 } 41 42 repoPath, err := securejoin.SecureJoin(x.Config.Repo.ScanPath, relativeRepoPath) 43 if err != nil { 44 fail(xrpcerr.GenericError(err)) 45 return 46 } 47 48 gr, err := git.Open(repoPath, data.Branch) 49 if err != nil { 50 fail(xrpcerr.GenericError(fmt.Errorf("failed to open repository: %w", err))) 51 return 52 } 53 54 err = gr.MergeCheck([]byte(data.Patch), data.Branch) 55 56 response := tangled.RepoMergeCheck_Output{ 57 Is_conflicted: false, 58 } 59 60 if err != nil { 61 var mergeErr *git.ErrMerge 62 if errors.As(err, &mergeErr) { 63 response.Is_conflicted = true 64 65 conflicts := make([]*tangled.RepoMergeCheck_ConflictInfo, len(mergeErr.Conflicts)) 66 for i, conflict := range mergeErr.Conflicts { 67 conflicts[i] = &tangled.RepoMergeCheck_ConflictInfo{ 68 Filename: conflict.Filename, 69 Reason: conflict.Reason, 70 } 71 } 72 response.Conflicts = conflicts 73 74 if mergeErr.Message != "" { 75 response.Message = &mergeErr.Message 76 } 77 } else { 78 response.Is_conflicted = true 79 errMsg := err.Error() 80 response.Error = &errMsg 81 } 82 } 83 84 w.Header().Set("Content-Type", "application/json") 85 w.WriteHeader(http.StatusOK) 86 json.NewEncoder(w).Encode(response) 87}