Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package diffoscope for openSUSE:Factory 
checked in at 2023-11-01 22:10:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/diffoscope (Old)
 and      /work/SRC/openSUSE:Factory/.diffoscope.new.17445 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "diffoscope"

Wed Nov  1 22:10:59 2023 rev:43 rq:1121673 version:251

Changes:
--------
--- /work/SRC/openSUSE:Factory/diffoscope/diffoscope.changes    2023-08-06 
16:29:47.387784481 +0200
+++ /work/SRC/openSUSE:Factory/.diffoscope.new.17445/diffoscope.changes 
2023-11-01 22:11:31.491100063 +0100
@@ -1,0 +2,30 @@
+Wed Nov  1 17:44:17 UTC 2023 - Andrea Manzini <andrea.manz...@suse.com>
+
+- removed patch fix-file-5.45.patch as included in upstream
+
+- Update to version 251:
+  * If the equivalent of `file -i` returns text/plain, fallback to comparing
+    this file as a text file. This especially helps when file(1) miscategorises
+    text files as some esoteric type. 
+
+- Update to version 250:
+  * Fix compatibility with file 5.45. 
+  * Add external tool references for GNU Guix (for html2text and ttx).
+
+- Update to version 249:
+  * Add specialize_as() method, and use it to speed up .smali comparison in 
APKs.
+  * Add documentation for the new specialize_as, and expand the documentation
+    of `specialize` too. 
+  * Correct typos in diffoscope/presenters/utils.py.
+
+- Update to version 246:
+  * Add support for LLVM 16.
+
+- Update to version 244:
+  * Address compatibility with python-libarchive-c version 5.
+  * Testsuite changes
+
+- Update to version 243:
+  * Improve the documentation on to produce that binary blob that in the arsc 
comparator.
+
+-------------------------------------------------------------------

Old:
----
  diffoscope-242.tar.bz2
  diffoscope-242.tar.bz2.asc
  fix-file-5.45.patch

New:
----
  diffoscope-251.tar.bz2
  diffoscope-251.tar.bz2.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ diffoscope.spec ++++++
--- /var/tmp/diff_new_pack.Mu2uKC/_old  2023-11-01 22:11:31.931116364 +0100
+++ /var/tmp/diff_new_pack.Mu2uKC/_new  2023-11-01 22:11:31.931116364 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           diffoscope
-Version:        242
+Version:        251
 Release:        0
 Summary:        In-depth comparison of files, archives, and directories
 License:        GPL-3.0-or-later
@@ -26,8 +26,6 @@
 Source0:        https://diffoscope.org/archive/diffoscope-%{version}.tar.bz2
 Source1:        
https://diffoscope.org/archive/diffoscope-%{version}.tar.bz2.asc
 Source2:        diffoscope.keyring
-# PATCH-FIX-UPSTREAM   fix-file-5.45.patch -- fix compatibility with file 
version 5.45, see 
https://salsa.debian.org/reproducible-builds/diffoscope/-/issues/346
-Patch0:         
https://salsa.debian.org/reproducible-builds/diffoscope/-/commit/435a8fe9a201a7e74e705e06cc56b66fa6cb4af9.patch#/fix-file-5.45.patch
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 BuildRequires:  python3-base >= 3.7
@@ -112,8 +110,7 @@
 debbindiff.
 
 %prep
-%setup -q
-%patch0 -p1
+%autosetup -p1
 sed -i '0,/#!\/usr\/bin\/env/ d' diffoscope/main.py
 
 %build

++++++ diffoscope-242.tar.bz2 -> diffoscope-251.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/Dockerfile 
new/diffoscope-251/Dockerfile
--- old/diffoscope-242/Dockerfile       2023-05-05 21:05:32.000000000 +0200
+++ new/diffoscope-251/Dockerfile       2023-10-13 09:59:15.000000000 +0200
@@ -1,17 +1,18 @@
-FROM debian:sid
+FROM debian:sid-slim
 
 ARG DEBIAN_FRONTEND=noninteractive
 
-RUN apt-get update && apt-get dist-upgrade --yes
-RUN apt-get install --yes --no-install-recommends build-essential devscripts 
equivs
-
 ADD [".", "/srv/diffoscope"]
-RUN mk-build-deps --install --tool 'apt-get -o Debug::pkgProblemResolver=yes 
--no-install-recommends --yes' /srv/diffoscope/debian/control
-
-RUN apt-get remove --purge --yes build-essential devscripts equivs
-RUN rm -rf /srv/diffoscope/debian
+RUN mkdir -p /usr/share/man/man1/ \
+&& apt-get update && apt-get install --yes --no-install-recommends \
+    build-essential devscripts equivs \
+&& mk-build-deps --install --tool 'apt-get -o Debug::pkgProblemResolver=yes 
--no-install-recommends --yes' /srv/diffoscope/debian/control \
+&& apt-get remove --purge --yes \
+    build-essential devscripts equivs \
+&& rm -rf /srv/diffoscope/debian \
+&& rm -rf /var/lib/apt/lists/* \
+&& useradd -ms /bin/bash user
 
-RUN useradd -ms /bin/bash user
 USER user
 WORKDIR /home/user
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/README.rst 
new/diffoscope-251/README.rst
--- old/diffoscope-242/README.rst       2023-05-05 21:05:32.000000000 +0200
+++ new/diffoscope-251/README.rst       2023-10-13 09:59:15.000000000 +0200
@@ -4,9 +4,6 @@
 .. image:: https://badge.fury.io/py/diffoscope.svg
    :target: http://badge.fury.io/py/diffoscope
 
-.. image:: 
https://jenkins.debian.net/buildStatus/icon?job=reproducible_diffoscope_from_git_master&plastic=true
-  :target: https://jenkins.debian.net/job/reproducible_diffoscope_from_git
-
 diffoscope will try to get to the bottom of what makes files or
 directories different. It will recursively unpack archives of many kinds
 and transform various binary formats into more human-readable form to
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/debian/changelog 
new/diffoscope-251/debian/changelog
--- old/diffoscope-242/debian/changelog 2023-05-05 21:05:32.000000000 +0200
+++ new/diffoscope-251/debian/changelog 2023-10-13 09:59:15.000000000 +0200
@@ -1,3 +1,101 @@
+diffoscope (251) unstable; urgency=medium
+
+  * If the equivalent of `file -i` returns text/plain, fallback to comparing
+    this file as a text file. This especially helps when file(1) miscategorises
+    text files as some esoteric type. (Closes: Debian:#1053668)
+  * Update copyright years.
+
+ -- Chris Lamb <la...@debian.org>  Fri, 13 Oct 2023 08:59:12 +0100
+
+diffoscope (250) unstable; urgency=medium
+
+  [ Chris Lamb ]
+  * Fix compatibility with file 5.45. (Closes: 
reproducible-builds/diffoscope#351)
+
+  [ Vagrant Cascadian ]
+  * Add external tool references for GNU Guix (for html2text and ttx).
+
+ -- Chris Lamb <la...@debian.org>  Fri, 08 Sep 2023 12:10:31 -0700
+
+diffoscope (249) unstable; urgency=medium
+
+  [ FC Stegerman ]
+  * Add specialize_as() method, and use it to speed up .smali comparison in
+    APKs. (Closes: reproducible-builds/diffoscope!108)
+
+  [ Chris Lamb ]
+  * Add documentation for the new specialize_as, and expand the documentation
+    of `specialize` too. (Re: reproducible-builds/diffoscope!108)
+  * Update copyright years.
+
+  [ Felix Yan ]
+  * Correct typos in diffoscope/presenters/utils.py.
+
+ -- Chris Lamb <la...@debian.org>  Fri, 01 Sep 2023 10:41:51 -0700
+
+diffoscope (248) unstable; urgency=medium
+
+  [ Greg Chabala ]
+  * Merge Docker "RUN" commands into single layer.
+
+ -- Chris Lamb <la...@debian.org>  Fri, 25 Aug 2023 08:20:33 -0700
+
+diffoscope (247) unstable; urgency=medium
+
+  [ Chris Lamb ]
+  * Fix compataibility with file(1) version 5.45.
+  * Use assert_diff in test_uimage and test_cpio.
+
+  [ Roland Clobus ]
+  * xb-tool has moved in Debian bookworm.
+
+ -- Chris Lamb <la...@debian.org>  Fri, 04 Aug 2023 09:37:54 +0100
+
+diffoscope (246) unstable; urgency=medium
+
+  [ Gianfranco Costamagna ]
+  * Add support for LLVM 16.
+
+ -- Chris Lamb <la...@debian.org>  Fri, 28 Jul 2023 08:57:05 +0100
+
+diffoscope (245) unstable; urgency=medium
+
+  [ Chris Lamb ]
+  * Don't include file size in image metadata; it is, at best, distracting and
+    it is already in the directory metadata.
+  * Move to using assert_diff in ICO and JPEG tests.
+  * Update copyright years.
+
+ -- Chris Lamb <la...@debian.org>  Fri, 21 Jul 2023 08:57:41 +0100
+
+diffoscope (244) unstable; urgency=medium
+
+  [ Chris Lamb ]
+  * Address compatibility with python-libarchive-c version 5.
+    (Closes: reproducible-builds/diffoscope#344)
+  * Testsuite changes:
+    - Mark that test_dex::test_javap_14_differences requires procyon.
+    - Fix "test skipped" textual reason generation in the case of a required
+      version being outside of the required range.
+    - Temporarily mark some Android-related as XFAIL due to Debian bugs
+      #1040941 and #1040916.
+
+ -- Chris Lamb <la...@debian.org>  Fri, 14 Jul 2023 13:07:47 +0100
+
+diffoscope (243) unstable; urgency=medium
+
+  [ Chris Lamb ]
+  * Drop Jenkins build reference in README.rst.
+
+  [ Ed Maste ]
+  * Update FreeBSD package names
+
+  [ Mattia Rizzolo ]
+  * Improve the documentation on to produce that binary blob that in the arsc
+    comparator.
+
+ -- Chris Lamb <la...@debian.org>  Fri, 23 Jun 2023 17:11:25 +0100
+
 diffoscope (242) unstable; urgency=medium
 
   * If the binwalk Python module is not available, ensure the user knows they
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/debian/tests/control 
new/diffoscope-251/debian/tests/control
--- old/diffoscope-242/debian/tests/control     2023-05-05 21:05:32.000000000 
+0200
+++ new/diffoscope-251/debian/tests/control     2023-10-13 09:59:15.000000000 
+0200
@@ -7,7 +7,7 @@
 #   $ mv debian/tests/control.tmp debian/tests/control
 
 Tests: pytest-with-recommends
-Depends: python3-all, diffoscope, black, python3-pytest, python3-h5py, file, 
linux-image-amd64 [amd64] | linux-image-generic [amd64], aapt [amd64 arm64 
armel armhf i386 mips64el mipsel], abootimg, acl, apksigcopier, apksigner, 
apktool [!ppc64el !s390x], binutils-multiarch, bzip2, caca-utils, colord, 
coreboot-utils, db-util, default-jdk-headless | default-jdk | java-sdk, 
device-tree-compiler, dexdump [amd64 arm64 armhf i386], docx2txt, e2fsprogs, 
enjarify, ffmpeg, fontforge-extras, fonttools, fp-utils [!ppc64el !s390x], 
genisoimage, gettext, ghc, ghostscript, giflib-tools, gnumeric, gnupg, 
gnupg-utils, hdf5-tools, html2text, imagemagick, jsbeautifier, 
libarchive-tools, libxmlb-dev, llvm, lz4 | liblz4-tool, lzip, mono-utils, 
ocaml-nox, odt2txt, oggvideotools [!s390x], openssh-client, openssl, pgpdump, 
poppler-utils, procyon-decompiler, python3-pdfminer, r-base-core, rpm2cpio, 
sng, sqlite3, squashfs-tools, tcpdump, u-boot-tools, unzip, wabt, xmlbeans, 
xxd, xz-utils, zip, zstd, androgua
 rd, python3-argcomplete, python3-binwalk, python3-defusedxml, python3-distro, 
python3-guestfs, python3-jsondiff, python3-progressbar, python3-pypdf, 
python3-debian, python3-pyxattr, python3-rpm, python3-tlsh
+Depends: python3-all, diffoscope, black, python3-pytest, python3-h5py, file, 
linux-image-amd64 [amd64] | linux-image-generic [amd64], aapt [amd64 arm64 
armel armhf i386 mips64el mipsel], abootimg, acl, apksigcopier, apksigner, 
apktool [!ppc64el !s390x], binutils-multiarch, bzip2, caca-utils, colord, 
coreboot-utils, db-util, default-jdk-headless | default-jdk | java-sdk, 
device-tree-compiler, dexdump [amd64 arm64 armhf i386], docx2txt, e2fsprogs, 
enjarify, ffmpeg, fontforge-extras, fonttools, fp-utils [!ppc64el !s390x], 
genisoimage, gettext, ghc, ghostscript, giflib-tools, gnumeric, gnupg, 
gnupg-utils, hdf5-tools, html2text, imagemagick, jsbeautifier, 
libarchive-tools, libxmlb-utils, llvm, lz4 | liblz4-tool, lzip, mono-utils, 
ocaml-nox, odt2txt, oggvideotools [!s390x], openssh-client, openssl, pgpdump, 
poppler-utils, procyon-decompiler, python3-pdfminer, r-base-core, rpm2cpio, 
sng, sqlite3, squashfs-tools, tcpdump, u-boot-tools, unzip, wabt, xmlbeans, 
xxd, xz-utils, zip, zstd, androg
 uard, python3-argcomplete, python3-binwalk, python3-defusedxml, 
python3-distro, python3-guestfs, python3-jsondiff, python3-progressbar, 
python3-pypdf, python3-debian, python3-pyxattr, python3-rpm, python3-tlsh
 
 Tests: pytest
 Depends: python3-all, diffoscope, python3-pytest, python3-h5py, file, 
python3-tlsh
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/diffoscope/__init__.py 
new/diffoscope-251/diffoscope/__init__.py
--- old/diffoscope-242/diffoscope/__init__.py   2023-05-05 21:05:32.000000000 
+0200
+++ new/diffoscope-251/diffoscope/__init__.py   2023-10-13 09:59:15.000000000 
+0200
@@ -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 = "242"
+VERSION = "251"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/diffoscope/comparators/apk.py 
new/diffoscope-251/diffoscope/comparators/apk.py
--- old/diffoscope-242/diffoscope/comparators/apk.py    2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/diffoscope/comparators/apk.py    2023-10-13 
09:59:15.000000000 +0200
@@ -35,9 +35,11 @@
 )
 from diffoscope.tempfiles import get_temporary_directory
 
-from .utils.archive import Archive
+from .text import TextFile
+from .utils.archive import Archive, ArchiveMember
 from .utils.command import Command
 from .utils.compare import compare_files
+from .utils.specialize import specialize_as
 from .zip import ZipContainer, zipinfo_differences, ZipFileBase
 from .missing_file import MissingFile
 
@@ -157,6 +159,14 @@
     def get_member_names(self):
         return self._members
 
+    def get_member(self, member_name):
+        member = ArchiveMember(self, member_name)
+        if member_name.endswith(".smali") and member_name.startswith("smali"):
+            # smali{,_classesN}/**/*.smali files from apktool are always text,
+            # and using libmagic on thousands of these files takes minutes
+            return specialize_as(TextFile, member)
+        return member
+
     def extract(self, member_name, dest_dir):
         return os.path.join(self._tmpdir.name, member_name)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/diffoscope/comparators/arsc.py 
new/diffoscope-251/diffoscope/comparators/arsc.py
--- old/diffoscope-242/diffoscope/comparators/arsc.py   2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/diffoscope/comparators/arsc.py   2023-10-13 
09:59:15.000000000 +0200
@@ -33,6 +33,13 @@
 # <manifest xmlns:android="http://schemas.android.com/apk/res/android"; 
android:versionCode="1" android:versionName="1" android:compileSdkVersion="29" 
android:compileSdkVersionCodename="10.0.0" package="com.example" 
platformBuildVersionCode="29" platformBuildVersionName="10.0.0">
 #   <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/>
 # </manifest>
+#
+# This is created by running:
+#   $ aapt2 link -o output.apk -I 
/usr/share/android-framework-res/framework-res.apk --manifest 
AndroidManifest-in.xml
+#   $ unzip output.apk AndroidManifest.xml
+# The framework-res.apk needed by aapt2 here is provided by the Debian package
+# `android-framework-res`.
+# See https://salsa.debian.org/reproducible-builds/diffoscope/-/issues/340
 AXML = (
     b"\x03\x00\x08\x00\xf0\x03\x00\x00\x01\x00\x1c\x00l\x02\x00\x00"
     b"\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x00\x00\x00"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/diffoscope/comparators/image.py 
new/diffoscope-251/diffoscope/comparators/image.py
--- old/diffoscope-242/diffoscope/comparators/image.py  2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/diffoscope/comparators/image.py  2023-10-13 
09:59:15.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # diffoscope: in-depth comparison of files, archives, and directories
 #
-# Copyright © 2015-2020 Chris Lamb <la...@debian.org>
+# Copyright © 2015-2020, 2023 Chris Lamb <la...@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
@@ -47,7 +47,6 @@
 class Identify(Command):
     ATTRIBUTES = (
         "Image format: %m",
-        "File size: %b",
         "Height: %[height]",
         "Width: %[width]",
         "Orientation: %[orientation]",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/diffoscope/comparators/utils/file.py 
new/diffoscope-251/diffoscope/comparators/utils/file.py
--- old/diffoscope-242/diffoscope/comparators/utils/file.py     2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/diffoscope/comparators/utils/file.py     2023-10-13 
09:59:15.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # diffoscope: in-depth comparison of files, archives, and directories
 #
-# Copyright © 2016-2022 Chris Lamb <la...@debian.org>
+# Copyright © 2016-2023 Chris Lamb <la...@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
@@ -87,6 +87,11 @@
             )
 
         @classmethod
+        def guess_mime(cls, path):
+            # Not yet implemented
+            return ""
+
+        @classmethod
         def guess_encoding(cls, path):
             if not hasattr(cls, "_mimedb_encoding"):
                 cls._mimedb_encoding = magic.open(magic.MAGIC_MIME_ENCODING)
@@ -103,6 +108,12 @@
             return maybe_decode(cls._mimedb.from_file(path))
 
         @classmethod
+        def guess_mime(cls, path):
+            if not hasattr(cls, "_mimedb_mime"):
+                cls._mimedb_mime = magic.Magic(mime=True)
+            return maybe_decode(cls._mimedb_mime.from_file(path))
+
+        @classmethod
         def guess_encoding(cls, path):
             if not hasattr(cls, "_mimedb_encoding"):
                 cls._mimedb_encoding = magic.Magic(mime_encoding=True)
@@ -315,6 +326,12 @@
         return self._magic_file_type
 
     @property
+    def magic_mime_type(self):
+        if not hasattr(self, "_magic_mime_type"):
+            self._magic_mime_type = File.guess_mime(self.path)
+        return self._magic_mime_type
+
+    @property
     def file_header(self):
         if not hasattr(self, "_file_header"):
             with open(self.path, "rb") as f:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/diffoscope-242/diffoscope/comparators/utils/libarchive.py 
new/diffoscope-251/diffoscope/comparators/utils/libarchive.py
--- old/diffoscope-242/diffoscope/comparators/utils/libarchive.py       
2023-05-05 21:05:32.000000000 +0200
+++ new/diffoscope-251/diffoscope/comparators/utils/libarchive.py       
2023-10-13 09:59:15.000000000 +0200
@@ -2,7 +2,7 @@
 # diffoscope: in-depth comparison of files, archives, and directories
 #
 # Copyright © 2015 Jérémy Bobbio <lu...@debian.org>
-# Copyright © 2016-2022 Chris Lamb <la...@debian.org>
+# Copyright © 2016-2023 Chris Lamb <la...@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
@@ -122,6 +122,13 @@
 
 
 def list_libarchive(path, ignore_errors=False):
+    def force_str(val):
+        # libarchive ~5 began to return uname and gname as UTF-8 whilst
+        # previous versions returned bytes that required decoding.
+        if not isinstance(val, str):
+            val = val.decode("utf-8", errors="surrogateescape")
+        return val
+
     try:
         with libarchive.file_reader(path) as archive:
             for entry in archive:
@@ -146,18 +153,14 @@
                 ) + ".{:06d}".format(entry.mtime_nsec // 1000)
                 if entry.uname:
                     user = "{user:<8} {uid:>7}".format(
-                        user=entry.uname.decode(
-                            "utf-8", errors="surrogateescape"
-                        ),
+                        user=force_str(entry.uname),
                         uid="({})".format(entry.uid),
                     )
                 else:
                     user = entry.uid
                 if entry.gname:
                     group = "{group:<8} {gid:>7}".format(
-                        group=entry.gname.decode(
-                            "utf-8", errors="surrogateescape"
-                        ),
+                        group=force_str(entry.gname),
                         gid="({})".format(entry.gid),
                     )
                 else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/diffoscope-242/diffoscope/comparators/utils/specialize.py 
new/diffoscope-251/diffoscope/comparators/utils/specialize.py
--- old/diffoscope-242/diffoscope/comparators/utils/specialize.py       
2023-05-05 21:05:32.000000000 +0200
+++ new/diffoscope-251/diffoscope/comparators/utils/specialize.py       
2023-10-13 09:59:15.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # diffoscope: in-depth comparison of files, archives, and directories
 #
-# Copyright © 2016-2020 Chris Lamb <la...@debian.org>
+# Copyright © 2016-2020, 2023 Chris Lamb <la...@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
@@ -19,6 +19,7 @@
 import logging
 
 from diffoscope.profiling import profile
+from diffoscope.comparators.text import TextFile
 
 from ...utils import format_class
 
@@ -28,9 +29,6 @@
 
 
 def try_recognize(file, cls, recognizes):
-    if isinstance(file, cls):
-        return True
-
     # Does this file class match?
     with profile("recognizes", file):
         # logger.debug("trying %s on %s", cls, file)
@@ -43,17 +41,41 @@
         format_class(cls, strip="diffoscope.comparators."),
         file.name,
     )
-    new_cls = type(cls.__name__, (cls, type(file)), {})
-    file.__class__ = new_cls
+    specialize_as(cls, file)
 
     return True
 
 
+def specialize_as(cls, file):
+    """
+    Sometimes it is near-certain that files within a Container with a given
+    extension (say) are of a known File type. We therefore do not need to run
+    libmagic on these files. Using this facily within a Container can be an
+    optimization, especially in cases where the Container contains hundreds of
+    similar/small files. (This can be seen in the case of apktool and .smali
+    files). In this case, this method can be used to essentially fix/force the
+    type. Care should naturally be taken within Container implementations;
+    such as checking the file extension and so forth.
+    """
+
+    new_cls = type(cls.__name__, (cls, type(file)), {})
+    file.__class__ = new_cls
+    return file
+
+
 def specialize(file):
+    # If we already know the class (ie. via `specialize_as`), then we do not
+    # need to run `File.recognizes` at all.
+    for cls in ComparatorManager().classes:
+        if isinstance(file, cls):
+            return file
+
+    # Run the usual `File.recognizes` implementation.
     for cls in ComparatorManager().classes:
         if try_recognize(file, cls, cls.recognizes):
             return file
 
+    # If there are no matches, run the fallback implementation.
     for cls in ComparatorManager().classes:
         if try_recognize(file, cls, cls.fallback_recognizes):
             logger.debug(
@@ -68,6 +90,14 @@
         file.magic_file_type,
     )
 
+    if file.magic_mime_type == "text/plain":
+        logger.debug(
+            "However, %s is probably text; using %s",
+            file.name,
+            format_class(TextFile, strip="diffoscope.comparators."),
+        )
+        return specialize_as(TextFile, file)
+
     return file
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/diffoscope/external_tools.py 
new/diffoscope-251/diffoscope/external_tools.py
--- old/diffoscope-242/diffoscope/external_tools.py     2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/diffoscope/external_tools.py     2023-10-13 
09:59:15.000000000 +0200
@@ -86,7 +86,7 @@
     "guestfs": {"debian": "python3-guestfs"},
     "gzip": {"debian": "gzip", "arch": "gzip", "guix": "gzip"},
     "h5dump": {"debian": "hdf5-tools", "arch": "hdf5", "guix": "hdf5"},
-    "html2text": {"debian": "html2text"},
+    "html2text": {"debian": "html2text", "guix": "html2text"},
     "identify": {
         "debian": "imagemagick",
         "arch": "imagemagick",
@@ -182,7 +182,7 @@
     "ps2ascii": {
         "debian": "ghostscript",
         "arch": "ghostscript",
-        "FreeBSD": "ghostscript9-base",
+        "FreeBSD": "ghostscript",
         "guix": "ghostscript",
     },
     "pypdf": {"debian": "python3-pypdf"},
@@ -222,7 +222,7 @@
     "wasm2wat": {"debian": "wabt", "arch": "wabt", "guix": "wabt"},
     "tar": {"debian": "tar", "arch": "tar", "guix": "tar"},
     "tcpdump": {"debian": "tcpdump", "arch": "tcpdump", "guix": "tcpdump"},
-    "ttx": {"debian": "fonttools"},
+    "ttx": {"debian": "fonttools", "guix": "python-fonttools"},
     "unsquashfs": {
         "debian": "squashfs-tools",
         "arch": "squashfs-tools",
@@ -232,7 +232,7 @@
     "xxd": {
         "debian": "xxd",
         "arch": "vim",
-        "FreeBSD": "vim | vim-lite",
+        "FreeBSD": "vim",
         "guix": "xxd",
     },
     "xz": {"debian": "xz-utils", "arch": "xz", "guix": "xz"},
@@ -245,7 +245,11 @@
     "zipnote": {"debian": "zip", "guix": "zip"},
     "procyon": {"debian": "procyon-decompiler"},
     "dumpxsb": {"debian": "xmlbeans"},
-    "xb-tool": {"debian": "libxmlb-dev", "arch": "libxmlb", "guix": "libxmlb"},
+    "xb-tool": {
+        "debian": "libxmlb-utils",
+        "arch": "libxmlb",
+        "guix": "libxmlb",
+    },
     "zstd": {"debian": "zstd", "guix": "zstd"},
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/diffoscope/presenters/utils.py 
new/diffoscope-251/diffoscope/presenters/utils.py
--- old/diffoscope-242/diffoscope/presenters/utils.py   2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/diffoscope/presenters/utils.py   2023-10-13 
09:59:15.000000000 +0200
@@ -214,7 +214,7 @@
     IndexError: tuple index out of range
 
     If you don't have specific objects to index the holes with, and don't want
-    to create artifical indexes as in the above examples, here is a slightly
+    to create artificial indexes as in the above examples, here is a slightly
     simpler way of doing it:
 
     >>> tmpl = PartialString.numl("{0} {1} {2}", 2, object())
@@ -375,7 +375,7 @@
     def numl(cls, fmtstr="", nargs=0, *holes):
         """Create a partial string with some implicit numeric holes.
 
-        Useful in conjuction with PartialString.pformatl.
+        Useful in conjunction with PartialString.pformatl.
 
         >>> PartialString.numl("{0}{1}{2}{3}", 3, "last object")
         PartialString('{0}{1}{2}{3}', 0, 1, 2, 'last object')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_arsc.py 
new/diffoscope-251/tests/comparators/test_arsc.py
--- old/diffoscope-242/tests/comparators/test_arsc.py   2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_arsc.py   2023-10-13 
09:59:15.000000000 +0200
@@ -2,6 +2,7 @@
 # diffoscope: in-depth comparison of files, archives, and directories
 #
 # Copyright © 2023 FC Stegerman <f...@obfusk.net>
+# Copyright © 2023 Chris Lamb <la...@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
@@ -51,6 +52,7 @@
 
 
 @skip_unless_tools_exist("aapt2")
+@pytest.mark.xfail(strict=False)
 def test_differences(differences):
     expected_diff = get_data("arsc_expected_diff")
     check_arsc_differences(differences, expected_diff)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_cpio.py 
new/diffoscope-251/tests/comparators/test_cpio.py
--- old/diffoscope-242/tests/comparators/test_cpio.py   2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_cpio.py   2023-10-13 
09:59:15.000000000 +0200
@@ -2,7 +2,7 @@
 # diffoscope: in-depth comparison of files, archives, and directories
 #
 # Copyright © 2015 Jérémy Bobbio <lu...@debian.org>
-# Copyright © 2015-2017, 2020 Chris Lamb <la...@debian.org>
+# Copyright © 2015-2017, 2020, 2023 Chris Lamb <la...@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,8 +21,11 @@
 
 from diffoscope.comparators.cpio import CpioFile
 
-from ..utils.data import load_fixture, get_data
-from ..utils.tools import skip_unless_tools_exist
+from ..utils.data import load_fixture, assert_diff
+from ..utils.tools import (
+    skip_unless_tools_exist,
+    skip_unless_file_version_is_at_least,
+)
 from ..utils.nonexisting import assert_non_existing
 
 cpio1 = load_fixture("test1.cpio")
@@ -46,24 +49,23 @@
 
 @skip_unless_tools_exist("cpio")
 def test_listing(differences):
-    expected_diff = get_data("cpio_listing_expected_diff")
-    assert differences[0].unified_diff == expected_diff
+    assert_diff(differences[0], "cpio_listing_expected_diff")
 
 
 @skip_unless_tools_exist("cpio")
+@skip_unless_file_version_is_at_least("5.45")
 def test_symlink(differences):
-    assert differences[1].source1 == "dir/link"
-    assert differences[1].comment == "symlink"
-    expected_diff = get_data("symlink_expected_diff")
-    assert differences[1].unified_diff == expected_diff
+    assert differences[2].source1 == "dir/link"
+    assert differences[2].comment == "symlink"
+    assert_diff(differences[2], "symlink_expected_diff")
 
 
 @skip_unless_tools_exist("cpio")
+@skip_unless_file_version_is_at_least("5.45")
 def test_compressed_files(differences):
-    assert differences[2].source1 == "dir/text"
-    assert differences[2].source2 == "dir/text"
-    expected_diff = get_data("text_ascii_expected_diff")
-    assert differences[2].unified_diff == expected_diff
+    assert differences[3].source1 == "dir/text"
+    assert differences[3].source2 == "dir/text"
+    assert_diff(differences[3], "text_ascii_expected_diff")
 
 
 @skip_unless_tools_exist("cpio")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_dex.py 
new/diffoscope-251/tests/comparators/test_dex.py
--- old/diffoscope-242/tests/comparators/test_dex.py    2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_dex.py    2023-10-13 
09:59:15.000000000 +0200
@@ -2,7 +2,7 @@
 # diffoscope: in-depth comparison of files, archives, and directories
 #
 # Copyright © 2015 Jérémy Bobbio <lu...@debian.org>
-# Copyright © 2016-2020 Chris Lamb <la...@debian.org>
+# Copyright © 2016-2020, 2023 Chris Lamb <la...@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
@@ -94,15 +94,17 @@
     check_dex_differences(differences, expected_diff)
 
 
-@skip_unless_tools_exist("enjarify", "zipinfo", "javap", "dexdump")
+@skip_unless_tools_exist("enjarify", "zipinfo", "javap", "dexdump", "procyon")
 @skip_unless_tool_is_at_least("javap", javap_version, "14.0")
 @skip_unless_tool_is_at_least("enjarify", enjarify_version, "1.0.3")
+@pytest.mark.xfail(strict=False)
 def test_javap_14_differences(differences):
     expected_diff = get_data("dex_javap_14_expected_diffs")
     check_dex_differences(differences, expected_diff)
 
 
 @skip_unless_tools_exist("enjarify", "zipinfo", "javap")
+@pytest.mark.xfail(strict=False)
 def test_compare_non_existing(monkeypatch, dex1):
     monkeypatch.setattr(Config(), "new_file", True)
     difference = dex1.compare(MissingFile("/nonexisting", dex1))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_elf.py 
new/diffoscope-251/tests/comparators/test_elf.py
--- old/diffoscope-242/tests/comparators/test_elf.py    2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_elf.py    2023-10-13 
09:59:15.000000000 +0200
@@ -39,6 +39,7 @@
     skip_if_tool_version_is,
     skip_unless_tool_is_at_least,
 )
+from .test_rlib import llvm_version
 
 
 obj1 = load_fixture("test1.o")
@@ -194,7 +195,11 @@
     assert_diff(x86_o, "elfmix_disassembly_expected_diff")
     assert_diff(src_c, "elfmix_src_c_expected_diff")
 
-    mach_o_filenames = ["elfmix_mach_o_expected_diff__text"]
+    if llvm_version() < "16":
+        mach_o_filenames = ["elfmix_mach_o_expected_diff__text"]
+    else:
+        mach_o_filenames = ["elfmix_mach_o_expected_diff__text_16"]
+
     for idx, diff in enumerate(mach_o.details):
         assert_diff(diff, mach_o_filenames[idx])
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_fit.py 
new/diffoscope-251/tests/comparators/test_fit.py
--- old/diffoscope-242/tests/comparators/test_fit.py    2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_fit.py    2023-10-13 
09:59:15.000000000 +0200
@@ -3,7 +3,7 @@
 # diffoscope: in-depth comparison of files, archives, and directories
 #
 # Copyright © 2020 Conrad Ratschan <ratscha...@gmail.com>
-# Copyright © 2021 Chris Lamb <la...@debian.org>
+# Copyright © 2021, 2023 Chris Lamb <la...@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
@@ -27,7 +27,11 @@
 from diffoscope.comparators.utils.specialize import specialize
 
 from ..utils.data import data, assert_diff, load_fixture
-from ..utils.tools import skip_unless_tools_exist, skip_unless_tool_is_at_least
+from ..utils.tools import (
+    skip_unless_tools_exist,
+    skip_unless_tool_is_at_least,
+    skip_unless_file_version_is_at_least,
+)
 from ..utils.nonexisting import assert_non_existing
 
 cpio1 = load_fixture("test1.cpio")
@@ -123,20 +127,22 @@
 
 @skip_unless_tools_exist("cpio")
 @skip_unless_tool_is_at_least("dumpimage", dumpimage_version, "2021.01")
+@skip_unless_file_version_is_at_least("5.45")
 @skip_unless_tools_exist("fdtdump")
 def test_nested_symlink(nested_differences):
-    assert nested_differences[1].source1 == "dir/link"
-    assert nested_differences[1].comment == "symlink"
-    assert_diff(nested_differences[1], "symlink_expected_diff")
+    assert nested_differences[2].source1 == "dir/link"
+    assert nested_differences[2].comment == "symlink"
+    assert_diff(nested_differences[2], "symlink_expected_diff")
 
 
 @skip_unless_tools_exist("cpio")
 @skip_unless_tool_is_at_least("dumpimage", dumpimage_version, "2021.01")
 @skip_unless_tools_exist("fdtdump")
+@skip_unless_file_version_is_at_least("5.45")
 def test_nested_compressed_files(nested_differences):
-    assert nested_differences[2].source1 == "dir/text"
-    assert nested_differences[2].source2 == "dir/text"
-    assert_diff(nested_differences[2], "text_ascii_expected_diff")
+    assert nested_differences[3].source1 == "dir/text"
+    assert nested_differences[3].source2 == "dir/text"
+    assert_diff(nested_differences[3], "text_ascii_expected_diff")
 
 
 @skip_unless_tools_exist("cpio")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_ico_image.py 
new/diffoscope-251/tests/comparators/test_ico_image.py
--- old/diffoscope-242/tests/comparators/test_ico_image.py      2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_ico_image.py      2023-10-13 
09:59:15.000000000 +0200
@@ -21,7 +21,7 @@
 from diffoscope.comparators.image import ICOImageFile
 from diffoscope.config import Config
 
-from ..utils.data import load_fixture, get_data
+from ..utils.data import load_fixture, assert_diff
 from ..utils.tools import (
     skip_unless_tools_exist,
     skip_unless_tool_is_between,
@@ -51,8 +51,7 @@
 
 @skip_unless_tools_exist("img2txt", "convert")
 def test_diff(differences):
-    expected_diff = get_data("ico_image_expected_diff")
-    assert differences[0].unified_diff == expected_diff
+    assert_diff(differences[0], "ico_image_expected_diff")
 
 
 @pytest.fixture
@@ -65,8 +64,7 @@
     "identify", identify_version, "6.9.10-23", "7.0.0"
 )
 def test_diff_meta(differences_meta):
-    expected_diff = get_data("ico_image_meta_expected_diff")
-    assert differences_meta[-1].unified_diff == expected_diff
+    assert_diff(differences_meta[-1], "ico_image_meta_expected_diff")
 
 
 @skip_unless_tools_exist("img2txt", "identify")
@@ -74,8 +72,7 @@
     "identify", identify_version, "6.9.10-23", "7.0.0"
 )
 def test_diff_meta2(differences_meta):
-    expected_diff = get_data("ico_image_meta_expected_diff_v2")
-    assert differences_meta[-1].unified_diff == expected_diff
+    assert_diff(differences_meta[-1], "ico_image_meta_expected_diff_v2")
 
 
 @skip_unless_tools_exist("img2txt", "convert", "identify")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_jpeg_image.py 
new/diffoscope-251/tests/comparators/test_jpeg_image.py
--- old/diffoscope-242/tests/comparators/test_jpeg_image.py     2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_jpeg_image.py     2023-10-13 
09:59:15.000000000 +0200
@@ -23,7 +23,7 @@
 from diffoscope.comparators.image import JPEGImageFile
 from diffoscope.comparators.missing_file import MissingFile
 
-from ..utils.data import load_fixture, get_data
+from ..utils.data import load_fixture, assert_diff
 from ..utils.tools import skip_unless_tools_exist, skip_unless_tool_is_between
 
 
@@ -58,8 +58,7 @@
 
 @skip_unless_tools_exist("img2txt", "identify")
 def test_diff(differences):
-    expected_diff = get_data("jpeg_image_expected_diff")
-    assert differences[0].unified_diff == expected_diff
+    assert_diff(differences[0], "jpeg_image_expected_diff")
 
 
 @skip_unless_tools_exist("img2txt", "identify")
@@ -78,8 +77,7 @@
 @skip_unless_tools_exist("img2txt", "identify")
 @skip_unless_tool_is_between("identify", identify_version, "6.9.6", "7.0.0")
 def test_diff_meta(differences_meta):
-    expected_diff = get_data("jpeg_image_meta_expected_diff")
-    assert differences_meta[-1].unified_diff == expected_diff
+    assert_diff(differences_meta[-1], "jpeg_image_meta_expected_diff")
 
 
 @skip_unless_tools_exist("img2txt", "convert", "identify")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_macho.py 
new/diffoscope-251/tests/comparators/test_macho.py
--- old/diffoscope-242/tests/comparators/test_macho.py  2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_macho.py  2023-10-13 
09:59:15.000000000 +0200
@@ -116,14 +116,25 @@
     # Sections
     arch_differences = obj_differences[-1].details
     assert len(arch_differences) == 7
-    filenames = [
-        "macho_llvm_expected_diff__text",
-        "macho_llvm_expected_diff__stubs",
-        "macho_llvm_expected_diff__stub_helper",
-        "macho_llvm_expected_diff__cstring",
-        "macho_llvm_expected_diff__unwind_info",
-        "macho_llvm_expected_diff__eh_frame",
-        "macho_llvm_expected_diff__la_symbol_ptr",
-    ]
+    if llvm_version() < "16":
+        filenames = [
+            "macho_llvm_expected_diff__text",
+            "macho_llvm_expected_diff__stubs",
+            "macho_llvm_expected_diff__stub_helper",
+            "macho_llvm_expected_diff__cstring",
+            "macho_llvm_expected_diff__unwind_info",
+            "macho_llvm_expected_diff__eh_frame",
+            "macho_llvm_expected_diff__la_symbol_ptr",
+        ]
+    else:
+        filenames = [
+            "macho_llvm_expected_diff__text_16",
+            "macho_llvm_expected_diff__stubs_16",
+            "macho_llvm_expected_diff__stub_helper_16",
+            "macho_llvm_expected_diff__cstring",
+            "macho_llvm_expected_diff__unwind_info",
+            "macho_llvm_expected_diff__eh_frame",
+            "macho_llvm_expected_diff__la_symbol_ptr",
+        ]
     for idx, diff in enumerate(arch_differences):
         assert_diff(diff, filenames[idx])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_rlib.py 
new/diffoscope-251/tests/comparators/test_rlib.py
--- old/diffoscope-242/tests/comparators/test_rlib.py   2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_rlib.py   2023-10-13 
09:59:15.000000000 +0200
@@ -86,6 +86,9 @@
     if actual_ver >= "15.0":
         diff_file = "rlib_llvm_dis_expected_diff_15"
 
+    if actual_ver >= "16.0":
+        diff_file = "rlib_llvm_dis_expected_diff_16"
+
     return get_data(diff_file)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_text.py 
new/diffoscope-251/tests/comparators/test_text.py
--- old/diffoscope-242/tests/comparators/test_text.py   2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_text.py   2023-10-13 
09:59:15.000000000 +0200
@@ -2,7 +2,7 @@
 # diffoscope: in-depth comparison of files, archives, and directories
 #
 # Copyright © 2015 Jérémy Bobbio <lu...@debian.org>
-# Copyright © 2015-2020 Chris Lamb <la...@debian.org>
+# Copyright © 2015-2020, 2023 Chris Lamb <la...@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
@@ -20,6 +20,7 @@
 import codecs
 
 from diffoscope.comparators.binary import FilesystemFile
+from diffoscope.comparators.text import TextFile
 from diffoscope.comparators.utils.specialize import specialize
 
 from ..utils.data import data, load_fixture, get_data
@@ -95,3 +96,13 @@
     difference = text_order1.compare(text_order2)
     assert difference.comments == ["Ordering differences only"]
     assert difference.unified_diff == get_data("text_order_expected_diff")
+
+
+def test_text_fallback(tmp_path):
+    """
+    If we don't know the exact type but it looks like text, compare it as text.
+    """
+    temp = tmp_path / "temp.msc"
+    temp.write_text("msc{a, b;}")
+    specialized = specialize(FilesystemFile(str(temp)))
+    assert isinstance(specialized, TextFile)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/comparators/test_uimage.py 
new/diffoscope-251/tests/comparators/test_uimage.py
--- old/diffoscope-242/tests/comparators/test_uimage.py 2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/comparators/test_uimage.py 2023-10-13 
09:59:15.000000000 +0200
@@ -23,8 +23,12 @@
 from diffoscope.comparators.uimage import UimageFile
 from diffoscope.comparators.utils.specialize import specialize
 
-from ..utils.data import load_fixture, get_data, assert_diff
-from ..utils.tools import skip_unless_tools_exist, file_version_is_lt
+from ..utils.data import load_fixture, assert_diff
+from ..utils.tools import (
+    skip_unless_tools_exist,
+    file_version_is_lt,
+    skip_unless_file_version_is_at_least,
+)
 from ..utils.nonexisting import assert_non_existing
 
 cpio1 = load_fixture("test1.cpio")
@@ -108,24 +112,23 @@
 
 @skip_unless_tools_exist("cpio")
 def test_nested_listing(nested_differences):
-    expected_diff = get_data("cpio_listing_expected_diff")
-    assert nested_differences[0].unified_diff == expected_diff
+    assert_diff(nested_differences[0], "cpio_listing_expected_diff")
 
 
 @skip_unless_tools_exist("cpio")
+@skip_unless_file_version_is_at_least("5.45")
 def test_nested_symlink(nested_differences):
-    assert nested_differences[1].source1 == "dir/link"
-    assert nested_differences[1].comment == "symlink"
-    expected_diff = get_data("symlink_expected_diff")
-    assert nested_differences[1].unified_diff == expected_diff
+    assert nested_differences[2].source1 == "dir/link"
+    assert nested_differences[2].comment == "symlink"
+    assert_diff(nested_differences[2], "symlink_expected_diff")
 
 
 @skip_unless_tools_exist("cpio")
+@skip_unless_file_version_is_at_least("5.45")
 def test_nested_compressed_files(nested_differences):
-    assert nested_differences[2].source1 == "dir/text"
-    assert nested_differences[2].source2 == "dir/text"
-    expected_diff = get_data("text_ascii_expected_diff")
-    assert nested_differences[2].unified_diff == expected_diff
+    assert nested_differences[3].source1 == "dir/text"
+    assert nested_differences[3].source2 == "dir/text"
+    assert_diff(nested_differences[3], "text_ascii_expected_diff")
 
 
 @skip_unless_tools_exist("cpio")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/diffoscope-242/tests/data/elfmix_mach_o_expected_diff__text_16 
new/diffoscope-251/tests/data/elfmix_mach_o_expected_diff__text_16
--- old/diffoscope-242/tests/data/elfmix_mach_o_expected_diff__text_16  
1970-01-01 01:00:00.000000000 +0100
+++ new/diffoscope-251/tests/data/elfmix_mach_o_expected_diff__text_16  
2023-10-13 09:59:15.000000000 +0200
@@ -0,0 +1,9 @@
+@@ -1,7 +1,7 @@
+ Contents of (__TEXT,__text) section
+ _return42_or_3:
+       pushq   %rbp
+       movq    %rsp, %rbp
+-      movl    $0x2a, %eax
++      movl    $0x2b, %eax
+       popq    %rbp
+       retq
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/diffoscope-242/tests/data/ico_image_meta_expected_diff 
new/diffoscope-251/tests/data/ico_image_meta_expected_diff
--- old/diffoscope-242/tests/data/ico_image_meta_expected_diff  2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/data/ico_image_meta_expected_diff  2023-10-13 
09:59:15.000000000 +0200
@@ -1,7 +1,4 @@
-@@ -1,17 +1,17 @@
- Image format: ICO
--File size: 6926B
-+File size: 3270B
+@@ -2,15 +2,15 @@
  Height: 100
  Width: 100
  Orientation: Undefined
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/diffoscope-242/tests/data/ico_image_meta_expected_diff_v2 
new/diffoscope-251/tests/data/ico_image_meta_expected_diff_v2
--- old/diffoscope-242/tests/data/ico_image_meta_expected_diff_v2       
2023-05-05 21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/data/ico_image_meta_expected_diff_v2       
2023-10-13 09:59:15.000000000 +0200
@@ -1,7 +1,4 @@
-@@ -1,17 +1,17 @@
- Image format: ICO
--File size: 6926B
-+File size: 3270B
+@@ -2,15 +2,15 @@
  Height: 100
  Width: 100
  Orientation: Undefined
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/diffoscope-242/tests/data/jpeg_image_meta_expected_diff 
new/diffoscope-251/tests/data/jpeg_image_meta_expected_diff
--- old/diffoscope-242/tests/data/jpeg_image_meta_expected_diff 2023-05-05 
21:05:32.000000000 +0200
+++ new/diffoscope-251/tests/data/jpeg_image_meta_expected_diff 2023-10-13 
09:59:15.000000000 +0200
@@ -1,7 +1,5 @@
-@@ -1,20 +1,20 @@
+@@ -1,19 +1,19 @@
  Image format: JPEG
--File size: 662B
-+File size: 627B
  Height: 100
  Width: 100
  Orientation: Undefined
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/diffoscope-242/tests/data/macho_llvm_expected_diff__stub_helper_16 
new/diffoscope-251/tests/data/macho_llvm_expected_diff__stub_helper_16
--- old/diffoscope-242/tests/data/macho_llvm_expected_diff__stub_helper_16      
1970-01-01 01:00:00.000000000 +0100
+++ new/diffoscope-251/tests/data/macho_llvm_expected_diff__stub_helper_16      
2023-10-13 09:59:15.000000000 +0200
@@ -0,0 +1,11 @@
+@@ -1,7 +1,7 @@
+ Contents of (__TEXT,__stub_helper) section
+-      leaq    0xa9(%rip), %r11
++      leaq    0x91(%rip), %r11
+       pushq   %r11
+-      jmpq    *0x99(%rip) ## literal pool symbol address: dyld_stub_binder
++      jmpq    *0x81(%rip) ## literal pool symbol address: dyld_stub_binder
+       nop
+       pushq   $0x0
+-      jmp     0x100000f58
++      jmp     0x100000f70
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/diffoscope-242/tests/data/macho_llvm_expected_diff__stubs_16 
new/diffoscope-251/tests/data/macho_llvm_expected_diff__stubs_16
--- old/diffoscope-242/tests/data/macho_llvm_expected_diff__stubs_16    
1970-01-01 01:00:00.000000000 +0100
+++ new/diffoscope-251/tests/data/macho_llvm_expected_diff__stubs_16    
2023-10-13 09:59:15.000000000 +0200
@@ -0,0 +1,4 @@
+@@ -1,2 +1,2 @@
+ Contents of (__TEXT,__stubs) section
+-      jmpq    *0xb8(%rip) ## literal pool symbol address: _printf
++      jmpq    *0xa0(%rip) ## literal pool symbol address: _printf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/diffoscope-242/tests/data/macho_llvm_expected_diff__text_16 
new/diffoscope-251/tests/data/macho_llvm_expected_diff__text_16
--- old/diffoscope-242/tests/data/macho_llvm_expected_diff__text_16     
1970-01-01 01:00:00.000000000 +0100
+++ new/diffoscope-251/tests/data/macho_llvm_expected_diff__text_16     
2023-10-13 09:59:15.000000000 +0200
@@ -0,0 +1,20 @@
+@@ -1,16 +1,15 @@
+ Contents of (__TEXT,__text) section
+ _main:
+       pushq   %rbp
+       movq    %rsp, %rbp
+       subq    $0x10, %rsp
+-      leaq    0x43(%rip), %rdi ## literal pool for: "%s %s\n"
+-      leaq    0x43(%rip), %rsi ## literal pool for: "17:31:50"
+-      leaq    0x45(%rip), %rdx ## literal pool for: "Wed Dec  2 17:31:49 2015"
++      leaq    0x3b(%rip), %rdi ## literal pool for: "%s\n"
++      leaq    0x38(%rip), %rsi ## literal pool for: "15:52:34"
+       movb    $0x0, %al
+-      callq   0x100000f52 ## symbol stub for: _printf
++      callq   0x100000f6a ## symbol stub for: _printf
+       xorl    %ecx, %ecx
+       movl    %eax, -0x4(%rbp)
+       movl    %ecx, %eax
+       addq    $0x10, %rsp
+       popq    %rbp
+       retq
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/diffoscope-242/tests/data/rlib_llvm_dis_expected_diff_16 
new/diffoscope-251/tests/data/rlib_llvm_dis_expected_diff_16
--- old/diffoscope-242/tests/data/rlib_llvm_dis_expected_diff_16        
1970-01-01 01:00:00.000000000 +0100
+++ new/diffoscope-251/tests/data/rlib_llvm_dis_expected_diff_16        
2023-10-13 09:59:15.000000000 +0200
@@ -0,0 +1,36 @@
+@@ -42,32 +42,32 @@
+ entry-block:
+   %out.i.i = alloca ptr, align 8
+   %4 = icmp ult i64 %3, 17
+   br i1 %4, label %then-block-195-.i, label 
%_ZN12alloc_system3imp8allocate17h8ba7625cc4a820e8E.exit.i
+ 
+ then-block-195-.i:                                ; preds = %entry-block
+   %5 = tail call ptr @realloc(ptr %0, i64 %2) #2
+-  br label %_ZN12alloc_system3imp10reallocate17h4a0811c9ec086854E.exit
++  br label %_ZN12alloc_system3imp10reallocate1l44a0811c9ec086854E.exit
+ 
+ _ZN12alloc_system3imp8allocate17h8ba7625cc4a820e8E.exit.i: ; preds = 
%entry-block
+   %6 = bitcast ptr %out.i.i to ptr
+   call void @llvm.lifetime.start.p0(i64 8, ptr %6) #2
+   store ptr null, ptr %out.i.i, align 8
+   %7 = call i32 @posix_memalign(ptr nonnull %out.i.i, i64 %3, i64 %2) #2
+   %8 = icmp eq i32 %7, 0
+   %9 = load ptr, ptr %out.i.i, align 8
+   %sret_slot.0.i.i = select i1 %8, ptr %9, ptr null
+   call void @llvm.lifetime.end.p0(i64 8, ptr %6) #2
+   %10 = icmp ule i64 %2, %1
+   %11 = select i1 %10, i64 %2, i64 %1
+   call void @llvm.memmove.p0.p0.i64(ptr align 1 %sret_slot.0.i.i, ptr align 1 
%0, i64 %11, i1 false) #2
+   call void @free(ptr %0) #2
+-  br label %_ZN12alloc_system3imp10reallocate17h4a0811c9ec086854E.exit
++  br label %_ZN12alloc_system3imp10reallocate1l44a0811c9ec086854E.exit
+ 
+-_ZN12alloc_system3imp10reallocate17h4a0811c9ec086854E.exit: ; preds = 
%_ZN12alloc_system3imp8allocate17h8ba7625cc4a820e8E.exit.i, %then-block-195-.i
++_ZN12alloc_system3imp10reallocate1l44a0811c9ec086854E.exit: ; preds = 
%_ZN12alloc_system3imp8allocate17h8ba7625cc4a820e8E.exit.i, %then-block-195-.i
+   %sret_slot.0.i = phi ptr [ %5, %then-block-195-.i ], [ %sret_slot.0.i.i, 
%_ZN12alloc_system3imp8allocate17h8ba7625cc4a820e8E.exit.i ]
+   ret ptr %sret_slot.0.i
+ }
+ 
+ ; Function Attrs: nounwind memory(none) uwtable
+ define i64 @__rust_reallocate_inplace(ptr nocapture readnone %0, i64 %1, i64 
%2, i64 %3) unnamed_addr #1 {
+ entry-block:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/diffoscope-242/tests/utils/tools.py 
new/diffoscope-251/tests/utils/tools.py
--- old/diffoscope-242/tests/utils/tools.py     2023-05-05 21:05:32.000000000 
+0200
+++ new/diffoscope-251/tests/utils/tools.py     2023-10-13 09:59:15.000000000 
+0200
@@ -157,7 +157,7 @@
         (vcls(str(actual_ver)) < vcls(str(min_ver)))
         or (vcls(str(actual_ver)) > vcls(str(max_ver))),
         reason="{} min {} >= {} ({} detected)".format(
-            reason(tool), min_ver, max_ver, actual_ver
+            reason(tool, force_include=True), min_ver, max_ver, actual_ver
         ),
         tools=(tool,),
     )
@@ -215,11 +215,11 @@
     return skip_unless_tool_is_at_least("file", file_version, version)
 
 
-def reason(*tools):
+def reason(*tools, force_include=False):
     xs = []
 
     for x in tools:
-        if not tools_missing(x):
+        if not tools_missing(x) and not force_include:
             continue
         provider = get_package_provider(x)
         if provider is None:
@@ -228,4 +228,7 @@
 
         xs.append("{} (try installing {})".format(x, provider))
 
+    if not xs:
+        return ""
+
     return "requires {}".format(" and ".join(xs))

Reply via email to