diff options
author | Maximilian Bosch <maximilian@mbosch.me> | 2022-06-13 20:39:09 +0200 |
---|---|---|
committer | Maximilian Bosch <maximilian@mbosch.me> | 2022-07-12 10:18:38 +0200 |
commit | c1c37f32002e2e2ad167bcac2e5d76a3a3ad6a35 (patch) | |
tree | 56308eb385627248159035f5092ab6713372362d /src | |
parent | f071eb3702c7aa86fc1885321d73a3707ed702b6 (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.cc | 23 |
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) { |