This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knotserver / xrpc / merge_check.go
2.3 kB 93 lines
1package xrpc 2 3import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "net/http" 8 9 "tangled.org/core/api/tangled" 10 "tangled.org/core/knotserver/git" 11 "tangled.org/core/patchutil" 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 _, repoPath, err := x.resolveRepoDID(data.Repo, did, name) 37 if err != nil { 38 l.Error("failed to resolve repo", "err", err) 39 fail(xrpcerr.RepoNotFoundError) 40 return 41 } 42 43 gr, err := git.Open(repoPath, data.Branch) 44 if err != nil { 45 fail(xrpcerr.GenericError(fmt.Errorf("failed to open repository: %w", err))) 46 return 47 } 48 if x.Sandbox != nil { 49 gr = gr.WithSandbox(x.Sandbox) 50 } 51 52 mo := git.MergeOptions{} 53 mo.CommitMessage = "merge check" 54 mo.CommitterName = x.Config.Git.UserName 55 mo.CommitterEmail = x.Config.Git.UserEmail 56 mo.FormatPatch = patchutil.IsFormatPatch(data.Patch) 57 58 err = gr.MergeCheckWithOptions(data.Patch, data.Branch, mo) 59 60 response := tangled.RepoMergeCheck_Output{ 61 Is_conflicted: false, 62 } 63 64 if err != nil { 65 var mergeErr *git.ErrMerge 66 if errors.As(err, &mergeErr) { 67 response.Is_conflicted = true 68 69 conflicts := make([]*tangled.RepoMergeCheck_ConflictInfo, len(mergeErr.Conflicts)) 70 for i, conflict := range mergeErr.Conflicts { 71 conflicts[i] = &tangled.RepoMergeCheck_ConflictInfo{ 72 Filename: conflict.Filename, 73 Reason: conflict.Reason, 74 } 75 } 76 response.Conflicts = conflicts 77 78 if mergeErr.Message != "" { 79 response.Message = &mergeErr.Message 80 } 81 } else { 82 response.Is_conflicted = true 83 errMsg := err.Error() 84 response.Error = &errMsg 85 } 86 } 87 88 l.Debug("merge check response", "isConflicted", response.Is_conflicted, "err", response.Error, "conflicts", response.Conflicts) 89 90 w.Header().Set("Content-Type", "application/json") 91 w.WriteHeader(http.StatusOK) 92 json.NewEncoder(w).Encode(response) 93}