Esempio n. 1
0
 def compare(self, other, source=None):
     differences = []
     try:
         listing_diff = Difference.from_text('\n'.join(list_files(self.path)),
                                             '\n'.join(list_files(other.path)),
                                             self.path, other.path, source='file list')
         if listing_diff:
             differences.append(listing_diff)
     except RequiredToolNotFound:
         logger.info("Unable to find 'getfacl'.")
     differences.extend(compare_meta(self.name, other.name))
     my_container = DirectoryContainer(self)
     other_container = DirectoryContainer(other)
     my_names = my_container.get_member_names()
     other_names = other_container.get_member_names()
     for name in sorted(set(my_names).intersection(other_names)):
         my_file = my_container.get_member(name)
         other_file = other_container.get_member(name)
         inner_difference = diffoscope.comparators.compare_files(
                                my_file, other_file, source=name)
         meta_differences = compare_meta(my_file.name, other_file.name)
         if meta_differences and not inner_difference:
             inner_difference = Difference(None, my_file.path, other_file.path)
         if inner_difference:
             inner_difference.add_details(meta_differences)
             differences.append(inner_difference)
     if not differences:
         return None
     difference = Difference(None, self.path, other.path, source)
     difference.add_details(differences)
     return difference
Esempio n. 2
0
def compare_root_paths(path1, path2):
    from ..directory import (
        FilesystemDirectory,
        FilesystemFile,
        compare_directories,
        compare_meta,
    )

    if not Config().new_file:
        bail_if_non_existing(path1, path2)
    if any_excluded(path1, path2):
        return None

    if os.path.isdir(path1) and os.path.isdir(path2):
        return compare_directories(path1, path2)

    container1 = FilesystemDirectory(os.path.dirname(path1)).as_container
    file1 = specialize(FilesystemFile(path1, container=container1))
    container2 = FilesystemDirectory(os.path.dirname(path2)).as_container
    file2 = specialize(FilesystemFile(path2, container=container2))
    difference = compare_files(file1, file2)

    if Config().exclude_directory_metadata in ('no', 'recursive'):
        meta = compare_meta(path1, path2)
        if meta:
            # Create an "empty" difference so we have something to attach file
            # metadata to.
            if difference is None:
                difference = Difference(None, file1.name, file2.name)
            difference.add_details(meta)
    return difference
Esempio n. 3
0
    def compare(self, other, source=None):
        differences = []

        listing_diff = Difference.from_text(
            '\n'.join(list_files(self.path)),
            '\n'.join(list_files(other.path)),
            self.path,
            other.path,
            source='file list',
        )
        if listing_diff:
            differences.append(listing_diff)

        differences.extend(compare_meta(self.name, other.name))

        my_container = DirectoryContainer(self)
        other_container = DirectoryContainer(other)
        differences.extend(my_container.compare(other_container))

        if not differences:
            return None

        difference = Difference(None, self.path, other.path, source)
        difference.add_details(differences)
        return difference
Esempio n. 4
0
def test_size_updates():
    d = Difference("0123456789", "path1", "path2")
    assert_size(d, 20)
    d.add_details([Difference("0123456789", "path1/a", "path2/a")])
    assert_size(d, 44)
    d.add_comment("lol1")
    assert_size(d, 48)
Esempio n. 5
0
 def compare(self, other, source=None):
     my_encoding = self.encoding or 'utf-8'
     other_encoding = other.encoding or 'utf-8'
     try:
         with codecs.open(self.path, 'r', encoding=my_encoding) as my_content, \
              codecs.open(other.path, 'r', encoding=other_encoding) as other_content:
             difference = Difference.from_text_readers(
                 my_content, other_content, self.name, other.name, source)
             # Check if difference is only in line order.
             if difference and order_only_difference(
                     difference.unified_diff):
                 difference.add_comment("ordering differences only")
             if my_encoding != other_encoding:
                 if difference is None:
                     difference = Difference(None, self.path, other.path,
                                             source)
                 difference.add_details([
                     Difference.from_text(my_encoding,
                                          other_encoding,
                                          None,
                                          None,
                                          source='encoding')
                 ])
             return difference
     except (LookupError, UnicodeDecodeError):
         # unknown or misdetected encoding
         return self.compare_bytes(other, source)
Esempio n. 6
0
 def compare(self, other, source=None):
     differences = []
     try:
         listing_diff = Difference.from_text(
             '\n'.join(list_files(self.path)),
             '\n'.join(list_files(other.path)),
             self.path,
             other.path,
             source='file list')
         if listing_diff:
             differences.append(listing_diff)
     except RequiredToolNotFound:
         logger.info("Unable to find 'getfacl'.")
     differences.extend(compare_meta(self.name, other.name))
     my_container = DirectoryContainer(self)
     other_container = DirectoryContainer(other)
     my_names = my_container.get_member_names()
     other_names = other_container.get_member_names()
     for name in sorted(set(my_names).intersection(other_names)):
         my_file = my_container.get_member(name)
         other_file = other_container.get_member(name)
         inner_difference = diffoscope.comparators.compare_files(
             my_file, other_file, source=name)
         meta_differences = compare_meta(my_file.name, other_file.name)
         if meta_differences and not inner_difference:
             inner_difference = Difference(None, my_file.path,
                                           other_file.path)
         if inner_difference:
             inner_difference.add_details(meta_differences)
             differences.append(inner_difference)
     if not differences:
         return None
     difference = Difference(None, self.path, other.path, source)
     difference.add_details(differences)
     return difference
Esempio n. 7
0
 def _compare_using_details(self, other, source):
     details = [d for d in self.compare_details(other, source) if d is not None]
     if len(details) == 0:
         return None
     difference = Difference(None, self.name, other.name, source=source)
     difference.add_details(details)
     return difference
Esempio n. 8
0
 def compare(self, other, source=None):
     differences = []
     try:
         find_diff = Difference.from_command(FindAll, self.path, other.path)
         if find_diff:
             differences.append(find_diff)
     except RequiredToolNotFound:
         logger.info("Unable to find 'getfacl'.")
     differences.extend(compare_meta(self.name, other.name))
     with DirectoryContainer(self).open() as my_container, \
          DirectoryContainer(other).open() as other_container:
         my_names = my_container.get_member_names()
         other_names = other_container.get_member_names()
         for name in sorted(set(my_names).intersection(other_names)):
             my_file = my_container.get_member(name)
             other_file = other_container.get_member(name)
             with my_file.get_content(), other_file.get_content():
                 inner_difference = diffoscope.comparators.compare_files(
                                        my_file, other_file, source=name)
                 meta_differences = compare_meta(my_file.name, other_file.name)
                 if meta_differences and not inner_difference:
                     inner_difference = Difference(None, my_file.path, other_file.path)
                 if inner_difference:
                     inner_difference.add_details(meta_differences)
                     differences.append(inner_difference)
     if not differences:
         return None
     difference = Difference(None, self.path, other.path, source)
     difference.add_details(differences)
     return difference
Esempio n. 9
0
 def compare_pair(file1, file2, source):
     inner_difference = compare_files(file1, file2, source=source)
     meta_differences = compare_meta(file1.name, file2.name)
     if meta_differences and not inner_difference:
         inner_difference = Difference(None, file1.path, file2.path)
     if inner_difference:
         inner_difference.add_details(meta_differences)
     return inner_difference
Esempio n. 10
0
 def _compare_using_details(self, other, source):
     details = []
     if hasattr(self, 'compare_details'):
         details.extend(filter(None, self.compare_details(other, source)))
     if self.as_container:
         details.extend(filter(None, self.as_container.compare(other.as_container)))
     if not details:
         return None
     difference = Difference(None, self.name, other.name, source=source)
     difference.add_details(details)
     return difference
Esempio n. 11
0
 def _compare_using_details(self, other, source):
     details = []
     if hasattr(self, 'compare_details'):
         details.extend(filter(None, self.compare_details(other, source)))
     if self.as_container:
         details.extend(
             filter(None, self.as_container.compare(other.as_container)))
     if not details:
         return None
     difference = Difference(None, self.name, other.name, source=source)
     difference.add_details(details)
     return difference
Esempio n. 12
0
    def compare(self, other, source=None):
        """
        Override file's compare method to get rid of the binary diff fallback,
        as it would be redundant with other outputs
        """
        details = self.compare_details(other, source)
        details = [x for x in details if x]
        if not details:
            return None

        difference = Difference(None, self.name, other.name, source=source)
        difference.add_details(details)
        return difference
Esempio n. 13
0
def test_traverse_heapq():
    d0 = Difference("0", "path1/a", "path2/a")
    d1 = Difference("012", "path1/b", "path2/b")
    d2 = Difference("01", "path1/c", "path2/c")
    d0.add_details([
        Difference("012345678", "path1/a/1", "path2/a/1"),
        Difference("0123", "path1/a/2", "path2/a/2"),
        Difference("012", "path1/a/3", "path2/a/3")
    ])
    d1.add_details([
        Difference("01234567", "path1/b/1", "path2/b/1"),
        Difference("01234", "path1/b/2", "path2/b/2"),
        Difference("012345", "path1/b/3", "path2/b/3")
    ])
    d2.add_details([
        Difference("01", "path1/c/1", "path2/c/1"),
        Difference("0123456789", "path1/c/2", "path2/c/2"),
        Difference("0123456", "path1/c/3", "path2/c/3")
    ])
    diff = Difference("0123456789", "path1", "path2")
    diff.add_details([d0, d1, d2])

    # traverse nodes in depth order, but at a given depth traverse the nodes
    # there from smallest diff (counted non-recursively) to largest
    def f(node, parscore):
        depth = parscore[0] + 1 if parscore else 0
        return depth, node.size_self()

    assert_size(diff, 284)
    results = [d.source1[6:] for d in diff.traverse_heapq(f)]
    assert results == [
        '', 'a', 'c', 'b', 'c/1', 'a/3', 'a/2', 'b/2', 'b/3', 'c/3', 'b/1',
        'a/1', 'c/2'
    ]
Esempio n. 14
0
 def compare(self, other, source=None):
     my_encoding = self.encoding or 'utf-8'
     other_encoding = other.encoding or 'utf-8'
     try:
         with codecs.open(self.path, 'r', encoding=my_encoding) as my_content, \
              codecs.open(other.path, 'r', encoding=other_encoding) as other_content:
             difference = Difference.from_text_readers(my_content, other_content, self.name, other.name, source)
             if my_encoding != other_encoding:
                 if difference is None:
                     difference = Difference(None, self.path, other.path, source)
                 difference.add_details([Difference.from_text(my_encoding, other_encoding, None, None, source='encoding')])
             return difference
     except (LookupError, UnicodeDecodeError):
         # unknown or misdetected encoding
         return self.compare_bytes(other, source)
Esempio n. 15
0
    def _compare_using_details(self, other, source):
        details = []
        difference = Difference(None, self.name, other.name, source=source)

        if hasattr(self, 'compare_details'):
            details.extend(self.compare_details(other, source))
        if self.as_container:
            if self.as_container.auto_diff_metadata:
                details.extend([
                    Difference.from_text(
                        self.magic_file_type,
                        other.magic_file_type,
                        self,
                        other,
                        source='filetype from file(1)',
                    ),
                    Difference.from_text(
                        self.__class__.__name__,
                        other.__class__.__name__,
                        self,
                        other,
                        source='filetype from diffoscope',
                    ),
                ])
            # Don't recurse forever on archive quines, etc.
            depth = self._as_container.depth
            no_recurse = depth >= Config().max_container_depth
            if no_recurse:
                msg = "Reached max container depth ({})".format(depth)
                logger.debug(msg)
                difference.add_comment(msg)
            details.extend(
                self.as_container.compare(other.as_container,
                                          no_recurse=no_recurse))

        details = [x for x in details if x]
        if not details:
            return None
        difference.add_details(details)

        return difference
Esempio n. 16
0
    def _compare_using_details(self, other, source):
        details = []
        difference = Difference(None, self.name, other.name, source=source)

        if hasattr(self, 'compare_details'):
            details.extend(self.compare_details(other, source))
        if self.as_container:
            # Don't recursve forever on archive quines, etc.
            depth = self._as_container.depth
            no_recurse = (depth >= Config().max_container_depth)
            if no_recurse:
                msg = "Reached max container depth ({})".format(depth)
                logger.debug(msg)
                difference.add_comment(msg)
            details.extend(
                self.as_container.compare(other.as_container,
                                          no_recurse=no_recurse))

        details = [x for x in details if x]
        if not details:
            return None
        difference.add_details(details)

        return difference