aboutsummaryrefslogtreecommitdiff
path: root/lmtp_handle_patch.go
diff options
context:
space:
mode:
authorRunxi Yu <me@runxiyu.org>2025-04-02 15:06:15 +0800
committerRunxi Yu <me@runxiyu.org>2025-04-02 15:06:15 +0800
commite93df9b5bc32df01eb90e32b7f0bb1001cf18c53 (patch)
tree05e04f190f16a00db0f955dd3044dceabe2f9892 /lmtp_handle_patch.go
parentDB: Grammar (diff)
downloadforge-e93df9b5bc32df01eb90e32b7f0bb1001cf18c53.tar.gz
forge-e93df9b5bc32df01eb90e32b7f0bb1001cf18c53.tar.zst
forge-e93df9b5bc32df01eb90e32b7f0bb1001cf18c53.zip
LMTP: Fix patch handling (\r\n, mbox format, double-Wait)v0.1.10
Diffstat (limited to 'lmtp_handle_patch.go')
-rw-r--r--lmtp_handle_patch.go35
1 files changed, 18 insertions, 17 deletions
diff --git a/lmtp_handle_patch.go b/lmtp_handle_patch.go
index d69424b..6bcb272 100644
--- a/lmtp_handle_patch.go
+++ b/lmtp_handle_patch.go
@@ -7,46 +7,47 @@ import (
"bytes"
"crypto/rand"
"encoding/hex"
+ "fmt"
+ "io"
"os"
"os/exec"
"strings"
"time"
"github.com/bluekeyes/go-gitdiff/gitdiff"
- "github.com/emersion/go-message"
"github.com/go-git/go-git/v5"
)
-func lmtpHandlePatch(session *lmtpSession, groupPath []string, repoName string, email *message.Entity) (err error) {
+func lmtpHandlePatch(session *lmtpSession, groupPath []string, repoName string, mbox io.Reader) (err error) {
var diffFiles []*gitdiff.File
var preamble string
- if diffFiles, preamble, err = gitdiff.Parse(email.Body); err != nil {
- return
+ if diffFiles, preamble, err = gitdiff.Parse(mbox); err != nil {
+ return fmt.Errorf("failed to parse patch: %w", err)
}
var header *gitdiff.PatchHeader
if header, err = gitdiff.ParsePatchHeader(preamble); err != nil {
- return
+ return fmt.Errorf("failed to parse patch headers: %w", err)
}
var repo *git.Repository
var fsPath string
repo, _, _, fsPath, err = openRepo(session.ctx, groupPath, repoName)
if err != nil {
- return
+ return fmt.Errorf("failed to open repo: %w", err)
}
headRef, err := repo.Head()
if err != nil {
- return
+ return fmt.Errorf("failed to get repo head hash: %w", err)
}
headCommit, err := repo.CommitObject(headRef.Hash())
if err != nil {
- return
+ return fmt.Errorf("failed to get repo head commit: %w", err)
}
headTree, err := headCommit.Tree()
if err != nil {
- return
+ return fmt.Errorf("failed to get repo head tree: %w", err)
}
headTreeHash := headTree.Hash.String()
@@ -55,17 +56,17 @@ func lmtpHandlePatch(session *lmtpSession, groupPath []string, repoName string,
for _, diffFile := range diffFiles {
sourceFile, err := headTree.File(diffFile.OldName)
if err != nil {
- return err
+ return fmt.Errorf("failed to get file at old name %#v: %w", diffFile.OldName, err)
}
sourceString, err := sourceFile.Contents()
if err != nil {
- return err
+ return fmt.Errorf("failed to get contents: %w", err)
}
sourceBuf := bytes.NewReader(stringToBytes(sourceString))
var patchedBuf bytes.Buffer
if err := gitdiff.Apply(&patchedBuf, sourceBuf, diffFile); err != nil {
- return err
+ return fmt.Errorf("failed to apply patch: %w", err)
}
var hashBuf bytes.Buffer
@@ -78,13 +79,13 @@ func lmtpHandlePatch(session *lmtpSession, groupPath []string, repoName string,
cmd.Stdout = &hashBuf
cmd.Stdin = &patchedBuf
if err := cmd.Run(); err != nil {
- return err
+ return fmt.Errorf("failed to run git hash-object: %w", err)
}
newHashStr := strings.TrimSpace(hashBuf.String())
newHash, err := hex.DecodeString(newHashStr)
if err != nil {
- return err
+ return fmt.Errorf("failed to decode hex string from git: %w", err)
}
blobUpdates[diffFile.NewName] = newHash
@@ -95,7 +96,7 @@ func lmtpHandlePatch(session *lmtpSession, groupPath []string, repoName string,
newTreeSha, err := buildTreeRecursive(session.ctx, fsPath, headTreeHash, blobUpdates)
if err != nil {
- return err
+ return fmt.Errorf("failed to recursively build a tree: %w", err)
}
commitMsg := header.Title
@@ -115,7 +116,7 @@ func lmtpHandlePatch(session *lmtpSession, groupPath []string, repoName string,
var commitOut bytes.Buffer
commitCmd.Stdout = &commitOut
if err := commitCmd.Run(); err != nil {
- return err
+ return fmt.Errorf("failed to commit tree: %w", err)
}
newCommitSha := strings.TrimSpace(commitOut.String())
@@ -124,7 +125,7 @@ func lmtpHandlePatch(session *lmtpSession, groupPath []string, repoName string,
refCmd := exec.CommandContext(session.ctx, "git", "update-ref", "refs/heads/contrib/"+newBranchName, newCommitSha) //#nosec G204
refCmd.Env = append(os.Environ(), "GIT_DIR="+fsPath)
if err := refCmd.Run(); err != nil {
- return err
+ return fmt.Errorf("failed to update ref: %w", err)
}
return nil