1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-18 08:19:35 +01:00

Merge remote-tracking branch 'origin/master' into relative-flakes

This commit is contained in:
Eelco Dolstra 2024-12-18 21:09:27 +01:00
commit 8534c4222c
263 changed files with 2129 additions and 805 deletions

View file

@ -21,23 +21,23 @@ using namespace flake;
namespace flake {
typedef std::pair<StorePath, FlakeRef> FetchedFlake;
typedef std::vector<std::pair<FlakeRef, FetchedFlake>> FlakeCache;
struct FetchedFlake
{
FlakeRef lockedRef;
StorePath storePath;
};
typedef std::map<FlakeRef, FetchedFlake> FlakeCache;
static std::optional<FetchedFlake> lookupInFlakeCache(
const FlakeCache & flakeCache,
const FlakeRef & flakeRef)
{
// FIXME: inefficient.
for (auto & i : flakeCache) {
if (flakeRef == i.first) {
debug("mapping '%s' to previously seen input '%s' -> '%s",
flakeRef, i.first, i.second.second);
return i.second;
}
}
return std::nullopt;
auto i = flakeCache.find(flakeRef);
if (i == flakeCache.end()) return std::nullopt;
debug("mapping '%s' to previously seen input '%s' -> '%s",
flakeRef, i->first, i->second.lockedRef);
return i->second;
}
static std::tuple<StorePath, FlakeRef, FlakeRef> fetchOrSubstituteTree(
@ -51,32 +51,39 @@ static std::tuple<StorePath, FlakeRef, FlakeRef> fetchOrSubstituteTree(
if (!fetched) {
if (originalRef.input.isDirect()) {
fetched.emplace(originalRef.fetchTree(state.store));
auto [storePath, lockedRef] = originalRef.fetchTree(state.store);
fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .storePath = storePath});
} else {
if (allowLookup) {
resolvedRef = originalRef.resolve(state.store);
auto fetchedResolved = lookupInFlakeCache(flakeCache, originalRef);
if (!fetchedResolved) fetchedResolved.emplace(resolvedRef.fetchTree(state.store));
flakeCache.push_back({resolvedRef, *fetchedResolved});
fetched.emplace(*fetchedResolved);
resolvedRef = originalRef.resolve(
state.store,
[](fetchers::Registry::RegistryType type) {
/* Only use the global registry and CLI flags
to resolve indirect flakerefs. */
return type == fetchers::Registry::Flag || type == fetchers::Registry::Global;
});
fetched = lookupInFlakeCache(flakeCache, originalRef);
if (!fetched) {
auto [storePath, lockedRef] = resolvedRef.fetchTree(state.store);
fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .storePath = storePath});
}
flakeCache.insert_or_assign(resolvedRef, *fetched);
}
else {
throw Error("'%s' is an indirect flake reference, but registry lookups are not allowed", originalRef);
}
}
flakeCache.push_back({originalRef, *fetched});
flakeCache.insert_or_assign(originalRef, *fetched);
}
auto [storePath, lockedRef] = *fetched;
debug("got tree '%s' from '%s'",
state.store->printStorePath(storePath), lockedRef);
state.store->printStorePath(fetched->storePath), fetched->lockedRef);
state.allowPath(storePath);
state.allowPath(fetched->storePath);
assert(!originalRef.input.getNarHash() || storePath == originalRef.input.computeStorePath(*state.store));
assert(!originalRef.input.getNarHash() || fetched->storePath == originalRef.input.computeStorePath(*state.store));
return {std::move(storePath), resolvedRef, lockedRef};
return {fetched->storePath, resolvedRef, fetched->lockedRef};
}
static void forceTrivialValue(EvalState & state, Value & value, const PosIdx pos)
@ -752,6 +759,8 @@ LockedFlake lockFlake(
if (lockFlags.writeLockFile) {
if (sourcePath || lockFlags.outputLockFilePath) {
if (auto unlockedInput = newLockFile.isUnlocked()) {
if (lockFlags.failOnUnlocked)
throw Error("cannot write lock file of flake '%s' because it has an unlocked input ('%s').\n", topRef, *unlockedInput);
if (state.fetchSettings.warnDirty)
warn("will not write lock file of flake '%s' because it has an unlocked input ('%s')", topRef, *unlockedInput);
} else {