python3Packages.ruff: reuse already built ruff binary

The maturin build system cannot see that we already build the ruff binary in nixpkgs.
This leads to the ruff binary being rebuilt and placed inside of the resulting Python package.
Every nixpkgs-review that passes through the `pkgs.ruff` package therefore builds `ruff` 3 times per architecture.
Said binary was never even used due to the patching that already occurs in `find_ruff_bin`.

Especially with how time-consuming release builds can be in Rust, there is no reason to keep this package in this state.

master: `nix-build -A python3Packages.ruff` - `0.44s user 0.28s system 0% cpu 5:09.64 total`
branch: `nix-build -A python3Packages.ruff` - `0.36s user 0.12s system 9% cpu 4.856 total`
This commit is contained in:
Benjamin Sparks 2025-05-30 01:23:15 +02:00
parent 018ae0a295
commit cf311adc99

View file

@ -1,8 +1,8 @@
{
buildPythonPackage,
hatchling,
lib,
ruff,
rustPlatform,
installShellFiles,
}:
buildPythonPackage {
@ -10,26 +10,38 @@ buildPythonPackage {
pname
version
src
cargoDeps
postInstall
meta
;
# Do not rely on path lookup at runtime to find the ruff binary
postPatch = ''
substituteInPlace python/ruff/__main__.py \
--replace-fail \
'ruff_exe = "ruff" + sysconfig.get_config_var("EXE")' \
'return "${placeholder "out"}/bin/ruff"'
'';
pyproject = true;
nativeBuildInputs = [
installShellFiles
rustPlatform.cargoSetupHook
rustPlatform.maturinBuildHook
];
build-system = [ hatchling ];
postPatch =
# Do not rely on path lookup at runtime to find the ruff binary.
# Use the propagated binary instead.
''
substituteInPlace python/ruff/__main__.py \
--replace-fail \
'ruff_exe = "ruff" + sysconfig.get_config_var("EXE")' \
'return "${lib.getExe ruff}"'
''
# Sidestep the maturin build system in favour of reusing the binary already built by nixpkgs,
# to avoid rebuilding the ruff binary for every active python package set.
+ ''
substituteInPlace pyproject.toml \
--replace-fail 'requires = ["maturin>=1.0,<2.0"]' 'requires = ["hatchling"]' \
--replace-fail 'build-backend = "maturin"' 'build-backend = "hatchling.build"'
cat >> pyproject.toml <<EOF
[tool.hatch.build]
packages = ['python/ruff']
EOF
'';
postInstall = ''
mkdir -p $out/bin && ln -s ${lib.getExe ruff} $out/bin/ruff
'';
pythonImportsCheck = [ "ruff" ];
}