[diffoscope] 03/05: Fix errors when comparing directories with non-directories. (Closes: #835641)

Chris Lamb chris at chris-lamb.co.uk
Tue Feb 7 04:32:28 CET 2017


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

lamby pushed a commit to branch master
in repository diffoscope.

commit db37e55517c38275615facf8bf3972f99012b551
Author: Chris Lamb <lamby at debian.org>
Date:   Tue Feb 7 15:36:45 2017 +1300

    Fix errors when comparing directories with non-directories. (Closes: #835641)
    
    We now display a nicer diff such as:
    
      --- /etc/cron.d/
      +++ /etc/fstab
      @@ -1 +1 @@
      -type: directory
      +type: file
    
    Signed-off-by: Chris Lamb <lamby at debian.org>
---
 diffoscope/comparators/utils/file.py   | 22 +++++++++++++++++++
 tests/comparators/test_directory.py    | 39 ++++++++++++++++++++++++++++++++++
 tests/data/test_directory_device_diff  |  3 +++
 tests/data/test_directory_file_diff    |  3 +++
 tests/data/test_directory_symlink_diff |  3 +++
 5 files changed, 70 insertions(+)

diff --git a/diffoscope/comparators/utils/file.py b/diffoscope/comparators/utils/file.py
index 55d4f74..fd9e0e9 100644
--- a/diffoscope/comparators/utils/file.py
+++ b/diffoscope/comparators/utils/file.py
@@ -131,6 +131,18 @@ class File(object, metaclass=abc.ABCMeta):
             self._magic_file_type = File.guess_file_type(self.path)
         return self._magic_file_type
 
+    @property
+    def file_type(self):
+        for x, y in (
+            (self.is_device, "device"),
+            (self.is_symlink, "symlink"),
+            (self.is_directory, "directory"),
+        ):
+            if x():
+                return y
+
+        return "file"
+
     if tlsh:
         @property
         def fuzzy_hash(self):
@@ -162,6 +174,16 @@ class File(object, metaclass=abc.ABCMeta):
     def compare_bytes(self, other, source=None):
         from .compare import compare_binary_files
 
+        # Don't attempt to compare directories with any other type as binaries
+        if os.path.isdir(self.path) or os.path.isdir(other.path):
+            return Difference.from_text(
+                "type: {}".format(self.file_type),
+                "type: {}".format(other.file_type),
+                self.name,
+                other.name,
+                source,
+            )
+
         return compare_binary_files(self, other, source)
 
     def _compare_using_details(self, other, source):
diff --git a/tests/comparators/test_directory.py b/tests/comparators/test_directory.py
index 2210cbb..d4c1764 100644
--- a/tests/comparators/test_directory.py
+++ b/tests/comparators/test_directory.py
@@ -3,6 +3,7 @@
 # diffoscope: in-depth comparison of files, archives, and directories
 #
 # Copyright © 2015 Jérémy Bobbio <lunar at debian.org>
+#             2017 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
@@ -21,7 +22,9 @@ import os
 import shutil
 import pytest
 
+from diffoscope.comparators.binary import FilesystemFile
 from diffoscope.comparators.directory import compare_directories
+from diffoscope.comparators.utils.specialize import specialize
 
 from utils.data import data, get_data
 
@@ -61,3 +64,39 @@ def test_content(differences):
 
 def test_stat(differences):
     assert 'stat' in differences[0].details[0].details[0].source1
+
+
+def test_compare_to_file(tmpdir):
+    path = str(tmpdir.join('file'))
+
+    with open(path, 'w') as f:
+        f.write("content")
+
+    a = specialize(FilesystemFile(str(tmpdir.mkdir('dir'))))
+    b = specialize(FilesystemFile(path))
+
+    assert a.compare(b).unified_diff == get_data('test_directory_file_diff')
+
+def test_compare_to_device(tmpdir):
+    a = specialize(FilesystemFile(str(tmpdir.mkdir('dir'))))
+    b = specialize(FilesystemFile('/dev/null'))
+
+    assert a.compare(b).unified_diff == get_data('test_directory_device_diff')
+
+def test_compare_to_symlink(tmpdir):
+    path = str(tmpdir.join('src'))
+    os.symlink('/etc/passwd', path)
+
+    a = specialize(FilesystemFile(str(tmpdir.mkdir('dir'))))
+    b = specialize(FilesystemFile(path))
+
+    assert a.compare(b).unified_diff == get_data('test_directory_symlink_diff')
+
+def test_compare_to_dangling_symlink(tmpdir):
+    path = str(tmpdir.join('src'))
+    os.symlink('/dangling', path)
+
+    a = specialize(FilesystemFile(str(tmpdir.mkdir('dir'))))
+    b = specialize(FilesystemFile(path))
+
+    assert a.compare(b).unified_diff == get_data('test_directory_symlink_diff')
diff --git a/tests/data/test_directory_device_diff b/tests/data/test_directory_device_diff
new file mode 100644
index 0000000..ddaab99
--- /dev/null
+++ b/tests/data/test_directory_device_diff
@@ -0,0 +1,3 @@
+@@ -1 +1 @@
+-type: directory
++type: device
diff --git a/tests/data/test_directory_file_diff b/tests/data/test_directory_file_diff
new file mode 100644
index 0000000..34a7fb2
--- /dev/null
+++ b/tests/data/test_directory_file_diff
@@ -0,0 +1,3 @@
+@@ -1 +1 @@
+-type: directory
++type: file
diff --git a/tests/data/test_directory_symlink_diff b/tests/data/test_directory_symlink_diff
new file mode 100644
index 0000000..9856e01
--- /dev/null
+++ b/tests/data/test_directory_symlink_diff
@@ -0,0 +1,3 @@
+@@ -1 +1 @@
+-type: directory
++type: symlink

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


More information about the diffoscope mailing list