[Git][reproducible-builds/diffoscope][master] 10 commits: Split out command-line formatting into a separate utility function.
Chris Lamb
gitlab at salsa.debian.org
Mon Oct 28 11:28:50 UTC 2019
Chris Lamb pushed to branch master at Reproducible Builds / diffoscope
Commits:
f784d2cd by Chris Lamb at 2019-10-26T13:40:36Z
Split out command-line formatting into a separate utility function.
- - - - -
ecccd718 by Chris Lamb at 2019-10-28T11:11:55Z
Truncate very long command lines when displaying them as an external source of data.
- - - - -
138aac1a by Chris Lamb at 2019-10-28T11:11:55Z
When printing an error from a command, format the command for the user.
- - - - -
c525ba9b by Chris Lamb at 2019-10-28T11:11:55Z
Add ability to pass (byte)string input to external commands.
- - - - -
07a013f8 by Chris Lamb at 2019-10-28T11:11:55Z
Don't pass our long script to parse R .rdb files via the command line; use stdin instead.
- - - - -
f8e436d9 by Chris Lamb at 2019-10-28T11:11:55Z
Use Rscript's --vanilla option over --no-environ as this also enables --no-save, --no-restore, --no-site-file and --no-init-file.
- - - - -
6a8251d9 by Chris Lamb at 2019-10-28T11:11:55Z
Use "exit code" over "return code" when referring to UNIX error codes in displayed differences.
- - - - -
f23f2b44 by Chris Lamb at 2019-10-28T11:11:55Z
Alias the internal R environment objects to its own variable.
- - - - -
91d70295 by Chris Lamb at 2019-10-28T11:12:30Z
Call R's "deparse" function to ensure that we do not error out and revert to a binary diff when processing .rdb files with internal "vector" types as they do not automatically coerce to strings.
- - - - -
b0e40108 by Chris Lamb at 2019-10-28T11:15:23Z
releasing package diffoscope version 129
- - - - -
7 changed files:
- debian/changelog
- diffoscope/__init__.py
- diffoscope/comparators/rdata.py
- diffoscope/comparators/utils/command.py
- diffoscope/comparators/utils/file.py
- diffoscope/difference.py
- + diffoscope/utils.py
Changes:
=====================================
debian/changelog
=====================================
@@ -1,8 +1,22 @@
-diffoscope (129) UNRELEASED; urgency=medium
-
- * WIP (generated upon release).
-
- -- Chris Lamb <lamby at debian.org> Fri, 25 Oct 2019 09:42:10 +0100
+diffoscope (129) unstable; urgency=medium
+
+ * Call R's "deparse" function to ensure that we do not error out and revert
+ to a binary diff when processing .rdb files with internal "vector" types as
+ they do not automatically coerce to strings.
+ * Add the ability to pass Python bytestrings to external commands and
+ pass our long script to parse R .rdb files using this new method over a
+ long command-line argument
+ * Use Rscript's --vanilla option over --no-environ as this also enables
+ --no-save, --no-restore, --no-site-file and --no-init-file.
+ * Improve command-line error messages:
+ - Split out formatting into a separate utility function.
+ - Truncate very long lines when displaying them as an external source
+ of data.
+ - When printing an error from a command, format the command for the user.
+ * Use "exit code" over "return code" when referring to UNIX error codes in
+ displayed differences.
+
+ -- Chris Lamb <lamby at debian.org> Mon, 28 Oct 2019 11:15:18 +0000
diffoscope (128) unstable; urgency=medium
=====================================
diffoscope/__init__.py
=====================================
@@ -17,4 +17,4 @@
# You should have received a copy of the GNU General Public License
# along with diffoscope. If not, see <https://www.gnu.org/licenses/>.
-VERSION = "128"
+VERSION = "129"
=====================================
diffoscope/comparators/rdata.py
=====================================
@@ -32,7 +32,7 @@ import binascii
HEADER = binascii.a2b_hex("580a000000020003")
-DUMP_RDB = r"""
+DUMP_RDB = rb"""
hideOutput = lazyLoad(commandArgs(TRUE));
for (x in ls(all.names = TRUE, sorted = TRUE)) {
@@ -42,8 +42,10 @@ for (x in ls(all.names = TRUE, sorted = TRUE)) {
if (typeof(obj) == "environment") {
cat("\n{\n", sep = "");
- for (y in ls(obj, all.names = TRUE, sorted = TRUE))
- cat(sprintf(" \"%s\" = \"%s\"\n", y, get(y, envir = obj)), sep = "");
+ for (y in ls(obj, all.names = TRUE, sorted = TRUE)) {
+ obj2 = get(y, envir = obj);
+ cat(sprintf(" \"%s\" = \"%s\"\n", y, deparse(obj2)), sep = "");
+ }
cat("}\n");
} else {
for (line in deparse(obj))
@@ -109,7 +111,7 @@ class RdsReader(Command):
def cmdline(self):
return [
'Rscript',
- '--no-environ',
+ '--vanilla',
'-e',
'args <- commandArgs(TRUE); readRDS(args[1])',
self.path,
@@ -138,7 +140,10 @@ class RdbReader(Command):
@tool_required('Rscript')
def cmdline(self):
- return ['Rscript', '--no-environ', '-e', DUMP_RDB, self.path]
+ return ['Rscript', '--vanilla', '-', self.path]
+
+ def input(self):
+ return DUMP_RDB
class RdbFile(File):
=====================================
diffoscope/comparators/utils/command.py
=====================================
@@ -22,6 +22,8 @@ import logging
import shlex
import subprocess
+from ...utils import format_cmdline
+
logger = logging.getLogger(__name__)
@@ -47,6 +49,7 @@ class Command(metaclass=abc.ABCMeta):
shell=False,
close_fds=True,
env=self.env(),
+ input=self.input(),
stdin=self._stdin,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
@@ -65,16 +68,9 @@ class Command(metaclass=abc.ABCMeta):
def cmdline(self):
raise NotImplementedError()
- def shell_cmdline(self):
- def fn(x):
- if x == self.path:
- return '{}'
- x = repr(x)
- if ' ' not in x:
- x = x[1:-1]
- return x
-
- return ' '.join(fn(x) for x in self.cmdline())
+ def shell_cmdline(self, *args, **kwargs):
+ kwargs.setdefault('replace', (self.path,))
+ return format_cmdline(self.cmdline(), *args, **kwargs)
def env(self):
return None # inherit parent environment by default
@@ -89,6 +85,9 @@ class Command(metaclass=abc.ABCMeta):
def terminate(self):
pass
+ def input(self):
+ pass
+
def _read_stderr(self):
if self.MASK_STDERR:
return ""
=====================================
diffoscope/comparators/utils/file.py
=====================================
@@ -30,6 +30,7 @@ from diffoscope.exc import (
ContainerExtractionError,
)
from diffoscope.tools import tool_required
+from diffoscope.utils import format_cmdline
from diffoscope.config import Config
from diffoscope.profiling import profile
from diffoscope.difference import Difference
@@ -451,7 +452,6 @@ class File(metaclass=abc.ABCMeta):
)
except subprocess.CalledProcessError as e:
difference = self.compare_bytes(other, source=source)
- cmd = ' '.join(e.cmd)
if difference is None:
return None
@@ -480,8 +480,10 @@ class File(metaclass=abc.ABCMeta):
suffix = '{} [...]'.format(suffix[:max_len])
difference.add_comment(
- "Command `{}` exited with return code {}.{}".format(
- cmd, e.returncode, suffix or " (No output)"
+ "Command `{}` exited with exit code {}.{}".format(
+ format_cmdline(e.cmd),
+ e.returncode,
+ suffix or " (No output)",
)
)
except RequiredToolNotFound as e:
=====================================
diffoscope/difference.py
=====================================
@@ -280,7 +280,7 @@ class Difference:
if 'source' not in kwargs:
source_cmd = command1 or command2
- kwargs['source'] = source_cmd.shell_cmdline()
+ kwargs['source'] = source_cmd.shell_cmdline(truncate=120)
try:
difference = Difference.from_feeder(
=====================================
diffoscope/utils.py
=====================================
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+#
+# diffoscope: in-depth comparison of files, archives, and directories
+#
+# Copyright © 2019 Chris Lamb <lamby at debian.org>
+#
+# diffoscope is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# diffoscope is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with diffoscope. If not, see <https://www.gnu.org/licenses/>.
+
+
+def format_cmdline(cmd, replace=(), truncate=None):
+ def fn(x):
+ if x in replace:
+ return '{}'
+ x = repr(x)
+ if ' ' not in x:
+ x = x[1:-1]
+ return x
+
+ result = ' '.join(fn(x) for x in cmd)
+
+ if truncate is not None and len(result) > truncate:
+ result = result[: truncate + 4] + " […]"
+
+ return result
View it on GitLab: https://salsa.debian.org/reproducible-builds/diffoscope/compare/cea78e6406d42b6e546936194c3960100f5053a6...b0e401085554974399192f1f9ec1dd00fb8e6095
--
View it on GitLab: https://salsa.debian.org/reproducible-builds/diffoscope/compare/cea78e6406d42b6e546936194c3960100f5053a6...b0e401085554974399192f1f9ec1dd00fb8e6095
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.reproducible-builds.org/pipermail/rb-commits/attachments/20191028/000d78f9/attachment.htm>
More information about the rb-commits
mailing list