From 559fd7ffe7a8cb61b11bec081f14ce3c3ffb210d Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Tue, 27 Jun 2023 14:58:29 +0200 Subject: [PATCH] nix flake check: improve error message if overlay is not a lambda (#8582) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nix flake check: improve error message if overlay is not a lambda Suppose you have an overlay like this { inputs = { /* ... */ }; outputs = { flake-utils, ... }: flake-utils.lib.eachDefaultSystem (system: { overlays.default = final: prev: { }; }); } then `nix flake check` (correctly) fails because `overlays` are supposed to have the structure `overlays. = final: prev: exp`. However, the error-message is a little bit counter-intuitive: error: overlay does not take an argument named 'final' While one might guess where the error actually comes from because the trace above says `… while checking the overlay 'overlays.x86_64-linux'` this is still pretty confusing because it complains about an argument not being named `final` even though that's evidently the case. With this change, the error-message actually makes it clear what's wrong: [ma27@carsten:~/Projects/nix/tmp]$ nix flake check --extra-experimental-features 'nix-command flakes' path:$(pwd) error: … while checking flake output 'overlays' at /nix/store/clgblnxx003hyrq8qkz5ab6kgqkck6qc-source/flake.nix:4:5: 3| outputs = { ... }: { 4| overlays.x86_64-linux.snens = final: prev: { | ^ 5| kek = throw "snens"; … while checking the overlay 'overlays.x86_64-linux' at /nix/store/clgblnxx003hyrq8qkz5ab6kgqkck6qc-source/flake.nix:4:5: 3| outputs = { ... }: { 4| overlays.x86_64-linux.snens = final: prev: { | ^ 5| kek = throw "snens"; error: overlay is not a lambda, but a set instead --- src/nix/flake.cc | 6 ++++-- tests/flakes/check.sh | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 8d39de389..b5f5d0cac 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -386,8 +386,10 @@ struct CmdFlakeCheck : FlakeCommand auto checkOverlay = [&](const std::string & attrPath, Value & v, const PosIdx pos) { try { state->forceValue(v, pos); - if (!v.isLambda() - || v.lambda.fun->hasFormals() + if (!v.isLambda()) { + throw Error("overlay is not a function, but %s instead", showType(v)); + } + if (v.lambda.fun->hasFormals() || !argHasName(v.lambda.fun->arg, "final")) throw Error("overlay does not take an argument named 'final'"); auto body = dynamic_cast(v.lambda.fun->body); diff --git a/tests/flakes/check.sh b/tests/flakes/check.sh index 34b82c61c..0433e5335 100644 --- a/tests/flakes/check.sh +++ b/tests/flakes/check.sh @@ -25,6 +25,18 @@ EOF (! nix flake check $flakeDir) +cat > $flakeDir/flake.nix <&1 && fail "nix flake check --all-systems should have failed" || true) +echo "$checkRes" | grepQuiet "error: overlay is not a function, but a set instead" + cat > $flakeDir/flake.nix <