diff --git a/dev/flake-module.nix b/dev/flake-module.nix index 84033a4..a2b15c4 100644 --- a/dev/flake-module.nix +++ b/dev/flake-module.nix @@ -42,6 +42,10 @@ let tests = import ./tests/eval-tests.nix { flake-parts = self; }; in tests.runTests pkgs.emptyFile // { internals = tests; }; + checks.perSystem-memoize = pkgs.callPackage ./tests/perSystem-memoize.nix { + flake-parts = self; + }; + nix-unit.tests = import ./tests/nix-unit.nix { flake-parts = self; }; # nix-unit evaluates the flake, which triggers the dev partition via diff --git a/dev/tests/perSystem-memoize.nix b/dev/tests/perSystem-memoize.nix new file mode 100644 index 0000000..ec89e3a --- /dev/null +++ b/dev/tests/perSystem-memoize.nix @@ -0,0 +1,32 @@ +# Test that perSystem evaluation is memoized: calling withSystem twice for the +# same undeclared system should only evaluate perSystem once. +# Run with: +# nix build .#checks.x86_64-linux.perSystem-memoize + +{ flake-parts, runCommand, nix }: +runCommand "perSystem-memoize" { nativeBuildInputs = [ nix ]; } '' + export HOME="$(realpath .)" + unset NIX_STORE + export NIX_STORE_DIR=${builtins.storeDir} + export NIX_REMOTE="$HOME/storedata" + + nix eval \ + --extra-experimental-features 'nix-command flakes' \ + --no-write-lock-file \ + --offline \ + --substituters "" \ + --override-input flake-parts ${flake-parts} \ + --override-input flake-parts/nixpkgs-lib ${flake-parts.inputs.nixpkgs-lib} \ + "${./perSystem-memoize}#result" \ + 2>eval-stderr + + count=$(grep -c "Evaluating perSystem for foo" eval-stderr || true) + cat eval-stderr >&2 + echo "Trace count: $count" + if [ "$count" -ne 1 ]; then + echo "FAIL: expected perSystem to be evaluated exactly once, but it was evaluated $count times" + exit 1 + fi + echo "PASS: perSystem evaluated exactly once" + touch $out +'' diff --git a/dev/tests/perSystem-memoize/flake.nix b/dev/tests/perSystem-memoize/flake.nix new file mode 100644 index 0000000..78b6a33 --- /dev/null +++ b/dev/tests/perSystem-memoize/flake.nix @@ -0,0 +1,15 @@ +{ + inputs.flake-parts.url = "github:hercules-ci/flake-parts"; + outputs = inputs: + inputs.flake-parts.lib.mkFlake { inherit inputs; } ({ withSystem, ... }: { + systems = [ ]; + perSystem = { system, ... }: + builtins.trace "Evaluating perSystem for ${system}" { }; + flake.result = + let + a = withSystem "foo" ({ config, ... }: null); + b = withSystem "foo" ({ config, ... }: "ok"); + in + builtins.seq a b; + }); +}