[Reproducible-commits] [diffoscope] 07/21: Call tar to retrieve Tar archive metadata

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 be9a8657441449afe538cdd1445fe99db3d847fb
Author: Jérémy Bobbio <lunar at debian.org>
Date:   Sat Sep 19 18:24:01 2015 +0200

    Call tar to retrieve Tar archive metadata
    
    We used to rely on the Python tarfile module to get a listing with the content
    of Tar archives. The interface of the list() method is a bit awkward to use as
    the results are always written on stdout. Replacing sys.stdout on the fly is
    not thread-safe and has problems with how Python 3 handles strings.
    
    So let's call the system `tar`. It makes the implementation more consistent with
    other comparators and we get even more accurate output.
    
    As tar is an essential package on Debian, we filter it out from the list of
    Recommends.
---
 debian/rules                         |  2 +-
 diffoscope/__init__.py               |  1 +
 diffoscope/comparators/deb.py        |  8 ++------
 diffoscope/comparators/tar.py        | 23 +++++++----------------
 tests/comparators/test_utils.py      |  2 +-
 tests/data/tar_listing_expected_diff | 16 ++++++++--------
 6 files changed, 20 insertions(+), 32 deletions(-)

diff --git a/debian/rules b/debian/rules
index c868422..4595b44 100755
--- a/debian/rules
+++ b/debian/rules
@@ -14,7 +14,7 @@ override_dh_auto_build:
 
 override_dh_gencontrol:
 	TOOLS="$$(bin/diffoscope --list-tools | tail -n 1 | \
-		sed -e 's/\(^\| \)\(coreutils\|diffutils\|e2fsprogs\|findutils\|gzip\)\(,\|$$\)//g')"; \
+		sed -e 's/\(^\| \)\(coreutils\|diffutils\|e2fsprogs\|findutils\|gzip\|tar\)\(,\|$$\)//g')"; \
 		[ -n "$$TOOLS" ] || { echo '--list-tools failed' >&2; exit 1; }; \
 		echo "diffoscope:Recommends=$$TOOLS" >> debian/diffoscope.substvars
 	dh_gencontrol -O--buildsystem=pybuild
diff --git a/diffoscope/__init__.py b/diffoscope/__init__.py
index 78dfcb9..d8adb0c 100644
--- a/diffoscope/__init__.py
+++ b/diffoscope/__init__.py
@@ -60,6 +60,7 @@ class RequiredToolNotFound(Exception):
                 , 'sng':        { 'debian': 'sng' }
                 , 'stat':       { 'debian': 'coreutils' }
                 , 'sqlite3':    { 'debian': 'sqlite3'}
+                , 'tar':        { 'debian': 'tar'}
                 , 'unsquashfs': { 'debian': 'squashfs-tools' }
                 , 'xxd':        { 'debian': 'vim-common' }
                 , 'xz':         { 'debian': 'xz-utils' }
diff --git a/diffoscope/comparators/deb.py b/diffoscope/comparators/deb.py
index 157aafb..a26f654 100644
--- a/diffoscope/comparators/deb.py
+++ b/diffoscope/comparators/deb.py
@@ -27,7 +27,7 @@ from diffoscope.difference import Difference
 from diffoscope.comparators.binary import File, needs_content
 from diffoscope.comparators.utils import \
     Archive, ArchiveMember, get_ar_content
-from diffoscope.comparators.tar import TarContainer, get_tar_listing
+from diffoscope.comparators.tar import TarContainer, TarListing
 
 AR_EXTRACTION_BUFFER_SIZE = 32768
 
@@ -153,10 +153,6 @@ class DebDataTarFile(File):
         ignore_files = self.container.source.container.source.files_with_same_content_in_data
         with DebTarContainer(self, ignore_files).open() as my_container, \
              DebTarContainer(other, ignore_files).open() as other_container:
-            # look up differences in file list and file metadata
-            my_listing = get_tar_listing(my_container.archive)
-            other_listing = get_tar_listing(other_container.archive)
-            differences.append(Difference.from_unicode(
-                                  my_listing, other_listing, self.name, other.name, source="metadata"))
+            differences.append(Difference.from_command(TarListing, self.path, other.path))
             differences.extend(my_container.compare(other_container))
         return differences
diff --git a/diffoscope/comparators/tar.py b/diffoscope/comparators/tar.py
index 19b025f..b45a1cd 100644
--- a/diffoscope/comparators/tar.py
+++ b/diffoscope/comparators/tar.py
@@ -18,7 +18,6 @@
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
 from contextlib import contextmanager
-from io import BytesIO
 import os.path
 import re
 import stat
@@ -30,7 +29,7 @@ from diffoscope.comparators.binary import File, needs_content
 from diffoscope.comparators.device import Device
 from diffoscope.comparators.directory import Directory
 from diffoscope.comparators.symlink import Symlink
-from diffoscope.comparators.utils import Archive, ArchiveMember
+from diffoscope.comparators.utils import Archive, ArchiveMember, Command, tool_required
 
 class TarMember(ArchiveMember):
     def is_directory(self):
@@ -125,15 +124,11 @@ class TarContainer(Archive):
             return TarMember(self, member_name)
 
 
-def get_tar_listing(tar):
-    orig_stdout = sys.stdout
-    output = BytesIO()
-    try:
-        sys.stdout = output
-        tar.list(verbose=True)
-        return output.getvalue().decode('utf-8')
-    finally:
-        sys.stdout = orig_stdout
+class TarListing(Command):
+    @tool_required('tar')
+    def cmdline(self):
+        return ['tar', '--full-time', '-tvf', self.path]
+
 
 class TarFile(File):
     RE_FILE_TYPE = re.compile(r'\btar archive\b')
@@ -147,10 +142,6 @@ class TarFile(File):
         differences = []
         with TarContainer(self).open() as my_container, \
              TarContainer(other).open() as other_container:
-            # look up differences in file list and file metadata
-            my_listing = get_tar_listing(my_container.archive)
-            other_listing = get_tar_listing(other_container.archive)
-            differences.append(Difference.from_unicode(
-                                  my_listing, other_listing, self.name, other.name, source="metadata"))
+            differences.append(Difference.from_command(TarListing, self.path, other.path))
             differences.extend(my_container.compare(other_container))
         return differences
diff --git a/tests/comparators/test_utils.py b/tests/comparators/test_utils.py
index 6dda4e0..957e1e7 100644
--- a/tests/comparators/test_utils.py
+++ b/tests/comparators/test_utils.py
@@ -62,7 +62,7 @@ def test_no_fuzzy_matching(monkeypatch, fuzzy_tar_in_tar1, fuzzy_tar_in_tar2):
     monkeypatch.setattr(Config, 'fuzzy_threshold', 0)
     difference = fuzzy_tar_in_tar1.compare(fuzzy_tar_in_tar2)
     assert len(difference.details) == 1
-    assert difference.details[0].source1 == 'metadata'
+    assert difference.details[0].source1 == 'tar --full-time -tvf {}'
 
 def test_no_fuzzy_matching_new_file(monkeypatch, fuzzy_tar_in_tar1, fuzzy_tar_in_tar2):
     monkeypatch.setattr(Config, 'fuzzy_threshold', 0)
diff --git a/tests/data/tar_listing_expected_diff b/tests/data/tar_listing_expected_diff
index 505d11a..b91dc34 100644
--- a/tests/data/tar_listing_expected_diff
+++ b/tests/data/tar_listing_expected_diff
@@ -1,9 +1,9 @@
 @@ -1,4 +1,4 @@
---rwxr-xr-x lunar/lunar          0 2015-06-29 15:49:09 dir/
---rw-r--r-- lunar/lunar        446 2015-06-29 15:49:09 dir/text
---rw-r--r-- root/root        1,3 2015-06-29 15:49:09 dir/null
---rwxrwxrwx lunar/lunar          0 2015-06-29 15:49:09 dir/link -> broken
-+-rwxr-xr-x lunar/lunar          0 2015-06-29 15:49:41 dir/
-+-rw-r--r-- lunar/lunar        671 2015-06-29 15:49:41 dir/text
-+-rw-r--r-- root/root        1,3 2015-06-29 15:49:41 dir/null
-+-rwxrwxrwx lunar/lunar          0 2015-06-29 15:49:41 dir/link -> really-broken
+-drwxr-xr-x lunar/lunar       0 2015-06-29 15:49:09 dir/
+--rw-r--r-- lunar/lunar     446 2015-06-29 15:49:09 dir/text
+-crw-r--r-- root/root       1,3 2015-06-29 15:49:09 dir/null
+-lrwxrwxrwx lunar/lunar       0 2015-06-29 15:49:09 dir/link -> broken
++drwxr-xr-x lunar/lunar       0 2015-06-29 15:49:41 dir/
++-rw-r--r-- lunar/lunar     671 2015-06-29 15:49:41 dir/text
++crw-r--r-- root/root       1,3 2015-06-29 15:49:41 dir/null
++lrwxrwxrwx lunar/lunar       0 2015-06-29 15:49:41 dir/link -> really-broken

-- 
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