aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/flake/flake.cc17
-rw-r--r--tests/functional/flakes/follow-paths.sh55
2 files changed, 70 insertions, 2 deletions
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<InputPath, FlakeInput> & 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 <<EOF > $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 <<EOF > $flakeFollowsA/flake.nix
+{
+ inputs = {
+ B.url = "path:$flakeFollowsB";
+ C = {
+ url = "path:$flakeFollowsC";
+ inputs.D.inputs.E.follows = "B";
+ };
+ };
+ outputs = _: {};
+}
+EOF
+
+cat <<EOF > $flakeFollowsB/flake.nix
+{
+ outputs = _: {};
+}
+EOF
+
+cat <<EOF > $flakeFollowsC/flake.nix
+{
+ inputs = {
+ D.url = "path:$flakeFollowsD";
+ };
+ outputs = _: {};
+}
+EOF
+
+cat <<EOF > $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" ]]