forked from tangled.org/core
this repo has no description

knotserver/git: shared types and idomatic go

Changed files
+38 -26
knotserver
types
+8 -8
knotserver/git/merge.go
···
"github.com/go-git/go-git/v5/plumbing"
)
-
type MergeError struct {
+
type ErrMerge struct {
Message string
Conflicts []ConflictInfo
HasConflict bool
···
Reason string
}
-
func (e MergeError) Error() string {
+
func (e ErrMerge) Error() string {
if e.HasConflict {
return fmt.Sprintf("merge failed due to conflicts: %s (%d conflicts)", e.Message, len(e.Conflicts))
}
···
if err := cmd.Run(); err != nil {
if checkOnly {
conflicts := parseGitApplyErrors(stderr.String())
-
return &MergeError{
+
return &ErrMerge{
Message: "patch cannot be applied cleanly",
Conflicts: conflicts,
HasConflict: len(conflicts) > 0,
···
func (g *GitRepo) MergeCheck(patchData []byte, targetBranch string) error {
patchFile, err := g.createTempFileWithPatch(patchData)
if err != nil {
-
return &MergeError{
+
return &ErrMerge{
Message: err.Error(),
OtherError: err,
}
···
tmpDir, err := g.cloneRepository(targetBranch)
if err != nil {
-
return &MergeError{
+
return &ErrMerge{
Message: err.Error(),
OtherError: err,
}
···
func (g *GitRepo) Merge(patchData []byte, targetBranch string) error {
patchFile, err := g.createTempFileWithPatch(patchData)
if err != nil {
-
return &MergeError{
+
return &ErrMerge{
Message: err.Error(),
OtherError: err,
}
···
tmpDir, err := g.cloneRepository(targetBranch)
if err != nil {
-
return &MergeError{
+
return &ErrMerge{
Message: err.Error(),
OtherError: err,
}
···
pushCmd := exec.Command("git", "-C", tmpDir, "push")
if err := pushCmd.Run(); err != nil {
-
return &MergeError{
+
return &ErrMerge{
Message: "failed to push changes to bare repository",
OtherError: err,
}
+18 -18
knotserver/routes.go
···
notFound(w)
return
}
-
if err := gr.Merge([]byte(patch), branch); err != nil {
-
var mergeErr *git.MergeError
+
var mergeErr *git.ErrMerge
if errors.As(err, &mergeErr) {
-
conflictDetails := make([]map[string]interface{}, len(mergeErr.Conflicts))
+
conflicts := make([]types.ConflictInfo, len(mergeErr.Conflicts))
for i, conflict := range mergeErr.Conflicts {
-
conflictDetails[i] = map[string]interface{}{
-
"filename": conflict.Filename,
-
"reason": conflict.Reason,
+
conflicts[i] = types.ConflictInfo{
+
Filename: conflict.Filename,
+
Reason: conflict.Reason,
}
}
-
response := map[string]interface{}{
-
"message": mergeErr.Message,
-
"conflicts": conflictDetails,
+
response := types.MergeCheckResponse{
+
IsConflicted: true,
+
Conflicts: conflicts,
+
Message: mergeErr.Message,
}
writeConflict(w, response)
h.l.Error("git: merge conflict", "handler", "Merge", "error", mergeErr)
···
return
}
-
var mergeErr *git.MergeError
+
var mergeErr *git.ErrMerge
if errors.As(err, &mergeErr) {
-
conflictDetails := make([]map[string]interface{}, len(mergeErr.Conflicts))
+
conflicts := make([]types.ConflictInfo, len(mergeErr.Conflicts))
for i, conflict := range mergeErr.Conflicts {
-
conflictDetails[i] = map[string]interface{}{
-
"filename": conflict.Filename,
-
"reason": conflict.Reason,
+
conflicts[i] = types.ConflictInfo{
+
Filename: conflict.Filename,
+
Reason: conflict.Reason,
}
}
-
response := map[string]interface{}{
-
"message": mergeErr.Message,
-
"conflicts": conflictDetails,
+
response := types.MergeCheckResponse{
+
IsConflicted: true,
+
Conflicts: conflicts,
+
Message: mergeErr.Message,
}
writeConflict(w, response)
h.l.Error("git: merge conflict", "handler", "MergeCheck", "error", mergeErr.Error())
return
}
-
writeError(w, err.Error(), http.StatusInternalServerError)
h.l.Error("git: failed to check merge", "handler", "MergeCheck", "error", err.Error())
}
+12
types/merge.go
···
package types
+
+
type ConflictInfo struct {
+
Filename string `json:"filename"`
+
Reason string `json:"reason"`
+
}
+
+
type MergeCheckResponse struct {
+
IsConflicted bool `json:"is_conflicted"`
+
Conflicts []ConflictInfo `json:"conflicts"`
+
Message string `json:"message"`
+
Error string `json:"error"`
+
}