There was no noticeable positive impact from having coverage reports on every single test run. While adding a separate command to check coverage might be added in the future, the overhead of collecting the coverage for every test run made seems not worth it currently.
313 lines
9.3 KiB
Nix
313 lines
9.3 KiB
Nix
{
|
|
# callPackage args
|
|
gnupg,
|
|
installShellFiles,
|
|
jq,
|
|
lib,
|
|
nix,
|
|
pkgs,
|
|
runCommand,
|
|
stdenv,
|
|
# custom args
|
|
clan-core-path,
|
|
includedRuntimeDeps,
|
|
nix-select,
|
|
nixpkgs,
|
|
pythonRuntime,
|
|
setupNixInNix,
|
|
templateDerivation,
|
|
}:
|
|
let
|
|
pyDeps = ps: [
|
|
ps.argcomplete # Enables shell completions
|
|
];
|
|
devDeps = ps: [
|
|
ps.ipython
|
|
];
|
|
pyTestDeps =
|
|
ps:
|
|
[
|
|
ps.pytest
|
|
ps.pytest-subprocess
|
|
ps.pytest-xdist
|
|
ps.pytest-timeout
|
|
]
|
|
++ (pyDeps ps);
|
|
pythonRuntimeWithDeps = pythonRuntime.withPackages (ps: pyDeps ps);
|
|
|
|
# load nixpkgs runtime dependencies from a json file
|
|
# This file represents an allow list at the same time that is checked by the run_cmd
|
|
# implementation in nix.py
|
|
allDependencies = lib.importJSON ./clan_lib/nix/allowed-packages.json;
|
|
generateRuntimeDependenciesMap =
|
|
deps:
|
|
lib.filterAttrs (_: pkg: !pkg.meta.unsupported or false) (lib.genAttrs deps (name: pkgs.${name}));
|
|
testRuntimeDependenciesMap = generateRuntimeDependenciesMap allDependencies;
|
|
testRuntimeDependencies = (lib.attrValues testRuntimeDependenciesMap);
|
|
bundledRuntimeDependenciesMap = generateRuntimeDependenciesMap includedRuntimeDeps;
|
|
bundledRuntimeDependencies = lib.attrValues bundledRuntimeDependenciesMap;
|
|
|
|
testDependencies = testRuntimeDependencies ++ [
|
|
gnupg
|
|
stdenv.cc # Compiler used for certain native extensions
|
|
(pythonRuntime.withPackages pyTestDeps)
|
|
];
|
|
|
|
nixFilter = import ../../lib/filter-clan-core/nix-filter.nix;
|
|
|
|
cliSource =
|
|
source:
|
|
runCommand "clan-cli-source"
|
|
{
|
|
nativeBuildInputs = [ jq ];
|
|
}
|
|
''
|
|
cp -r ${source} $out
|
|
chmod -R +w $out
|
|
|
|
# In cases where the devshell created this file, this will already exist
|
|
rm -f $out/clan_lib/nixpkgs
|
|
rm -f $out/clan_lib/select
|
|
|
|
substituteInPlace $out/clan_lib/flake/flake.py \
|
|
--replace-fail '@fallback_nixpkgs_hash@' "$(jq -r '.nodes.nixpkgs.locked.narHash' ${nixpkgs'}/flake.lock)" \
|
|
--replace-fail '@select_hash@' "$(jq -r '.nodes."nix-select".locked.narHash' ${../../flake.lock})"
|
|
ln -sf ${nixpkgs'} $out/clan_lib/nixpkgs
|
|
ln -sf ${nix-select} $out/clan_lib/select
|
|
cp -r ${../../templates} $out/clan_lib/clan_core_templates
|
|
'';
|
|
|
|
sourceWithoutTests = cliSource (
|
|
nixFilter.filter {
|
|
root = ./.;
|
|
include = [
|
|
(
|
|
_root: path: _type:
|
|
(builtins.match ".*/test_[^/]+\.py" path) == null
|
|
&& (builtins.match ".*/[^/]+_test\.py" path) == null
|
|
# && (builtins.match ".*/tests/.+" path) == null
|
|
)
|
|
];
|
|
}
|
|
);
|
|
sourceWithTests = cliSource ./.;
|
|
|
|
# Create a custom nixpkgs for use within the project
|
|
nixpkgs' =
|
|
runCommand "nixpkgs"
|
|
{
|
|
# Not all versions have `nix flake update --flake` option
|
|
nativeBuildInputs = [ nix ];
|
|
}
|
|
''
|
|
mkdir $out
|
|
cat > $out/flake.nix << EOF
|
|
{
|
|
description = "dependencies for the clan-cli";
|
|
|
|
inputs = {
|
|
nixpkgs.url = "path://${nixpkgs}";
|
|
};
|
|
|
|
outputs = _inputs: { };
|
|
}
|
|
EOF
|
|
ln -sf ${nixpkgs} $out/path
|
|
HOME=$TMPDIR nix flake update --flake $out \
|
|
--store ./. \
|
|
--extra-experimental-features 'nix-command flakes'
|
|
'';
|
|
in
|
|
pythonRuntime.pkgs.buildPythonApplication {
|
|
name = "clan-cli";
|
|
src = sourceWithoutTests;
|
|
format = "pyproject";
|
|
|
|
# Arguments for the wrapper to unset LD_LIBRARY_PATH to avoid glibc version issues
|
|
makeWrapperArgs = [
|
|
"--unset LD_LIBRARY_PATH"
|
|
"--unset PYTHONPATH"
|
|
|
|
# include selected runtime dependencies in the PATH
|
|
"--prefix"
|
|
"PATH"
|
|
":"
|
|
(lib.makeBinPath (lib.attrValues bundledRuntimeDependenciesMap))
|
|
|
|
"--set"
|
|
"CLAN_PROVIDED_PACKAGES"
|
|
(lib.concatStringsSep ":" (lib.attrNames bundledRuntimeDependenciesMap))
|
|
];
|
|
|
|
nativeBuildInputs = [
|
|
(pythonRuntime.withPackages (ps: [ ps.setuptools ]))
|
|
installShellFiles
|
|
];
|
|
|
|
propagatedBuildInputs = [ pythonRuntimeWithDeps ] ++ bundledRuntimeDependencies;
|
|
|
|
passthru.tests =
|
|
{
|
|
clan-deps = pkgs.runCommand "clan-deps" { } ''
|
|
# ${builtins.toString (builtins.attrValues testRuntimeDependenciesMap)}
|
|
touch $out
|
|
'';
|
|
clan-pytest-without-core =
|
|
runCommand "clan-pytest-without-core"
|
|
{
|
|
nativeBuildInputs = testDependencies;
|
|
closureInfo = pkgs.closureInfo {
|
|
rootPaths = [
|
|
templateDerivation
|
|
];
|
|
};
|
|
}
|
|
''
|
|
set -euo pipefail
|
|
cp -r ${sourceWithTests} ./src
|
|
chmod +w -R ./src
|
|
cd ./src
|
|
|
|
export NIX_STATE_DIR=$TMPDIR/nix IN_NIX_SANDBOX=1 PYTHONWARNINGS=error
|
|
|
|
# required to prevent concurrent 'nix flake lock' operations
|
|
export CLAN_TEST_STORE=$TMPDIR/store
|
|
export LOCK_NIX=$TMPDIR/nix_lock
|
|
mkdir -p "$CLAN_TEST_STORE/nix/store"
|
|
|
|
# limit build cores to 16
|
|
jobs="$((NIX_BUILD_CORES>16 ? 16 : NIX_BUILD_CORES))"
|
|
|
|
python -m pytest -m "not impure and not with_core" -n $jobs ./clan_cli ./clan_lib
|
|
touch $out
|
|
'';
|
|
}
|
|
// lib.optionalAttrs (!stdenv.isDarwin) {
|
|
# disabled on macOS until we fix all remaining issues
|
|
clan-pytest-with-core =
|
|
runCommand "clan-pytest-with-core"
|
|
{
|
|
nativeBuildInputs = testDependencies;
|
|
buildInputs = [
|
|
pkgs.bash
|
|
pkgs.coreutils
|
|
pkgs.nix
|
|
];
|
|
closureInfo = pkgs.closureInfo {
|
|
rootPaths = [
|
|
templateDerivation
|
|
pkgs.bash
|
|
pkgs.coreutils
|
|
pkgs.jq.dev
|
|
pkgs.stdenv
|
|
pkgs.stdenvNoCC
|
|
pkgs.shellcheck-minimal
|
|
];
|
|
};
|
|
}
|
|
''
|
|
set -euo pipefail
|
|
cp -r ${sourceWithTests} ./src
|
|
chmod +w -R ./src
|
|
cd ./src
|
|
|
|
${setupNixInNix}
|
|
|
|
export CLAN_CORE_PATH=${clan-core-path}
|
|
export PYTHONWARNINGS=error
|
|
|
|
# limit build cores to 16
|
|
jobs="$((NIX_BUILD_CORES>16 ? 16 : NIX_BUILD_CORES))"
|
|
|
|
python -m pytest -m "not impure and with_core" ./clan_cli -n $jobs
|
|
touch $out
|
|
'';
|
|
}
|
|
// lib.optionalAttrs (!stdenv.isDarwin) {
|
|
# disabled on macOS until we fix all remaining issues
|
|
clan-lib-pytest =
|
|
runCommand "clan-lib-pytest"
|
|
{
|
|
nativeBuildInputs = testDependencies;
|
|
buildInputs = [
|
|
pkgs.bash
|
|
pkgs.coreutils
|
|
pkgs.nix
|
|
|
|
];
|
|
closureInfo = pkgs.closureInfo {
|
|
rootPaths = [
|
|
templateDerivation
|
|
pkgs.bash
|
|
pkgs.coreutils
|
|
pkgs.jq.dev
|
|
pkgs.stdenv
|
|
pkgs.stdenvNoCC
|
|
pkgs.openssh
|
|
pkgs.shellcheck-minimal
|
|
pkgs.mkpasswd
|
|
pkgs.xkcdpass
|
|
nix-select
|
|
];
|
|
};
|
|
}
|
|
''
|
|
set -euo pipefail
|
|
cp -r ${sourceWithTests} ./src
|
|
chmod +w -R ./src
|
|
cd ./src
|
|
|
|
${setupNixInNix}
|
|
|
|
export CLAN_CORE_PATH=${clan-core-path}
|
|
export PYTHONWARNINGS=error
|
|
|
|
# used for tests without flakes
|
|
export NIXPKGS=${nixpkgs}
|
|
export NIX_SELECT=${nix-select}
|
|
|
|
# limit build cores to 4
|
|
jobs="$((NIX_BUILD_CORES>4 ? 4 : NIX_BUILD_CORES))"
|
|
|
|
python -m pytest -m "with_core" ./clan_lib -n $jobs
|
|
touch $out
|
|
'';
|
|
};
|
|
|
|
passthru.nixpkgs = nixpkgs';
|
|
passthru.devshellPyDeps = ps: (pyTestDeps ps) ++ (pyDeps ps) ++ (devDeps ps);
|
|
passthru.pythonRuntime = pythonRuntime;
|
|
passthru.runtimeDependencies = bundledRuntimeDependencies;
|
|
passthru.runtimeDependenciesMap = bundledRuntimeDependenciesMap;
|
|
passthru.testRuntimeDependencies = testRuntimeDependencies;
|
|
passthru.testRuntimeDependenciesMap = testRuntimeDependenciesMap;
|
|
|
|
# Nixpkgs doesn't get copied from `src` as it's not in `package-data` in `pyproject.toml`
|
|
# as it significantly slows down the build so we copy it again here
|
|
# We don't copy `select` using `package-data` as Python globs don't include hidden directories
|
|
# leading to a different NAR hash and copying it here would also lead to `patchShebangs`
|
|
# changing the contents
|
|
postInstall = ''
|
|
cp -r ${nixpkgs'} $out/${pythonRuntime.sitePackages}/clan_lib/nixpkgs
|
|
ln -sf ${nix-select} $out/${pythonRuntime.sitePackages}/clan_lib/select
|
|
installShellCompletion --bash --name clan \
|
|
<(${pythonRuntimeWithDeps.pkgs.argcomplete}/bin/register-python-argcomplete --shell bash clan)
|
|
installShellCompletion --fish --name clan.fish \
|
|
<(${pythonRuntimeWithDeps.pkgs.argcomplete}/bin/register-python-argcomplete --shell fish clan)
|
|
installShellCompletion --zsh --name _clan \
|
|
<(${pythonRuntimeWithDeps.pkgs.argcomplete}/bin/register-python-argcomplete --shell zsh clan)
|
|
'';
|
|
|
|
# Clean up after the package to avoid leaking python packages into a devshell
|
|
# TODO: factor separate cli / API packages
|
|
postFixup = ''
|
|
rm $out/nix-support/propagated-build-inputs
|
|
'';
|
|
|
|
checkPhase = ''
|
|
$out/bin/clan --help
|
|
'';
|
|
|
|
meta.mainProgram = "clan";
|
|
}
|