mirror of
https://github.com/NixOS/nix
synced 2025-07-07 01:51:47 +02:00
Devirtualize double-copied paths
Borrowed from the original lazy-trees branch.
This commit is contained in:
parent
e099a5bc67
commit
0c0dda3b29
4 changed files with 33 additions and 2 deletions
|
@ -2317,6 +2317,9 @@ BackedStringView EvalState::coerceToString(
|
|||
}
|
||||
|
||||
if (v.type() == nPath) {
|
||||
// FIXME: instead of copying the path to the store, we could
|
||||
// return a virtual store path that lazily copies the path to
|
||||
// the store in devirtualize().
|
||||
return
|
||||
!canonicalizePath && !copyToStore
|
||||
? // FIXME: hack to preserve path literals that end in a
|
||||
|
@ -2406,7 +2409,7 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat
|
|||
*store,
|
||||
path.resolveSymlinks(SymlinkResolution::Ancestors),
|
||||
settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy,
|
||||
path.baseName(),
|
||||
computeBaseName(path),
|
||||
ContentAddressMethod::Raw::NixArchive,
|
||||
nullptr,
|
||||
repair);
|
||||
|
|
|
@ -586,6 +586,19 @@ public:
|
|||
|
||||
StorePath copyPathToStore(NixStringContext & context, const SourcePath & path);
|
||||
|
||||
|
||||
/**
|
||||
* Compute the base name for a `SourcePath`. For non-store paths,
|
||||
* this is just `SourcePath::baseName()`. But for store paths, for
|
||||
* backwards compatibility, it needs to be `<hash>-source`,
|
||||
* i.e. as if the path were copied to the Nix store. This results
|
||||
* in a "double-copied" store path like
|
||||
* `/nix/store/<hash1>-<hash2>-source`. We don't need to
|
||||
* materialize /nix/store/<hash2>-source though. Still, this
|
||||
* requires reading/hashing the path twice.
|
||||
*/
|
||||
std::string computeBaseName(const SourcePath & path);
|
||||
|
||||
/**
|
||||
* Path coercion.
|
||||
*
|
||||
|
|
|
@ -52,4 +52,19 @@ std::string EvalState::devirtualize(std::string_view s, const NixStringContext &
|
|||
return rewriteStrings(std::string(s), rewrites);
|
||||
}
|
||||
|
||||
std::string EvalState::computeBaseName(const SourcePath & path)
|
||||
{
|
||||
if (path.accessor == rootFS) {
|
||||
if (auto storePath = store->maybeParseStorePath(path.path.abs())) {
|
||||
warn(
|
||||
"Performing inefficient double copy of path '%s' to the store. "
|
||||
"This can typically be avoided by rewriting an attribute like `src = ./.` "
|
||||
"to `src = builtins.path { path = ./.; name = \"source\"; }`.",
|
||||
path);
|
||||
return std::string(fetchToStore(*store, path, FetchMode::DryRun).to_string());
|
||||
}
|
||||
}
|
||||
return std::string(path.baseName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2539,7 +2539,7 @@ static void prim_filterSource(EvalState & state, const PosIdx pos, Value * * arg
|
|||
"while evaluating the second argument (the path to filter) passed to 'builtins.filterSource'");
|
||||
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.filterSource");
|
||||
|
||||
addPath(state, pos, path.baseName(), path, args[0], ContentAddressMethod::Raw::NixArchive, std::nullopt, v, context);
|
||||
addPath(state, pos, state.computeBaseName(path), path, args[0], ContentAddressMethod::Raw::NixArchive, std::nullopt, v, context);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_filterSource({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue