1{
2 lib,
3 stdenv,
4 aapt,
5 abootimg,
6 acl,
7 apksigcopier,
8 apksigner,
9 apktool,
10 binutils-unwrapped-all-targets,
11 bzip2,
12 cbfstool,
13 cdrkit,
14 colord,
15 colordiff,
16 coreutils,
17 cpio,
18 db,
19 diffutils,
20 docutils,
21 dtc,
22 e2fsprogs,
23 enableBloat ? true,
24 enjarify,
25 fetchurl,
26 file,
27 findutils,
28 fontforge-fonttools,
29 ffmpeg,
30 fpc,
31 gettext,
32 ghc,
33 ghostscriptX,
34 giflib,
35 gnumeric,
36 gnupg,
37 gnutar,
38 gzip,
39 hdf5,
40 help2man,
41 html2text,
42 imagemagick,
43 installShellFiles,
44 jdk8,
45 libarchive,
46 libcaca,
47 libxmlb,
48 llvm,
49 lz4,
50 lzip,
51 mono,
52 ocaml,
53 odt2txt,
54 oggvideotools,
55 openssh,
56 openssl,
57 pdftk,
58 perl,
59 pgpdump,
60 poppler-utils,
61 procyon,
62 python3,
63 qemu,
64 R,
65 sng,
66 sqlite,
67 squashfsTools,
68 systemdUkify,
69 tcpdump,
70 ubootTools,
71 unzip,
72 wabt,
73 xmlbeans,
74 xxd,
75 xz,
76 zip,
77 zstd,
78 binwalk,
79 # updater only
80 writeScript,
81}:
82
83let
84 python = python3.override {
85 self = python;
86 packageOverrides = final: prev: {
87 # version 4 or newer would log the following error but tests currently don't fail because radare2 is disabled
88 # ValueError: argument TNULL is not a TLSH hex string
89 tlsh = prev.tlsh.overridePythonAttrs (
90 { src, ... }:
91 let
92 version = "3.19.1";
93 in
94 {
95 inherit version;
96 src = src.override {
97 tag = version;
98 hash = "sha256-ZYEjT/yShfA4+zpbGOtaFOx1nSSOWPtMvskPhHv3c9U=";
99 };
100 }
101 );
102 };
103 };
104in
105
106# Note: when upgrading this package, please run the list-missing-tools.sh script as described below!
107python.pkgs.buildPythonApplication rec {
108 pname = "diffoscope";
109 version = "302";
110 pyproject = true;
111
112 src = fetchurl {
113 url = "https://diffoscope.org/archive/diffoscope-${version}.tar.bz2";
114 hash = "sha256-PngiG+nPaPrGHt+uTeH7R+MlKjPXFxfkFiDo6+pssTw=";
115 };
116
117 outputs = [
118 "out"
119 "man"
120 ];
121
122 patches = [ ./ignore_links.patch ];
123
124 postPatch = ''
125 # When generating manpage, use the installed version
126 substituteInPlace doc/Makefile --replace-fail "../bin" "$out/bin"
127
128 substituteInPlace diffoscope/comparators/apk.py \
129 --replace-fail "from androguard.core.bytecodes import apk" "from androguard.core import apk"
130 '';
131
132 nativeBuildInputs = [
133 docutils
134 help2man
135 installShellFiles
136 ];
137
138 build-system = with python.pkgs; [ setuptools ];
139
140 # Most of the non-Python dependencies here are optional command-line tools for various file-format parsers.
141 # To help figuring out what's missing from the list, run: ./pkgs/tools/misc/diffoscope/list-missing-tools.sh
142 #
143 # Still missing these tools:
144 # Android-specific tools:
145 # dexdump
146 # Darwin-specific tools:
147 # lipo
148 # otool
149 # Other tools:
150 # docx2txt <- makes tests broken:
151 # > FAILED tests/comparators/test_docx.py::test_diff - IndexError: list index out of range
152 # > FAILED tests/comparators/test_docx.py::test_compare_non_existing - AssertionError
153 # radare2
154 # > FAILED tests/comparators/test_elf_decompiler.py::test_ghidra_diff - IndexError: list index out of range
155 # > FAILED tests/comparators/test_elf_decompiler.py::test_radare2_diff - AssertionError
156 # > FAILED tests/comparators/test_macho_decompiler.py::test_ghidra_diff - assert 0 == 1
157 # > FAILED tests/comparators/test_macho_decompiler.py::test_radare2_diff - AssertionError
158 #
159 # We filter automatically all packages for the host platform (some dependencies are not supported on Darwin, aarch64, etc.).
160 # Packages which are marked broken for a platform are not automatically filtered to avoid accidentally removing them without noticing it.
161 pythonPath = lib.filter (lib.meta.availableOn stdenv.hostPlatform) (
162 [
163 acl
164 binutils-unwrapped-all-targets
165 bzip2
166 cdrkit
167 colordiff
168 coreutils
169 cpio
170 db
171 diffutils
172 dtc
173 e2fsprogs
174 file
175 findutils
176 fontforge-fonttools
177 gettext
178 gnutar
179 gzip
180 html2text
181 libarchive
182 libxmlb
183 lz4
184 lzip
185 openssl
186 pgpdump
187 sng
188 sqlite
189 squashfsTools
190 unzip
191 xxd
192 xz
193 zip
194 zstd
195 ]
196 ++ (with python.pkgs; [
197 argcomplete
198 python-debian
199 defusedxml
200 jsbeautifier
201 jsondiff
202 libarchive-c
203 progressbar33
204 pypdf
205 python-magic
206 pyxattr
207 rpm
208 tlsh
209 ])
210 ++ lib.optionals enableBloat (
211 [
212 aapt
213 abootimg
214 apksigcopier
215 apksigner
216 apktool
217 cbfstool
218 colord
219 enjarify
220 ffmpeg
221 fpc
222 ghc
223 ghostscriptX
224 giflib
225 gnumeric
226 gnupg
227 hdf5
228 imagemagick
229 jdk8
230 libcaca
231 llvm
232 mono
233 ocaml
234 odt2txt
235 openssh
236 pdftk
237 perl
238 poppler-utils
239 procyon
240 qemu
241 R
242 systemdUkify
243 tcpdump
244 ubootTools
245 wabt
246 xmlbeans
247 binwalk
248 ]
249 ++ (with python.pkgs; [
250 androguard
251 black
252 guestfs
253 h5py
254 pdfminer-six
255 r2pipe
256 # docx2txt, nixpkgs packages another project named the same, which does not work
257 ])
258 # oggvideotools is broken on Darwin, please put it back when it will be fixed?
259 ++ lib.optionals stdenv.hostPlatform.isLinux [ oggvideotools ]
260 )
261 );
262
263 nativeCheckInputs = with python.pkgs; [ pytestCheckHook ] ++ pythonPath;
264
265 pytestFlags = [
266 # Always show more information when tests fail
267 "-vv"
268 ];
269
270 postInstall = ''
271 make -C doc
272 installManPage doc/diffoscope.1
273 '';
274
275 disabledTests = [
276 "test_sbin_added_to_path"
277 "test_diff_meta"
278 "test_diff_meta2"
279
280 # Fails because it fails to determine llvm version
281 "test_item3_deflate_llvm_bitcode"
282
283 # Flaky test on Linux and Darwin
284 "test_non_unicode_filename"
285 ]
286 ++ lib.optionals stdenv.hostPlatform.isDarwin [
287 # Disable flaky tests on Darwin
288 "test_listing"
289 "test_symlink_root"
290
291 # Appears to be a sandbox related issue
292 "test_trim_stderr_in_command"
293 # Seems to be a bug caused by having different versions of rdata than
294 # expected. Will file upstream.
295 "test_item_rdb"
296 # Caused by getting an otool command instead of llvm-objdump. Could be Nix
297 # setup, could be upstream bug. Will file upstream.
298 "test_libmix_differences"
299 ];
300
301 disabledTestPaths = lib.optionals stdenv.hostPlatform.isDarwin [
302 "tests/comparators/test_git.py"
303 "tests/comparators/test_java.py"
304 "tests/comparators/test_uimage.py"
305 "tests/comparators/test_device.py"
306 "tests/comparators/test_macho.py"
307 ];
308
309 passthru = {
310 updateScript = writeScript "update-diffoscope" ''
311 #!/usr/bin/env nix-shell
312 #!nix-shell -i bash -p curl pcre common-updater-scripts
313
314 set -eu -o pipefail
315
316 # Expect the text in format of "Latest release: 198 (31 Dec 2021)"'.
317 newVersion="$(curl -s https://diffoscope.org/ | pcregrep -o1 'Latest release: ([0-9]+)')"
318 update-source-version ${pname} "$newVersion"
319 '';
320 };
321
322 meta = {
323 description = "Perform in-depth comparison of files, archives, and directories";
324 longDescription = ''
325 diffoscope will try to get to the bottom of what makes files or directories
326 different. It will recursively unpack archives of many kinds and transform
327 various binary formats into more human readable form to compare them. It can
328 compare two tarballs, ISO images, or PDF just as easily. The differences can
329 be shown in a text or HTML report.
330
331 diffoscope is developed as part of the "reproducible builds" Debian
332 project and was formerly known as "debbindiff".
333 '';
334 homepage = "https://diffoscope.org/";
335 changelog = "https://diffoscope.org/news/diffoscope-${version}-released/";
336 license = lib.licenses.gpl3Plus;
337 maintainers = with lib.maintainers; [
338 dezgeg
339 danielfullmer
340 raitobezarius
341 ];
342 platforms = lib.platforms.unix;
343 mainProgram = "diffoscope";
344 };
345}