aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-12 02:33:43 +0000
committertv <tv@krebsco.de>2026-11-12 02:33:43 +0000
commit84444c00bf5ad06f8bca4e4cd68e6d227a8efd1e (patch)
tree35cd74ccd2e96a638491c68d508c8b20055be142
parent1dd511bd6920b428dbd48f36ac646da8463fcbdd (diff)
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.
-rw-r--r--pkgs/populate/default.nix8
-rw-r--r--tests/scenarios.nix16
2 files changed, 23 insertions, 1 deletions
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" {