[Reproducible-commits] [diffoscope] 13/21: Propagate failure of commands feeding diff
Jérémy Bobbio
lunar at moszumanska.debian.org
Mon Sep 21 17:39:27 UTC 2015
This is an automated email from the git hooks/post-receive script.
lunar pushed a commit to branch master
in repository diffoscope.
commit f2d751b0c498c929054c0d9978be11820bf4673d
Author: Jérémy Bobbio <lunar at debian.org>
Date: Sat Sep 19 23:58:23 2015 +0200
Propagate failure of commands feeding diff
We now check the return code once we are done with a command feeding
diff. In case of failure we raise an exception using CalledProcessError.
CalledProcessError assumes it will get the raw output. So we now capture
stderr in a BytesIO, make the attribute available, and only decode its content
when required.
If the command has received SIGTERM it's probably because we terminate commands
that linger slightly too long after we are done reading the output. So we don't
want to consider this an error. Ideally we should wait a little longer for
them to properly shut down. That will be easily doable in Python 3.3+.
---
diffoscope/comparators/utils.py | 12 ++++++++----
diffoscope/difference.py | 5 ++++-
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/diffoscope/comparators/utils.py b/diffoscope/comparators/utils.py
index d339aed..1997b00 100644
--- a/diffoscope/comparators/utils.py
+++ b/diffoscope/comparators/utils.py
@@ -19,7 +19,7 @@
from abc import ABCMeta, abstractmethod
from contextlib import contextmanager
-from io import StringIO
+from io import BytesIO
from itertools import starmap
# The following would be shutil.which in Python 3.3
import os
@@ -69,7 +69,7 @@ class Command(object):
else:
self._stdin_feeder = None
self._process.stdin.close()
- self._stderr = StringIO()
+ self._stderr = BytesIO()
self._stderr_line_count = 0
self._stderr_reader = Thread(target=self._read_stderr)
self._stderr_reader.daemon = True
@@ -100,7 +100,7 @@ class Command(object):
if self._stdin_feeder:
self._stdin_feeder.join()
self._stderr_reader.join()
- self._process.wait()
+ return self._process.wait()
MAX_STDERR_LINES = 50
@@ -115,7 +115,11 @@ class Command(object):
@property
def stderr_content(self):
- return self._stderr.getvalue()
+ return self._stderr.getvalue().decode('utf-8', errors='replace')
+
+ @property
+ def stderr(self):
+ return self._stderr
@property
def stdout(self):
diff --git a/diffoscope/difference.py b/diffoscope/difference.py
index 18d5d27..640b31d 100644
--- a/diffoscope/difference.py
+++ b/diffoscope/difference.py
@@ -22,6 +22,7 @@ from io import StringIO
import os
import os.path
import re
+import signal
import subprocess
import sys
import traceback
@@ -246,7 +247,9 @@ def make_feeder_from_command(command):
end_nl = make_feeder_from_file(command.stdout, command.filter)(out_file)
if command.poll() is None:
command.terminate()
- command.wait()
+ returncode = command.wait()
+ if returncode not in (0, -signal.SIGTERM):
+ raise subprocess.CalledProcessError(returncode, command.cmdline(), output=command.stderr.getvalue())
return end_nl
return feeder
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git
More information about the Reproducible-commits
mailing list