1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-07 18:31:49 +02:00

Fix deep overrides

An override like

  inputs.foo.inputs.bar.inputs.nixpkgs.follows = "nixpkgs";

implicitly set `inputs.foo.inputs.bar` to `flake:bar`, which led to an
unexpected error like

  error: cannot find flake 'flake:bar' in the flake registries

We now no longer create a parent override (like for `foo.bar` in the
example above) if it doesn't set an explicit ref or follows
attribute. We only recursively apply its child overrides.

Fixes https://github.com/NixOS/nix/issues/8325, https://github.com/DeterminateSystems/nix-src/issues/95, https://github.com/NixOS/nix/issues/12083, https://github.com/NixOS/nix/issues/5790.
This commit is contained in:
Eelco Dolstra 2025-06-12 20:19:19 +02:00
parent df2d5f276a
commit 7c0ea143d8

View file

@ -101,7 +101,6 @@ static void parseFlakeInputAttr(
static FlakeInput parseFlakeInput(
EvalState & state,
std::string_view inputName,
Value * value,
const PosIdx pos,
const InputAttrPath & lockRootAttrPath,
@ -171,9 +170,6 @@ static FlakeInput parseFlakeInput(
input.ref = parseFlakeRef(state.fetchSettings, *url, {}, true, input.isFlake, true);
}
if (!input.follows && !input.ref)
input.ref = FlakeRef::fromAttrs(state.fetchSettings, {{"type", "indirect"}, {"id", std::string(inputName)}});
return input;
}
@ -201,7 +197,6 @@ static std::pair<std::map<FlakeId, FlakeInput>, fetchers::Attrs> parseFlakeInput
} else {
inputs.emplace(inputName,
parseFlakeInput(state,
inputName,
inputAttr.value,
inputAttr.pos,
lockRootAttrPath,
@ -483,18 +478,27 @@ LockedFlake lockFlake(
/* Get the overrides (i.e. attributes of the form
'inputs.nixops.inputs.nixpkgs.url = ...'). */
for (auto & [id, input] : flakeInputs) {
std::function<void(const FlakeInput & input, const InputAttrPath & prefix)> addOverrides;
addOverrides = [&](const FlakeInput & input, const InputAttrPath & prefix)
{
for (auto & [idOverride, inputOverride] : input.overrides) {
auto inputAttrPath(inputAttrPathPrefix);
inputAttrPath.push_back(id);
auto inputAttrPath(prefix);
inputAttrPath.push_back(idOverride);
overrides.emplace(inputAttrPath,
OverrideTarget {
.input = inputOverride,
.sourcePath = sourcePath,
.parentInputAttrPath = inputAttrPathPrefix
});
if (inputOverride.ref || inputOverride.follows)
overrides.emplace(inputAttrPath,
OverrideTarget {
.input = inputOverride,
.sourcePath = sourcePath,
.parentInputAttrPath = inputAttrPathPrefix
});
addOverrides(inputOverride, inputAttrPath);
}
};
for (auto & [id, input] : flakeInputs) {
auto inputAttrPath(inputAttrPathPrefix);
inputAttrPath.push_back(id);
addOverrides(input, inputAttrPath);
}
/* Check whether this input has overrides for a
@ -550,7 +554,8 @@ LockedFlake lockFlake(
continue;
}
assert(input.ref);
if (!input.ref)
input.ref = FlakeRef::fromAttrs(state.fetchSettings, {{"type", "indirect"}, {"id", std::string(id)}});
auto overriddenParentPath =
input.ref->input.isRelative()