pythonPackages.pip: make reproducible (#102222)
The previous attempt wasn't covering all of the bases. It relied on invoking that pip-install-hook, and didn't apply to pip itself. The core issue is that the generated .pyc files embed some of the temporary paths, which are randomly generated. See https://r13y.com/diff/bf8c3ca3148ebff9ecf41f294cc60b9f209c006d49699e356969ff32d736f1c6-8806a7cca91fdd300e48736bfcd57c4d0b54c1cc2fd61609f35143170862b59c.html In this new attempt, the approach is to patch the TempFile implementation directly, so that it creates stable temporary directories. We also assume that if SOURCE_DATE_EPOCH is set, we are in a scenario where reproducible builds are desirable and enter that branch. See also https://github.com/pypa/pip/issues/7808
This commit is contained in:
parent
8f2be9ac36
commit
c409f69480
4 changed files with 32 additions and 15 deletions
|
@ -12,7 +12,7 @@ pipInstallPhase() {
|
||||||
|
|
||||||
pushd dist || return 1
|
pushd dist || return 1
|
||||||
mkdir tmpbuild
|
mkdir tmpbuild
|
||||||
NIX_PIP_INSTALL_TMPDIR=tmpbuild @pythonInterpreter@ -m pip install ./*.whl --no-index --prefix="$out" --no-cache $pipInstallFlags
|
@pythonInterpreter@ -m pip install ./*.whl --no-index --prefix="$out" --no-cache $pipInstallFlags
|
||||||
rm -rf tmpbuild
|
rm -rf tmpbuild
|
||||||
popd || return 1
|
popd || return 1
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,11 @@ stdenv.mkDerivation rec {
|
||||||
];
|
];
|
||||||
|
|
||||||
postPatch = ''
|
postPatch = ''
|
||||||
|
# Apply the pip reproducible patch
|
||||||
|
pushd "${pip.src.name}"
|
||||||
|
patch -p1 < ${../pip/reproducible.patch}
|
||||||
|
popd
|
||||||
|
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ buildPythonPackage rec {
|
||||||
};
|
};
|
||||||
|
|
||||||
# Remove when solved https://github.com/NixOS/nixpkgs/issues/81441
|
# Remove when solved https://github.com/NixOS/nixpkgs/issues/81441
|
||||||
# Also update pkgs/development/interpreters/python/hooks/pip-install-hook.sh accordingly
|
# See also https://github.com/pypa/pip/issues/7808
|
||||||
patches = [ ./reproducible.patch ];
|
patches = [ ./reproducible.patch ];
|
||||||
|
|
||||||
nativeBuildInputs = [ bootstrapped-pip ];
|
nativeBuildInputs = [ bootstrapped-pip ];
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
diff --git a/src/pip/_internal/operations/install/wheel.py b/src/pip/_internal/operations/install/wheel.py
|
diff --git a/src/pip/_internal/utils/temp_dir.py b/src/pip/_internal/utils/temp_dir.py
|
||||||
index e7315ee4..4e36b03d 100644
|
index 201ba6d98..f1569fecd 100644
|
||||||
--- a/src/pip/_internal/operations/install/wheel.py
|
--- a/src/pip/_internal/utils/temp_dir.py
|
||||||
+++ b/src/pip/_internal/operations/install/wheel.py
|
+++ b/src/pip/_internal/utils/temp_dir.py
|
||||||
@@ -615,6 +615,8 @@ def install_wheel(
|
@@ -3,6 +3,7 @@ from __future__ import absolute_import
|
||||||
direct_url=None, # type: Optional[DirectUrl]
|
import errno
|
||||||
):
|
import itertools
|
||||||
# type: (...) -> None
|
import logging
|
||||||
+ _temp_dir_for_testing = (
|
+import os
|
||||||
+ _temp_dir_for_testing or os.environ.get("NIX_PIP_INSTALL_TMPDIR"))
|
import os.path
|
||||||
with TempDirectory(
|
import tempfile
|
||||||
path=_temp_dir_for_testing, kind="unpacked-wheel"
|
from contextlib import contextmanager
|
||||||
) as unpacked_dir, ZipFile(wheel_path, allowZip64=True) as z:
|
@@ -181,6 +182,11 @@ class TempDirectory(object):
|
||||||
|
# symlinked to another directory. This tends to confuse build
|
||||||
|
# scripts, so we canonicalize the path by traversing potential
|
||||||
|
# symlinks here.
|
||||||
|
+ if "SOURCE_DATE_EPOCH" in os.environ:
|
||||||
|
+ path = os.path.join(tempfile.gettempdir(), "pip-{}-immobile".format(kind))
|
||||||
|
+ os.mkdir(path)
|
||||||
|
+ return path
|
||||||
|
+
|
||||||
|
path = os.path.realpath(
|
||||||
|
tempfile.mkdtemp(prefix="pip-{}-".format(kind))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue