From c4bdb75d9c589c7b5a6cedd02da57390f838a91c Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 19 Nov 2024 10:15:25 +0100 Subject: [PATCH] [FIX] runbot_merge: `EmailMessage.get_content` misbehaves `get_content` round-trips the text part through `ascii` with `error=replace`, so if the input is not ascii it screws up tremendously, which leads to either failing to apply patches (the more likely situation) or corrupting the patches. `get_payload`, if called without `decode`, pretty much just returns the payload unless it needs a decoding pass (e.g. because it contains raw surrogates, but that should not be an issue for us). So this is really what we want. While at it, increase `patch`'s verbosity in case it can give us more info. --- runbot_merge/models/patcher.py | 6 +++--- runbot_merge/tests/test_patching.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/runbot_merge/models/patcher.py b/runbot_merge/models/patcher.py index 199dd02d..d7ad0dfd 100644 --- a/runbot_merge/models/patcher.py +++ b/runbot_merge/models/patcher.py @@ -99,7 +99,7 @@ def parse_format_patch(p: Patch) -> ParseResult: name, email = parseaddr(m['from']) author = (name, email, m['date']) msg = re.sub(r'^\[PATCH( \d+/\d+)?\] ', '', m['subject']) - body, _, rest = m.get_content().partition('---\n') + body, _, rest = m.get_payload().partition('---\n') if body: msg += '\n\n' + body @@ -300,14 +300,14 @@ class Patch(models.Model): tempfile.TemporaryDirectory() as tmpdir: tf.extractall(tmpdir) patch = subprocess.run( - ['patch', f'-p{prefix}', '-d', tmpdir], + ['patch', f'-p{prefix}', '--directory', tmpdir, '--verbose'], input=p.patch, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8', ) if patch.returncode: - raise PatchFailure(patch.stdout) + raise PatchFailure("\n---------\n".join(filter(None, [p.patch, patch.stdout.strip(), patch.stderr.strip()]))) new_tree = r.update_tree(self.target.name, files) sha = r.stdout().with_config(encoding='utf-8')\ diff --git a/runbot_merge/tests/test_patching.py b/runbot_merge/tests/test_patching.py index 020fbae4..2f2c8b64 100644 --- a/runbot_merge/tests/test_patching.py +++ b/runbot_merge/tests/test_patching.py @@ -2,7 +2,7 @@ import xmlrpc.client import pytest -from utils import Commit, read_tracking_value +from utils import Commit, read_tracking_value, matches # basic udiff / show style patch, updates `b` from `1` to `2` BASIC_UDIFF = """\ @@ -255,7 +255,7 @@ def test_patch_conflict(env, project, repo, users): [], ), ( "Unable to apply patch", - "

patching file b
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file b.rej

", + matches("$$"), # feedback from patch can vary [], ), ( False, '', [('active', 1, 0)]