diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index 7f0e5b1e9..ab13ba3be 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -342,8 +342,21 @@ static void updateOverrides(std::map & overrideMap, const for (auto & [id, input] : overrides) { auto inputPath(inputPathPrefix); inputPath.push_back(id); - // Do not override existing assignment from outer flake - overrideMap.insert({inputPath, input}); + + /* Given + * + * { inputs.hydra.inputs.nix-eval-jobs.inputs.lix.follows = "lix"; } + * + * then `nix-eval-jobs` doesn't have an override. + * It's neither replaced using follows nor by a different + * URL. Thus no need to add it to overrides and thus re-fetch + * it. + */ + if (input.ref || input.follows) { + // Do not override existing assignment from outer flake + overrideMap.insert({inputPath, input}); + } + updateOverrides(overrideMap, input.overrides, inputPath); } } diff --git a/tests/functional/flakes/follow-paths.sh b/tests/functional/flakes/follow-paths.sh index e91ce87b1..1f824793b 100644 --- a/tests/functional/flakes/follow-paths.sh +++ b/tests/functional/flakes/follow-paths.sh @@ -307,3 +307,58 @@ cat < $flakeFollowsB/flake.nix EOF nix flake update --flake $flakeFollowsA 2>&1 | grepQuiet "warning: input 'B/C' has an override for a non-existent input 'E'" + +# Test for Nested follows cause flake interactions to update the nested input #460 +for letter in {A..E}; do + path="flakeFollows${letter}" + rm -f "${!path}"/flake.lock +done + +cat < $flakeFollowsA/flake.nix +{ + inputs = { + B.url = "path:$flakeFollowsB"; + C = { + url = "path:$flakeFollowsC"; + inputs.D.inputs.E.follows = "B"; + }; + }; + outputs = _: {}; +} +EOF + +cat < $flakeFollowsB/flake.nix +{ + outputs = _: {}; +} +EOF + +cat < $flakeFollowsC/flake.nix +{ + inputs = { + D.url = "path:$flakeFollowsD"; + }; + outputs = _: {}; +} +EOF + +cat < $flakeFollowsD/flake.nix +{ + inputs = { + E.url = "path:$flakeFollowsE"; + }; + outputs = _: {}; +} +EOF + +# Lockfiles are cleared, initially the dependency needs to be fetched. +out="$(nix --verbose flake show path:$flakeFollowsA 2>&1)" +echo "$out" +[[ "$out" = *$'\n'"fetching path input 'path:"*"/flakeD'"$'\n'* ]] + +# But on another flake command it doesn't. +out="$(nix --verbose flake show path:$flakeFollowsA 2>&1)" +[[ "$out" != *$'\n'"fetching path input 'path:"*"/flakeD'"$'\n'* ]] + +# Make sure the nested override is actually correct in this testcase. +[[ "$(nix flake metadata path:$flakeFollowsA --json | jq '.locks.nodes.D.inputs.E|.[]' -r)" = "B" ]]