1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-12 20:11:03 +01:00

Merge pull request #14736 from NixOS/builtins-path-references

builtins.path: Propagate references from derivation outputs
This commit is contained in:
Jörg Thalheim 2025-12-08 22:22:24 +00:00 committed by GitHub
commit 8ab5c2bc21
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 56 additions and 11 deletions

View file

@ -2807,11 +2807,18 @@ static void addPath(
const NixStringContext & context)
{
try {
if (path.accessor == state.rootFS && state.store->isInStore(path.path.abs())) {
StorePathSet refs;
if (path.accessor == state.rootFS && state.store->isInStore(path.path.abs()) && !context.empty()) {
// FIXME: handle CA derivation outputs (where path needs to
// be rewritten to the actual output).
auto rewrites = state.realiseContext(context);
path = {path.accessor, CanonPath(rewriteStrings(path.path.abs(), rewrites))};
auto [storePath, subPath] = state.store->toStorePath(path.path.abs());
try {
refs = state.store->queryPathInfo(storePath)->references;
} catch (Error &) { // FIXME: should be InvalidPathError
}
}
std::unique_ptr<PathFilter> filter;
@ -2824,18 +2831,27 @@ static void addPath(
std::optional<StorePath> expectedStorePath;
if (expectedHash)
expectedStorePath = state.store->makeFixedOutputPathFromCA(
name, ContentAddressWithReferences::fromParts(method, *expectedHash, {}));
name, ContentAddressWithReferences::fromParts(method, *expectedHash, {refs}));
if (!expectedHash || !state.store->isValidPath(*expectedStorePath)) {
auto dstPath = fetchToStore(
state.fetchSettings,
*state.store,
path.resolveSymlinks(),
settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy,
name,
method,
filter.get(),
state.repair);
// FIXME: support refs in fetchToStore()?
auto dstPath = refs.empty() ? fetchToStore(
state.fetchSettings,
*state.store,
path.resolveSymlinks(),
settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy,
name,
method,
filter.get(),
state.repair)
: state.store->addToStore(
name,
path.resolveSymlinks(),
method,
HashAlgorithm::SHA256,
refs,
filter ? *filter.get() : defaultPathFilter,
state.repair);
if (expectedHash && expectedStorePath != dstPath)
state.error<EvalError>("store path mismatch in (possibly filtered) path added from '%s'", path)
.atPos(pos)

View file

@ -46,4 +46,24 @@ rec {
};
importAddPathExpr = import addPathExpr;
symlink = mkDerivation {
name = "symlink";
buildCommand = ''
mkdir $out
echo hello world > $out/text
ln -s $out/text $out/symlink
ln -s ${step1} $out/symlink2
'';
};
pathFromDerivation = builtins.path {
name = "path-from-derivation";
path = "${symlink}/";
};
pathFromDerivation2 = builtins.path {
name = "path-from-derivation";
path = "${symlink}/text";
};
}

View file

@ -29,6 +29,15 @@ fi
outPath2=$(nix-build ./import-from-derivation.nix -A addPath --no-out-link)
[[ "$(cat "$outPath2")" = BLAFOO579 ]]
# Test that applying builtins.path to the result of a derivation propagates all references
for attr in pathFromDerivation pathFromDerivation2; do
outPath3=$(nix eval --raw -f ./import-from-derivation.nix "$attr")
refs=$(nix path-info --json "$outPath3" | jq -r '.[].references.[]')
[[ $(printf "%s" "$refs" | wc -w) = 2 ]]
[[ $refs =~ -step1 ]]
[[ $refs =~ -symlink ]]
done
# Test that IFD works with a chroot store.
if canUseSandbox; then