[diffoscope] 07/09: Respect order of containers when performing comparisons

Jérémy Bobbio lunar at moszumanska.debian.org
Tue Jan 19 18:22:31 CET 2016


This is an automated email from the git hooks/post-receive script.

lunar pushed a commit to branch master
in repository diffoscope.

commit d88a4f71487d7f663619e00cf8e42faf26caa120
Author: Jérémy Bobbio <lunar at debian.org>
Date:   Tue Jan 19 14:28:36 2016 +0000

    Respect order of containers when performing comparisons
    
    It doesn't matter that much, but it makes the output somewhat nicer.
    This feels much better when you are expected things to be in a certain
    order, like ELF sections.
---
 diffoscope/comparators/bzip2.py    |  3 ++-
 diffoscope/comparators/debian.py   |  3 ++-
 diffoscope/comparators/dex.py      |  3 ++-
 diffoscope/comparators/fsimage.py  |  3 ++-
 diffoscope/comparators/gzip.py     |  3 ++-
 diffoscope/comparators/squashfs.py |  3 ++-
 diffoscope/comparators/utils.py    | 24 +++++++++++++++---------
 diffoscope/comparators/xz.py       |  3 ++-
 tests/comparators/test_epub.py     | 12 ++++++------
 tests/comparators/test_ipk.py      |  4 ++--
 tests/comparators/test_iso9660.py  | 10 +++++-----
 tests/comparators/test_tar.py      | 14 +++++++-------
 tests/data/epub_expected_diffs     | 28 ++++++++++++++--------------
 13 files changed, 63 insertions(+), 50 deletions(-)

diff --git a/diffoscope/comparators/bzip2.py b/diffoscope/comparators/bzip2.py
index ff63ef1..797b649 100644
--- a/diffoscope/comparators/bzip2.py
+++ b/diffoscope/comparators/bzip2.py
@@ -17,6 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
+from collections import OrderedDict
 import os.path
 import re
 import subprocess
@@ -34,7 +35,7 @@ class Bzip2Container(Archive):
         pass
 
     def get_members(self):
-        return {'bzip2-content': self.get_member(self.get_member_names()[0])}
+        return OrderedDict({'bzip2-content': self.get_member(self.get_member_names()[0])})
 
     def get_member_names(self):
         return [get_compressed_content_name(self.source.path, '.bz2')]
diff --git a/diffoscope/comparators/debian.py b/diffoscope/comparators/debian.py
index 14a3480..495df66 100644
--- a/diffoscope/comparators/debian.py
+++ b/diffoscope/comparators/debian.py
@@ -17,6 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
+from collections import OrderedDict
 from contextlib import contextmanager
 from functools import partial
 import hashlib
@@ -84,7 +85,7 @@ class DebControlContainer(Container):
             return re.compile(re.escape(version))
 
     def get_members(self):
-        return {self._trim_version_number(name): self.get_member(name) for name in self.get_member_names()}
+        return OrderedDict([(self._trim_version_number(name), self.get_member(name)) for name in self.get_member_names()])
 
     def get_member_names(self):
         return [d['name'] for d in self.source.deb822.get('Files')]
diff --git a/diffoscope/comparators/dex.py b/diffoscope/comparators/dex.py
index 9ad4cb5..447c497 100644
--- a/diffoscope/comparators/dex.py
+++ b/diffoscope/comparators/dex.py
@@ -17,6 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
+from collections import OrderedDict
 import re
 import os.path
 import subprocess
@@ -38,7 +39,7 @@ class DexContainer(Archive):
         pass
 
     def get_members(self):
-        return {'dex-content': self.get_member(self.get_member_names()[0])}
+        return OrderedDict({'dex-content': self.get_member(self.get_member_names()[0])})
 
     def get_member_names(self):
         return [get_compressed_content_name(self.source.path, '.dex') + '.jar']
diff --git a/diffoscope/comparators/fsimage.py b/diffoscope/comparators/fsimage.py
index 8bcd236..90f39f0 100644
--- a/diffoscope/comparators/fsimage.py
+++ b/diffoscope/comparators/fsimage.py
@@ -17,6 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
+from collections import OrderedDict
 import re
 import os.path
 try:
@@ -54,7 +55,7 @@ class FsImageContainer(Archive):
         self.g.close()
 
     def get_members(self):
-        return {'fsimage-content': self.get_member(self.get_member_names()[0])}
+        return OrderedDict({'fsimage-content': self.get_member(self.get_member_names()[0])})
 
     def get_member_names(self):
         return [os.path.basename(self.source.path) + '.tar']
diff --git a/diffoscope/comparators/gzip.py b/diffoscope/comparators/gzip.py
index a8b19c8..3ddfa26 100644
--- a/diffoscope/comparators/gzip.py
+++ b/diffoscope/comparators/gzip.py
@@ -17,6 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
+from collections import OrderedDict
 import re
 import subprocess
 import os.path
@@ -34,7 +35,7 @@ class GzipContainer(Archive):
         pass
 
     def get_members(self):
-        return {'gzip-content': self.get_member(self.get_member_names()[0])}
+        return OrderedDict({'gzip-content': self.get_member(self.get_member_names()[0])})
 
     def get_member_names(self):
         return [get_compressed_content_name(self.source.path, '.gz')]
diff --git a/diffoscope/comparators/squashfs.py b/diffoscope/comparators/squashfs.py
index 7f7b1be..1231436 100644
--- a/diffoscope/comparators/squashfs.py
+++ b/diffoscope/comparators/squashfs.py
@@ -18,6 +18,7 @@
 # You should have received a copy of the GNU General Public License
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
+from collections import OrderedDict
 from contextlib import contextmanager
 import re
 import subprocess
@@ -212,7 +213,7 @@ class SquashfsContainer(Archive):
                 logger.warning('Unknown squashfs entry: %s', line)
 
     def open_archive(self):
-        return {kwargs['member_name']: (cls, kwargs) for cls, kwargs in self.entries(self.source.path)}
+        return OrderedDict([(kwargs['member_name'], (cls, kwargs)) for cls, kwargs in self.entries(self.source.path)])
 
     def close_archive(self):
         pass
diff --git a/diffoscope/comparators/utils.py b/diffoscope/comparators/utils.py
index b6d0cc5..df34e67 100644
--- a/diffoscope/comparators/utils.py
+++ b/diffoscope/comparators/utils.py
@@ -18,6 +18,7 @@
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
 from abc import ABCMeta, abstractmethod
+from collections import OrderedDict
 from contextlib import contextmanager
 from io import BytesIO
 from itertools import starmap
@@ -174,7 +175,7 @@ class Container(object, metaclass=ABCMeta):
 
     def get_members(self):
         """Returns a directory. The key is what is used to match when comparing containers."""
-        return {name: self.get_member(name) for name in self.get_member_names()}
+        return OrderedDict([(name, self.get_member(name)) for name in self.get_member_names()])
 
     def lookup_file(self, *names):
         """Try to fetch a specific file by digging in containers."""
@@ -202,19 +203,24 @@ class Container(object, metaclass=ABCMeta):
 
     def comparisons(self, other):
         my_members = self.get_members()
+        my_reminders = OrderedDict()
         other_members = other.get_members()
-        for name in sorted(my_members.keys() & other_members.keys()):
-            yield my_members.pop(name), other_members.pop(name), NO_COMMENT
+        # keep it sorted like my members
+        while my_members:
+            my_member_name, my_member = my_members.popitem(last=False)
+            if my_member_name in other_members:
+                yield my_member, other_members.pop(my_member_name), NO_COMMENT
+            else:
+                my_reminders[my_member_name] = my_member
+        my_members = my_reminders
         for my_name, other_name, score in diffoscope.comparators.perform_fuzzy_matching(my_members, other_members):
             comment = 'Files similar despite different names (difference score: %d)' % score
             yield my_members.pop(my_name), other_members.pop(other_name), comment
         if Config.general.new_file:
-            for my_name in my_members.keys() - other_members.keys():
-                my_file = my_members[my_name]
-                yield my_file, NonExistingFile('/dev/null', my_file), NO_COMMENT
-            for other_name in other_members.keys() - my_members.keys():
-                other_file = other_members[other_name]
-                yield NonExistingFile('/dev/null', other_file), other_file, NO_COMMENT
+            for my_member in my_members.values():
+                yield my_member, NonExistingFile('/dev/null', my_member), NO_COMMENT
+            for other_member in other_members.values():
+                yield NonExistingFile('/dev/null', other_member), other_member, NO_COMMENT
 
     def compare(self, other, source=None):
         return starmap(diffoscope.comparators.compare_commented_files, self.comparisons(other))
diff --git a/diffoscope/comparators/xz.py b/diffoscope/comparators/xz.py
index 79418f8..0b1b6c4 100644
--- a/diffoscope/comparators/xz.py
+++ b/diffoscope/comparators/xz.py
@@ -17,6 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
+from collections import OrderedDict
 import os.path
 import re
 import subprocess
@@ -34,7 +35,7 @@ class XzContainer(Archive):
         pass
 
     def get_members(self):
-        return {'xz-content': self.get_member(self.get_member_names()[0])}
+        return OrderedDict({'xz-content': self.get_member(self.get_member_names()[0])})
 
     def get_member_names(self):
         return [get_compressed_content_name(self.source.path, '.xz')]
diff --git a/tests/comparators/test_epub.py b/tests/comparators/test_epub.py
index 80134e1..f99f10c 100644
--- a/tests/comparators/test_epub.py
+++ b/tests/comparators/test_epub.py
@@ -51,12 +51,12 @@ def differences(epub1, epub2):
 def test_differences(differences):
     assert differences[0].source1 == 'zipinfo {}'
     assert differences[0].source2 == 'zipinfo {}'
-    assert differences[1].source1 == 'ch001.xhtml'
-    assert differences[1].source2 == 'ch001.xhtml'
-    assert differences[2].source1 == 'content.opf'
-    assert differences[2].source2 == 'content.opf'
-    assert differences[3].source1 == 'toc.ncx'
-    assert differences[3].source2 == 'toc.ncx'
+    assert differences[1].source1 == 'content.opf'
+    assert differences[1].source2 == 'content.opf'
+    assert differences[2].source1 == 'toc.ncx'
+    assert differences[2].source2 == 'toc.ncx'
+    assert differences[3].source1 == 'ch001.xhtml'
+    assert differences[3].source2 == 'ch001.xhtml'
     expected_diff = open(os.path.join(os.path.dirname(__file__), '../data/epub_expected_diffs')).read()
     assert expected_diff == "".join(map(lambda x: x.unified_diff, differences))
 
diff --git a/tests/comparators/test_ipk.py b/tests/comparators/test_ipk.py
index 1cf6c12..2c3ae3a 100644
--- a/tests/comparators/test_ipk.py
+++ b/tests/comparators/test_ipk.py
@@ -52,8 +52,8 @@ def test_metadata(differences):
     assert differences[0].unified_diff == expected_diff
 
 def test_compressed_files(differences):
-    assert differences[1].details[1].source1 == './control.tar.gz'
-    assert differences[1].details[2].source1 == './data.tar.gz'
+    assert differences[1].details[1].source1 == './data.tar.gz'
+    assert differences[1].details[2].source1 == './control.tar.gz'
 
 def test_compare_non_existing(monkeypatch, ipk1):
     monkeypatch.setattr(Config.general, 'new_file', True)
diff --git a/tests/comparators/test_iso9660.py b/tests/comparators/test_iso9660.py
index 5d5fa6d..e4382e6 100644
--- a/tests/comparators/test_iso9660.py
+++ b/tests/comparators/test_iso9660.py
@@ -59,16 +59,16 @@ def test_iso9660_rockridge(differences):
 
 @pytest.mark.skipif(tool_missing('isoinfo'), reason='missing isoinfo')
 def test_symlink(differences):
-    assert differences[2].comment == 'symlink'
+    assert differences[3].comment == 'symlink'
     expected_diff = open(os.path.join(os.path.dirname(__file__), '../data/symlink_expected_diff')).read()
-    assert differences[2].unified_diff == expected_diff
+    assert differences[3].unified_diff == expected_diff
 
 @pytest.mark.skipif(tool_missing('isoinfo'), reason='missing isoinfo')
 def test_compressed_files(differences):
-    assert differences[3].source1 == 'text'
-    assert differences[3].source2 == 'text'
+    assert differences[2].source1 == 'text'
+    assert differences[2].source2 == 'text'
     expected_diff = open(os.path.join(os.path.dirname(__file__), '../data/text_ascii_expected_diff')).read()
-    assert differences[3].unified_diff == expected_diff
+    assert differences[2].unified_diff == expected_diff
 
 @pytest.mark.skipif(tool_missing('isoinfo'), reason='missing isoinfo')
 def test_compare_non_existing(monkeypatch, iso1):
diff --git a/tests/comparators/test_tar.py b/tests/comparators/test_tar.py
index 78a7ff6..03fa07e 100644
--- a/tests/comparators/test_tar.py
+++ b/tests/comparators/test_tar.py
@@ -51,17 +51,17 @@ def test_listing(differences):
     assert differences[0].unified_diff == expected_diff
 
 def test_symlinks(differences):
-    assert differences[1].source1 == 'dir/link'
-    assert differences[1].source2 == 'dir/link'
-    assert differences[1].comment == 'symlink'
+    assert differences[2].source1 == 'dir/link'
+    assert differences[2].source2 == 'dir/link'
+    assert differences[2].comment == 'symlink'
     expected_diff = open(os.path.join(os.path.dirname(__file__), '../data/symlink_expected_diff')).read()
-    assert differences[1].unified_diff == expected_diff
+    assert differences[2].unified_diff == expected_diff
 
 def test_text_file(differences):
-    assert differences[2].source1 == 'dir/text'
-    assert differences[2].source2 == 'dir/text'
+    assert differences[1].source1 == 'dir/text'
+    assert differences[1].source2 == 'dir/text'
     expected_diff = open(os.path.join(os.path.dirname(__file__), '../data/text_ascii_expected_diff')).read()
-    assert differences[2].unified_diff == expected_diff
+    assert differences[1].unified_diff == expected_diff
 
 def test_compare_non_existing(monkeypatch, tar1):
     monkeypatch.setattr(Config.general, 'new_file', True)
diff --git a/tests/data/epub_expected_diffs b/tests/data/epub_expected_diffs
index 775af9c..a111c76 100644
--- a/tests/data/epub_expected_diffs
+++ b/tests/data/epub_expected_diffs
@@ -21,20 +21,6 @@
 +-rw----     0.0 fat      655 b- defX 15-Oct-27 11:33 nav.xhtml
 +-rw----     0.0 fat      615 b- defX 15-Oct-27 11:33 ch001.xhtml
 +9 files, 4535 bytes uncompressed, 2325 bytes compressed:  48.7%
-@@ -8,12 +8,12 @@
-   <title>Test Ebook</title>
-   <link rel="stylesheet" type="text/css" href="stylesheet.css" />
- </head>
- <body>
- <div id="test-ebook" class="section level1 unnumbered">
- <h1>Test Ebook</h1>
- <p>Hello World!</p>
--<p>Time: 12:32</p>
-+<p>Time: 12:33</p>
- </div>
- </body>
- </html>
- 
 @@ -1,13 +1,13 @@
  <?xml version="1.0" encoding="UTF-8"?>
  <package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="epub-id-1">
@@ -64,3 +50,17 @@
    <docTitle>
      <text>Test Ebook</text>
    </docTitle>
+@@ -8,12 +8,12 @@
+   <title>Test Ebook</title>
+   <link rel="stylesheet" type="text/css" href="stylesheet.css" />
+ </head>
+ <body>
+ <div id="test-ebook" class="section level1 unnumbered">
+ <h1>Test Ebook</h1>
+ <p>Hello World!</p>
+-<p>Time: 12:32</p>
++<p>Time: 12:33</p>
+ </div>
+ </body>
+ </html>
+ 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git


More information about the diffoscope mailing list