diff --git a/default.nix b/default.nix index e7f7185..0021b94 100644 --- a/default.nix +++ b/default.nix @@ -102,7 +102,7 @@ let # The canonical name is setuptools-scm setuptools-scm = super.setuptools_scm; - inherit (hooks) removePathDependenciesHook poetry2nixFixupHook; + inherit (hooks) pipBuildHook removePathDependenciesHook poetry2nixFixupHook; } ) # Null out any filtered packages, we don't want python.pkgs from nixpkgs diff --git a/hooks/default.nix b/hooks/default.nix index 12d2bc9..16a39a7 100644 --- a/hooks/default.nix +++ b/hooks/default.nix @@ -2,9 +2,12 @@ , callPackage , makeSetupHook , yj +, wheel +, pip }: let pythonInterpreter = python.pythonForBuild.interpreter; + pythonSitePackages = python.sitePackages; in { @@ -21,6 +24,17 @@ in } ./remove-path-dependencies.sh ) {}; + pipBuildHook = callPackage ( + { pip, wheel }: + makeSetupHook { + name = "pip-build-hook.sh"; + deps = [ pip wheel ]; + substitutions = { + inherit pythonInterpreter pythonSitePackages; + }; + } ./pip-build-hook.sh + ) {}; + poetry2nixFixupHook = callPackage ( {}: makeSetupHook { diff --git a/hooks/pip-build-hook.sh b/hooks/pip-build-hook.sh new file mode 100644 index 0000000..fa7b698 --- /dev/null +++ b/hooks/pip-build-hook.sh @@ -0,0 +1,50 @@ +# Setup hook to use for pip projects +echo "Sourcing pip-build-hook" + +pipBuildPhase() { + echo "Executing pipBuildPhase" + runHook preBuild + + # Prefer using setup.py to avoid build-system dependencies if we have a setup.py + if [ -z "${dontPreferSetupPy-}" ]; then + if test -e setup.py && test -e pyproject.toml; then + echo "Removing pyproject.toml..." + rm -f pyproject.toml + fi + fi + + mkdir -p dist + echo "Creating a wheel..." + @pythonInterpreter@ -m pip wheel --no-index --no-deps --no-clean --no-build-isolation --wheel-dir dist . + echo "Finished creating a wheel..." + + runHook postBuild + echo "Finished executing pipBuildPhase" +} + +pipShellHook() { + echo "Executing pipShellHook" + runHook preShellHook + + # Long-term setup.py should be dropped. + if [ -e pyproject.toml ]; then + tmp_path=$(mktemp -d) + export PATH="$tmp_path/bin:$PATH" + export PYTHONPATH="$tmp_path/@pythonSitePackages@:$PYTHONPATH" + mkdir -p "$tmp_path/@pythonSitePackages@" + @pythonInterpreter@ -m pip install -e . --prefix "$tmp_path" >&2 + fi + + runHook postShellHook + echo "Finished executing pipShellHook" +} + +if [ -z "${dontUsePipBuild-}" ] && [ -z "${buildPhase-}" ]; then + echo "Using pipBuildPhase" + buildPhase=pipBuildPhase +fi + +if [ -z "${shellHook-}" ]; then + echo "Using pipShellHook" + shellHook=pipShellHook +fi diff --git a/hooks/pyproject-without-path.py b/hooks/pyproject-without-path.py index bb61e4a..5d8fbcf 100644 --- a/hooks/pyproject-without-path.py +++ b/hooks/pyproject-without-path.py @@ -6,7 +6,14 @@ import sys data = json.load(sys.stdin) -for dep in data['tool']['poetry']['dependencies'].values(): + +def get_deep(o, path): + for p in path.split('.'): + o = o.get(p, {}) + return o + + +for dep in get_deep(data, 'tool.poetry.dependencies').values(): if isinstance(dep, dict): try: del dep['path']; diff --git a/mk-poetry-dep.nix b/mk-poetry-dep.nix index 5e71190..135ca7d 100644 --- a/mk-poetry-dep.nix +++ b/mk-poetry-dep.nix @@ -74,10 +74,10 @@ pythonPackages.callPackage ( format = if _isEgg then "egg" else if lib.strings.hasSuffix ".whl" name then "wheel" - else "setuptools"; + else "pyproject"; kind = if _isEgg then python.pythonVersion - else if format == "setuptools" then "source" + else if format == "pyproject" then "source" else (builtins.elemAt (lib.strings.splitString "-" name) 2); }; @@ -89,7 +89,7 @@ pythonPackages.callPackage ( ]; baseBuildInputs = lib.optional (! lib.elem name skipSetupToolsSCM) pythonPackages.setuptools-scm; - format = if isLocal then "pyproject" else if isGit then "setuptools" else fileInfo.format; + format = if isLocal then "pyproject" else if isGit then "pyproject" else fileInfo.format; in buildPythonPackage {