at 23.05-pre 3.2 kB view raw
1# shellcheck shell=bash 2 3# Setup hook that modifies Python dependencies versions. 4# 5# Example usage in a derivation: 6# 7# { …, pythonPackages, … }: 8# 9# pythonPackages.buildPythonPackage { 10# … 11# nativeBuildInputs = [ pythonPackages.pythonRelaxDepsHook ]; 12# 13# # This will relax the dependency restrictions 14# # e.g.: abc>1,<=2 -> abc 15# pythonRelaxDeps = [ "abc" ]; 16# # This will relax all dependencies restrictions instead 17# # pythonRelaxDeps = true; 18# # This will remove the dependency 19# # e.g.: cde>1,<=2 -> <nothing> 20# pythonRemoveDeps = [ "cde" ]; 21# # This will remove all dependencies from the project 22# # pythonRemoveDeps = true; 23# … 24# } 25# 26# IMPLEMENTATION NOTES: 27# 28# The "Requires-Dist" dependency specification format is described in PEP 508. 29# Examples that the regular expressions in this hook needs to support: 30# 31# Requires-Dist: foo 32# -> foo 33# Requires-Dist: foo[optional] 34# -> foo[optional] 35# Requires-Dist: foo[optional]~=1.2.3 36# -> foo[optional] 37# Requires-Dist: foo[optional, xyz] (~=1.2.3) 38# -> foo[optional, xyz] 39# Requires-Dist: foo[optional]~=1.2.3 ; os_name = "posix" 40# -> foo[optional] ; os_name = "posix" 41# 42# Currently unsupported: URL specs (foo @ https://example.com/a.zip). 43 44_pythonRelaxDeps() { 45 local -r metadata_file="$1" 46 47 if [[ -z "${pythonRelaxDeps:-}" ]] || [[ "$pythonRelaxDeps" == 0 ]]; then 48 return 49 elif [[ "$pythonRelaxDeps" == 1 ]]; then 50 sed -i "$metadata_file" -r \ 51 -e 's/(Requires-Dist: [a-zA-Z0-9_.-]+\s*(\[[^]]+\])?)[^;]*(;.*)?/\1\3/' 52 else 53 for dep in $pythonRelaxDeps; do 54 sed -i "$metadata_file" -r \ 55 -e "s/(Requires-Dist: $dep\s*(\[[^]]+\])?)[^;]*(;.*)?/\1\3/" 56 done 57 fi 58} 59 60_pythonRemoveDeps() { 61 local -r metadata_file="$1" 62 63 if [[ -z "${pythonRemoveDeps:-}" ]] || [[ "$pythonRemoveDeps" == 0 ]]; then 64 return 65 elif [[ "$pythonRemoveDeps" == 1 ]]; then 66 sed -i "$metadata_file" \ 67 -e '/Requires-Dist:.*/d' 68 else 69 for dep in $pythonRemoveDeps; do 70 sed -i "$metadata_file" \ 71 -e "/Requires-Dist: $dep/d" 72 done 73 fi 74 75} 76 77pythonRelaxDepsHook() { 78 pushd dist 79 80 # See https://peps.python.org/pep-0491/#escaping-and-unicode 81 local -r pkg_name="${pname//[^[:alnum:].]/_}-$version" 82 local -r unpack_dir="unpacked" 83 local -r metadata_file="$unpack_dir/$pkg_name/$pkg_name.dist-info/METADATA" 84 85 # We generally shouldn't have multiple wheel files, but let's be safer here 86 for wheel in "$pkg_name"*".whl"; do 87 @pythonInterpreter@ -m wheel unpack --dest "$unpack_dir" "$wheel" 88 rm -rf "$wheel" 89 90 _pythonRelaxDeps "$metadata_file" 91 _pythonRemoveDeps "$metadata_file" 92 93 if (( "${NIX_DEBUG:-0}" >= 1 )); then 94 echo "pythonRelaxDepsHook: resulting METADATA for '$wheel':" 95 cat "$unpack_dir/$pkg_name/$pkg_name.dist-info/METADATA" 96 fi 97 98 @pythonInterpreter@ -m wheel pack "$unpack_dir/$pkg_name" 99 done 100 101 # Remove the folder since it will otherwise be in the dist output. 102 rm -rf "$unpack_dir" 103 104 popd 105} 106 107postBuild+=" pythonRelaxDepsHook"