99 lines
2.6 KiB
Nix
99 lines
2.6 KiB
Nix
{
|
|
buildPythonPackage,
|
|
lib,
|
|
hatchling,
|
|
tomli-w,
|
|
}:
|
|
{
|
|
pname,
|
|
version,
|
|
|
|
# Editable root as string.
|
|
# Environment variables will be expanded at runtime using os.path.expandvars.
|
|
root,
|
|
|
|
# Arguments passed on verbatim to buildPythonPackage
|
|
derivationArgs ? { },
|
|
|
|
# Python dependencies
|
|
dependencies ? [ ],
|
|
optional-dependencies ? { },
|
|
|
|
# PEP-518 build-system https://peps.python.org/pep-518
|
|
build-system ? [ ],
|
|
|
|
# PEP-621 entry points https://peps.python.org/pep-0621/#entry-points
|
|
scripts ? { },
|
|
gui-scripts ? { },
|
|
entry-points ? { },
|
|
|
|
passthru ? { },
|
|
meta ? { },
|
|
}:
|
|
|
|
# Create a PEP-660 (https://peps.python.org/pep-0660/) editable package pointing to an impure location outside the Nix store.
|
|
# The primary use case of this function is to enable local development workflows where the local package is installed into a virtualenv-like environment using withPackages.
|
|
|
|
assert lib.isString root;
|
|
let
|
|
# In editable mode build-system's are considered to be runtime dependencies.
|
|
dependencies' = dependencies ++ build-system;
|
|
|
|
pyproject = {
|
|
# PEP-621 project table
|
|
project = {
|
|
name = pname;
|
|
inherit
|
|
version
|
|
scripts
|
|
gui-scripts
|
|
entry-points
|
|
;
|
|
dependencies = map lib.getName dependencies';
|
|
optional-dependencies = lib.mapAttrs (_: lib.getName) optional-dependencies;
|
|
};
|
|
|
|
# Allow empty package
|
|
tool.hatch.build.targets.wheel.bypass-selection = true;
|
|
|
|
# Include our editable pointer file in build
|
|
tool.hatch.build.targets.wheel.force-include."_${pname}.pth" = "_${pname}.pth";
|
|
|
|
# Build editable package using hatchling
|
|
build-system = {
|
|
requires = [ "hatchling" ];
|
|
build-backend = "hatchling.build";
|
|
};
|
|
};
|
|
|
|
in
|
|
buildPythonPackage (
|
|
{
|
|
inherit
|
|
pname
|
|
version
|
|
optional-dependencies
|
|
passthru
|
|
meta
|
|
;
|
|
dependencies = dependencies';
|
|
|
|
pyproject = true;
|
|
|
|
unpackPhase = ''
|
|
python -c "import json, tomli_w; print(tomli_w.dumps(json.load(open('$pyprojectContentsPath'))))" > pyproject.toml
|
|
echo 'import os.path, sys; sys.path.insert(0, os.path.expandvars("${root}"))' > _${pname}.pth
|
|
'';
|
|
|
|
build-system = [ hatchling ];
|
|
}
|
|
// derivationArgs
|
|
// {
|
|
# Note: Using formats.toml generates another intermediary derivation that needs to be built.
|
|
# We inline the same functionality for better UX.
|
|
nativeBuildInputs = (derivationArgs.nativeBuildInputs or [ ]) ++ [ tomli-w ];
|
|
pyprojectContents = builtins.toJSON pyproject;
|
|
passAsFile = [ "pyprojectContents" ];
|
|
preferLocalBuild = true;
|
|
}
|
|
)
|