aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaximilian Bosch <maximilian@mbosch.me>2022-06-13 20:39:09 +0200
committerMaximilian Bosch <maximilian@mbosch.me>2022-07-12 10:18:38 +0200
commitc1c37f32002e2e2ad167bcac2e5d76a3a3ad6a35 (patch)
tree56308eb385627248159035f5092ab6713372362d /src
parentf071eb3702c7aa86fc1885321d73a3707ed702b6 (diff)
flakes: throw an error if `follows`-declaration for an input is invalid
I recently got fairly confused why the following expression didn't have any effect { description = "Foobar"; inputs.sops-nix = { url = github:mic92/sops-nix; inputs.nixpkgs_22_05.follows = "nixpkgs"; }; } until I found out that the input was called `nixpkgs-22_05` (please note the dash vs. underscore). IMHO it's not a good idea to not throw an error in that case and probably leave end-users rather confused, so I implemented a small check for that which basically checks whether `follows`-declaration from overrides actually have corresponding inputs in the transitive flake. In fact this was done by accident already in our own test-suite where the removal of a `follows` was apparently forgotten[1]. Since the key of the `std::map` that holds the `overrides` is a vector and we have to find the last element of each vector (i.e. the override) this has to be done with a for loop in O(n) complexity with `n` being the total amount of overrides (which shouldn't be that large though). Please note that this doesn't work with nested expressions, i.e. inputs.fenix.inputs.nixpkgs.follows = "..."; which is a known problem[2]. For the expression demonstrated above, an error like this will be thrown: error: sops-nix has a `follows'-declaration for a non-existant input nixpkgs_22_05! [1] 2664a216e57169ec57d7f51be1b8383c1be83fd5 [2] https://github.com/NixOS/nix/issues/5790
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/flake/flake.cc23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index 920726b73..b97780a9c 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -373,6 +373,29 @@ LockedFlake lockFlake(
{
debug("computing lock file node '%s'", printInputPath(inputPathPrefix));
+ auto overrides2 = overrides;
+ for (auto & [inputPath, inputOverride] : overrides2) {
+ auto inputPath2(inputPath);
+ auto follow = inputPath2.back();
+ inputPath2.pop_back();
+ if (inputPath2 == inputPathPrefix
+ && flakeInputs.find(follow) == flakeInputs.end()
+ ) {
+ std::string root;
+ for (auto & element : inputPath2) {
+ root.append(element);
+ if (element != inputPath2.back()) {
+ root.append(".inputs.");
+ }
+ }
+ throw Error(
+ "%s has a `follows'-declaration for a non-existant input %s!",
+ root,
+ follow
+ );
+ }
+ }
+
/* Get the overrides (i.e. attributes of the form
'inputs.nixops.inputs.nixpkgs.url = ...'). */
for (auto & [id, input] : flakeInputs) {