From 84444c00bf5ad06f8bca4e4cd68e6d227a8efd1e Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 12 Nov 2026 02:33:43 +0000 Subject: populate flake-input: replace symlinks pointing outside the store nix-store --add-root only replaces symlinks pointing into the store, so a symlink pointing elsewhere at the target path, e.g. one a symlink source left there, made delivering a flake fail. Populate removes such links. An edge case switches a symlink source to a flake source. --- pkgs/populate/default.nix | 8 +++++++- tests/scenarios.nix | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pkgs/populate/default.nix b/pkgs/populate/default.nix index 66c88c1..75fbf61 100644 --- a/pkgs/populate/default.nix +++ b/pkgs/populate/default.nix @@ -395,7 +395,13 @@ let set -efu read -r dir read -r path - if test -e ${quote target.path} && ! test -L ${quote target.path}; then + # nix-store --add-root only replaces links into the store. + if test -L ${quote target.path}; then + case $(readlink ${quote target.path}) in + /nix/store/*) ;; + *) rm ${quote target.path} ;; + esac + elif test -e ${quote target.path}; then rm -fR ${quote target.path} fi nix-store --realise "$path" --add-root ${quote target.path} --indirect >/dev/null diff --git a/tests/scenarios.nix b/tests/scenarios.nix index 38f8736..9760e54 100644 --- a/tests/scenarios.nix +++ b/tests/scenarios.nix @@ -827,6 +827,22 @@ assert !(krops.isLocalTarget (targets.remote "/")); } ]; }) + (s "symlink-to-flake" { + phases = [ + { + sources = alt // { x.symlink = "alt"; }; + check = '' + expect_eq link "$(readlink "$T"/x)" alt + ''; + } + { + sources = alt // { x.flake = { flake = "/fixtures/top"; inherit fetchOnTarget; }; }; + check = checkFlake { attr = "msg"; expected = "top:dep+inner,sub"; } + '' + test -e "$T"/alt/flake.nix || fail "alt changed" + ''; + } + ]; + }) ] ++ lib.optional (targetKind == "local") # The target has the path the input is locked to. (s "uselocal" { -- cgit v1.3.1