1{ lib, stdenv
2, fetchFromGitLab
3, fetchpatch
4, python3
5, librsync
6, ncftp
7, gnupg
8, gnutar
9, par2cmdline
10, util-linux
11, rsync
12, makeWrapper
13, gettext
14}:
15let
16 pythonPackages = python3.pkgs;
17 inherit (lib.versions) majorMinor splitVersion;
18 majorMinorPatch = v: builtins.concatStringsSep "." (lib.take 3 (splitVersion v));
19in
20pythonPackages.buildPythonApplication rec {
21 pname = "duplicity";
22 version = "0.8.23";
23
24 src = fetchFromGitLab {
25 owner = "duplicity";
26 repo = "duplicity";
27 rev = "rel.${version}";
28 sha256 = "0my015zc8751smjgbsysmca7hvdm96cjw5zilqn3zq971nmmrksb";
29 };
30
31 patches = [
32 # We use the tar binary on all platforms.
33 ./gnutar-in-test.patch
34
35 # Our Python infrastructure runs test in installCheckPhase so we need
36 # to make the testing code stop assuming it is run from the source directory.
37 ./use-installed-scripts-in-test.patch
38 ] ++ lib.optionals stdenv.isLinux [
39 # Broken on Linux in Nix' build environment
40 ./linux-disable-timezone-test.patch
41 ];
42
43 SETUPTOOLS_SCM_PRETEND_VERSION = version;
44
45 preConfigure = ''
46 # fix version displayed by duplicity --version
47 # see SourceCopy in setup.py
48 ls
49 for i in bin/*.1 duplicity/__init__.py; do
50 substituteInPlace "$i" --replace '$version' "${version}"
51 done
52 '';
53
54 nativeBuildInputs = [
55 makeWrapper
56 gettext
57 pythonPackages.wrapPython
58 pythonPackages.setuptools-scm
59 ];
60 buildInputs = [
61 librsync
62 ];
63
64 pythonPath = with pythonPackages; [
65 b2sdk
66 boto3
67 cffi
68 cryptography
69 ecdsa
70 idna
71 pygobject3
72 fasteners
73 lockfile
74 paramiko
75 pyasn1
76 pycrypto
77 pydrive2
78 future
79 ];
80
81 checkInputs = [
82 gnupg # Add 'gpg' to PATH.
83 gnutar # Add 'tar' to PATH.
84 librsync # Add 'rdiff' to PATH.
85 par2cmdline # Add 'par2' to PATH.
86 ] ++ lib.optionals stdenv.isLinux [
87 util-linux # Add 'setsid' to PATH.
88 ] ++ (with pythonPackages; [
89 lockfile
90 mock
91 pexpect
92 pytest
93 pytest-runner
94 ]);
95
96 postInstall = ''
97 wrapProgram $out/bin/duplicity \
98 --prefix PATH : "${lib.makeBinPath [ gnupg ncftp rsync ]}"
99 '';
100
101 preCheck = ''
102 wrapPythonProgramsIn "$PWD/testing/overrides/bin" "$pythonPath"
103
104 # Add 'duplicity' to PATH for tests.
105 # Normally, 'setup.py test' adds 'build/scripts-2.7/' to PATH before running
106 # tests. However, 'build/scripts-2.7/duplicity' is not wrapped, so its
107 # shebang is incorrect and it fails to run inside Nix' sandbox.
108 # In combination with use-installed-scripts-in-test.patch, make 'setup.py
109 # test' use the installed 'duplicity' instead.
110 PATH="$out/bin:$PATH"
111
112 # Don't run developer-only checks (pep8, etc.).
113 export RUN_CODE_TESTS=0
114
115 # check version string
116 duplicity --version | grep ${version}
117 '' + lib.optionalString stdenv.isDarwin ''
118 # Work around the following error when running tests:
119 # > Max open files of 256 is too low, should be >= 1024.
120 # > Use 'ulimit -n 1024' or higher to correct.
121 ulimit -n 1024
122 '';
123
124 # TODO: Fix test failures on macOS 10.13:
125 #
126 # > OSError: out of pty devices
127 doCheck = !stdenv.isDarwin;
128
129 meta = with lib; {
130 description = "Encrypted bandwidth-efficient backup using the rsync algorithm";
131 homepage = "https://duplicity.gitlab.io/duplicity-web/";
132 license = licenses.gpl2Plus;
133 platforms = platforms.unix;
134 };
135}