[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