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:
parent
ff85b347b8
commit
182edb4dee
7 changed files with 48 additions and 60 deletions
|
@ -36,6 +36,7 @@ class Store;
|
||||||
namespace fetchers {
|
namespace fetchers {
|
||||||
struct Settings;
|
struct Settings;
|
||||||
struct InputCache;
|
struct InputCache;
|
||||||
|
struct Input;
|
||||||
}
|
}
|
||||||
struct EvalSettings;
|
struct EvalSettings;
|
||||||
class EvalState;
|
class EvalState;
|
||||||
|
@ -450,6 +451,15 @@ public:
|
||||||
|
|
||||||
void checkURI(const std::string & uri);
|
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.
|
* Parse a Nix expression from the specified file.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -67,4 +67,27 @@ std::string EvalState::computeBaseName(const SourcePath & path)
|
||||||
return std::string(path.baseName());
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,11 +204,7 @@ static void fetchTree(
|
||||||
|
|
||||||
auto cachedInput = state.inputCache->getAccessor(state.store, input, false);
|
auto cachedInput = state.inputCache->getAccessor(state.store, input, false);
|
||||||
|
|
||||||
auto storePath = StorePath::random(input.getName());
|
auto storePath = state.mountInput(cachedInput.lockedInput, input, cachedInput.accessor, true);
|
||||||
|
|
||||||
state.allowPath(storePath);
|
|
||||||
|
|
||||||
state.storeFS->mount(CanonPath(state.store->printStorePath(storePath)), cachedInput.accessor);
|
|
||||||
|
|
||||||
emitTreeAttrs(state, storePath, cachedInput.lockedInput, v, params.emptyRevFallback, false);
|
emitTreeAttrs(state, storePath, cachedInput.lockedInput, v, params.emptyRevFallback, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,33 +26,6 @@ using namespace fetchers;
|
||||||
|
|
||||||
namespace flake {
|
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)
|
static void forceTrivialValue(EvalState & state, Value & value, const PosIdx pos)
|
||||||
{
|
{
|
||||||
if (value.isThunk() && value.isTrivial())
|
if (value.isThunk() && value.isTrivial())
|
||||||
|
@ -350,7 +323,7 @@ static Flake getFlake(
|
||||||
const FlakeRef & originalRef,
|
const FlakeRef & originalRef,
|
||||||
bool useRegistries,
|
bool useRegistries,
|
||||||
const InputAttrPath & lockRootAttrPath,
|
const InputAttrPath & lockRootAttrPath,
|
||||||
CopyMode copyMode)
|
bool requireLockable)
|
||||||
{
|
{
|
||||||
// Fetch a lazy tree first.
|
// Fetch a lazy tree first.
|
||||||
auto cachedInput = state.inputCache->getAccessor(state.store, originalRef.input, useRegistries);
|
auto cachedInput = state.inputCache->getAccessor(state.store, originalRef.input, useRegistries);
|
||||||
|
@ -376,13 +349,13 @@ static Flake getFlake(
|
||||||
// Re-parse flake.nix from the store.
|
// Re-parse flake.nix from the store.
|
||||||
return readFlake(
|
return readFlake(
|
||||||
state, originalRef, resolvedRef, lockedRef,
|
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);
|
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(
|
static LockFile readLockFile(
|
||||||
|
@ -404,7 +377,7 @@ LockedFlake lockFlake(
|
||||||
{
|
{
|
||||||
auto useRegistries = lockFlags.useRegistries.value_or(settings.useRegistries);
|
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) {
|
if (lockFlags.applyNixConfig) {
|
||||||
flake.config.apply(settings);
|
flake.config.apply(settings);
|
||||||
|
@ -449,13 +422,6 @@ LockedFlake lockFlake(
|
||||||
explicitCliOverrides.insert(i.first);
|
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;
|
LockFile newLockFile;
|
||||||
|
|
||||||
std::vector<FlakeRef> parents;
|
std::vector<FlakeRef> parents;
|
||||||
|
@ -586,7 +552,7 @@ LockedFlake lockFlake(
|
||||||
if (auto resolvedPath = resolveRelativePath()) {
|
if (auto resolvedPath = resolveRelativePath()) {
|
||||||
return readFlake(state, ref, ref, ref, *resolvedPath, inputAttrPath);
|
return readFlake(state, ref, ref, ref, *resolvedPath, inputAttrPath);
|
||||||
} else {
|
} 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);
|
auto lockedRef = FlakeRef(std::move(cachedInput.lockedInput), input.ref->subdir);
|
||||||
|
|
||||||
return {
|
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
|
lockedRef
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -851,7 +817,7 @@ LockedFlake lockFlake(
|
||||||
repo, so we should re-read it. FIXME: we could
|
repo, so we should re-read it. FIXME: we could
|
||||||
also just clear the 'rev' field... */
|
also just clear the 'rev' field... */
|
||||||
auto prevLockedRef = flake.lockedRef;
|
auto prevLockedRef = flake.lockedRef;
|
||||||
flake = getFlake(state, topRef, useRegistries, lockFlags.copyMode);
|
flake = getFlake(state, topRef, useRegistries, lockFlags.requireLockable);
|
||||||
|
|
||||||
if (lockFlags.commitLockFile &&
|
if (lockFlags.commitLockFile &&
|
||||||
flake.lockedRef.input.getRev() &&
|
flake.lockedRef.input.getRev() &&
|
||||||
|
|
|
@ -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(
|
Flake getFlake(
|
||||||
EvalState & state,
|
EvalState & state,
|
||||||
const FlakeRef & flakeRef,
|
const FlakeRef & flakeRef,
|
||||||
bool useRegistries,
|
bool useRegistries,
|
||||||
CopyMode copyMode = CopyMode::RequireLockable);
|
bool requireLockable = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fingerprint of a locked flake; used as a cache key.
|
* Fingerprint of a locked flake; used as a cache key.
|
||||||
|
@ -228,7 +221,7 @@ struct LockFlags
|
||||||
/**
|
/**
|
||||||
* Whether to require a locked input.
|
* Whether to require a locked input.
|
||||||
*/
|
*/
|
||||||
CopyMode copyMode = CopyMode::RequireLockable;
|
bool requireLockable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
LockedFlake lockFlake(
|
LockedFlake lockFlake(
|
||||||
|
|
|
@ -134,7 +134,7 @@ public:
|
||||||
lockFlags.recreateLockFile = updateAll;
|
lockFlags.recreateLockFile = updateAll;
|
||||||
lockFlags.writeLockFile = true;
|
lockFlags.writeLockFile = true;
|
||||||
lockFlags.applyNixConfig = true;
|
lockFlags.applyNixConfig = true;
|
||||||
lockFlags.copyMode = CopyMode::Lazy;
|
lockFlags.requireLockable = false;
|
||||||
|
|
||||||
lockFlake();
|
lockFlake();
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ struct CmdFlakeLock : FlakeCommand
|
||||||
lockFlags.writeLockFile = true;
|
lockFlags.writeLockFile = true;
|
||||||
lockFlags.failOnUnlocked = true;
|
lockFlags.failOnUnlocked = true;
|
||||||
lockFlags.applyNixConfig = true;
|
lockFlags.applyNixConfig = true;
|
||||||
lockFlags.copyMode = CopyMode::Lazy;
|
lockFlags.requireLockable = false;
|
||||||
|
|
||||||
lockFlake();
|
lockFlake();
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON
|
||||||
|
|
||||||
void run(nix::ref<nix::Store> store) override
|
void run(nix::ref<nix::Store> store) override
|
||||||
{
|
{
|
||||||
lockFlags.copyMode = CopyMode::Lazy;
|
lockFlags.requireLockable = false;
|
||||||
auto lockedFlake = lockFlake();
|
auto lockedFlake = lockFlake();
|
||||||
auto & flake = lockedFlake.flake;
|
auto & flake = lockedFlake.flake;
|
||||||
|
|
||||||
|
|
|
@ -303,7 +303,7 @@ echo foo > "$empty/x"
|
||||||
|
|
||||||
git -C "$empty" add 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.
|
# Test a repo with an empty commit.
|
||||||
git -C "$empty" rm -f x
|
git -C "$empty" rm -f x
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue