1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-28 01:11:15 +02:00

Move mountInput into EvalState

This commit is contained in:
Eelco Dolstra 2025-04-23 13:52:22 +02:00
parent ff85b347b8
commit 182edb4dee
7 changed files with 48 additions and 60 deletions

View file

@ -36,6 +36,7 @@ class Store;
namespace fetchers {
struct Settings;
struct InputCache;
struct Input;
}
struct EvalSettings;
class EvalState;
@ -450,6 +451,15 @@ public:
void checkURI(const std::string & uri);
/**
* Mount an input on the Nix store.
*/
StorePath mountInput(
fetchers::Input & input,
const fetchers::Input & originalInput,
ref<SourceAccessor> accessor,
bool requireLockable);
/**
* Parse a Nix expression from the specified file.
*/

View file

@ -67,4 +67,27 @@ std::string EvalState::computeBaseName(const SourcePath & path)
return std::string(path.baseName());
}
StorePath EvalState::mountInput(
fetchers::Input & input, const fetchers::Input & originalInput, ref<SourceAccessor> accessor, bool requireLockable)
{
auto storePath = StorePath::random(input.getName());
allowPath(storePath); // FIXME: should just whitelist the entire virtual store
storeFS->mount(CanonPath(store->printStorePath(storePath)), accessor);
if (requireLockable && !input.isLocked() && !input.getNarHash()) {
auto narHash = accessor->hashPath(CanonPath::root);
input.attrs.insert_or_assign("narHash", narHash.to_string(HashFormat::SRI, true));
}
// FIXME: check NAR hash
#if 0
assert(!originalInput.getNarHash() || storePath == originalInput.computeStorePath(*store));
#endif
return storePath;
}
}

View file

@ -204,11 +204,7 @@ static void fetchTree(
auto cachedInput = state.inputCache->getAccessor(state.store, input, false);
auto storePath = StorePath::random(input.getName());
state.allowPath(storePath);
state.storeFS->mount(CanonPath(state.store->printStorePath(storePath)), cachedInput.accessor);
auto storePath = state.mountInput(cachedInput.lockedInput, input, cachedInput.accessor, true);
emitTreeAttrs(state, storePath, cachedInput.lockedInput, v, params.emptyRevFallback, false);
}

View file

@ -26,33 +26,6 @@ using namespace fetchers;
namespace flake {
static StorePath mountInput(
EvalState & state,
fetchers::Input & input,
const fetchers::Input & originalInput,
ref<SourceAccessor> accessor,
CopyMode copyMode)
{
auto storePath = StorePath::random(input.getName());
state.allowPath(storePath); // FIXME: should just whitelist the entire virtual store
state.storeFS->mount(CanonPath(state.store->printStorePath(storePath)), accessor);
if (copyMode == CopyMode::RequireLockable && !input.isLocked() && !input.getNarHash()) {
auto narHash = accessor->hashPath(CanonPath::root);
input.attrs.insert_or_assign("narHash", narHash.to_string(HashFormat::SRI, true));
}
// FIXME: check NAR hash
#if 0
assert(!originalInput.getNarHash() || storePath == originalInput.computeStorePath(*state.store));
#endif
return storePath;
}
static void forceTrivialValue(EvalState & state, Value & value, const PosIdx pos)
{
if (value.isThunk() && value.isTrivial())
@ -350,7 +323,7 @@ static Flake getFlake(
const FlakeRef & originalRef,
bool useRegistries,
const InputAttrPath & lockRootAttrPath,
CopyMode copyMode)
bool requireLockable)
{
// Fetch a lazy tree first.
auto cachedInput = state.inputCache->getAccessor(state.store, originalRef.input, useRegistries);
@ -376,13 +349,13 @@ static Flake getFlake(
// Re-parse flake.nix from the store.
return readFlake(
state, originalRef, resolvedRef, lockedRef,
state.storePath(mountInput(state, lockedRef.input, originalRef.input, cachedInput.accessor, copyMode)),
state.storePath(state.mountInput(lockedRef.input, originalRef.input, cachedInput.accessor, requireLockable)),
lockRootAttrPath);
}
Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool useRegistries, CopyMode copyMode)
Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool useRegistries, bool requireLockable)
{
return getFlake(state, originalRef, useRegistries, {}, copyMode);
return getFlake(state, originalRef, useRegistries, {}, requireLockable);
}
static LockFile readLockFile(
@ -404,7 +377,7 @@ LockedFlake lockFlake(
{
auto useRegistries = lockFlags.useRegistries.value_or(settings.useRegistries);
auto flake = getFlake(state, topRef, useRegistries, {}, lockFlags.copyMode);
auto flake = getFlake(state, topRef, useRegistries, {}, lockFlags.requireLockable);
if (lockFlags.applyNixConfig) {
flake.config.apply(settings);
@ -449,13 +422,6 @@ LockedFlake lockFlake(
explicitCliOverrides.insert(i.first);
}
/* For locking of inputs, we require at least a NAR
hash. I.e. we can't be fully lazy. */
auto inputCopyMode =
lockFlags.copyMode == CopyMode::Lazy
? CopyMode::RequireLockable
: lockFlags.copyMode;
LockFile newLockFile;
std::vector<FlakeRef> parents;
@ -586,7 +552,7 @@ LockedFlake lockFlake(
if (auto resolvedPath = resolveRelativePath()) {
return readFlake(state, ref, ref, ref, *resolvedPath, inputAttrPath);
} else {
return getFlake(state, ref, useRegistries, inputAttrPath, inputCopyMode);
return getFlake(state, ref, useRegistries, inputAttrPath, true);
}
};
@ -739,7 +705,7 @@ LockedFlake lockFlake(
auto lockedRef = FlakeRef(std::move(cachedInput.lockedInput), input.ref->subdir);
return {
state.storePath(mountInput(state, lockedRef.input, input.ref->input, cachedInput.accessor, inputCopyMode)),
state.storePath(state.mountInput(lockedRef.input, input.ref->input, cachedInput.accessor, true)),
lockedRef
};
}
@ -851,7 +817,7 @@ LockedFlake lockFlake(
repo, so we should re-read it. FIXME: we could
also just clear the 'rev' field... */
auto prevLockedRef = flake.lockedRef;
flake = getFlake(state, topRef, useRegistries, lockFlags.copyMode);
flake = getFlake(state, topRef, useRegistries, lockFlags.requireLockable);
if (lockFlags.commitLockFile &&
flake.lockedRef.input.getRev() &&

View file

@ -115,18 +115,11 @@ struct Flake
}
};
enum struct CopyMode {
//! Ensure that the input is locked or has a NAR hash.
RequireLockable,
//! Just return a lazy source accessor.
Lazy,
};
Flake getFlake(
EvalState & state,
const FlakeRef & flakeRef,
bool useRegistries,
CopyMode copyMode = CopyMode::RequireLockable);
bool requireLockable = true);
/**
* Fingerprint of a locked flake; used as a cache key.
@ -228,7 +221,7 @@ struct LockFlags
/**
* Whether to require a locked input.
*/
CopyMode copyMode = CopyMode::RequireLockable;
bool requireLockable = true;
};
LockedFlake lockFlake(

View file

@ -134,7 +134,7 @@ public:
lockFlags.recreateLockFile = updateAll;
lockFlags.writeLockFile = true;
lockFlags.applyNixConfig = true;
lockFlags.copyMode = CopyMode::Lazy;
lockFlags.requireLockable = false;
lockFlake();
}
@ -167,7 +167,7 @@ struct CmdFlakeLock : FlakeCommand
lockFlags.writeLockFile = true;
lockFlags.failOnUnlocked = true;
lockFlags.applyNixConfig = true;
lockFlags.copyMode = CopyMode::Lazy;
lockFlags.requireLockable = false;
lockFlake();
}
@ -214,7 +214,7 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON
void run(nix::ref<nix::Store> store) override
{
lockFlags.copyMode = CopyMode::Lazy;
lockFlags.requireLockable = false;
auto lockedFlake = lockFlake();
auto & flake = lockedFlake.flake;

View file

@ -303,7 +303,7 @@ echo foo > "$empty/x"
git -C "$empty" add x
[[ $(nix eval --impure --expr "builtins.removeAttrs (builtins.fetchGit $empty) [\"outPath\"]") = '{ lastModified = 0; lastModifiedDate = "19700101000000"; rev = "0000000000000000000000000000000000000000"; revCount = 0; shortRev = "0000000"; submodules = false; }' ]]
[[ $(nix eval --impure --expr "builtins.removeAttrs (builtins.fetchGit $empty) [\"outPath\"]") = '{ lastModified = 0; lastModifiedDate = "19700101000000"; narHash = "sha256-wzlAGjxKxpaWdqVhlq55q5Gxo4Bf860+kLeEa/v02As="; rev = "0000000000000000000000000000000000000000"; revCount = 0; shortRev = "0000000"; submodules = false; }' ]]
# Test a repo with an empty commit.
git -C "$empty" rm -f x