Skip to content

Commit 1ab97a7

Browse files
committed
fetchOrSubstituteTree(): Return an accessor
This prepares lazy access to flake.nix etc.
1 parent 3c10909 commit 1ab97a7

File tree

4 files changed

+54
-19
lines changed

4 files changed

+54
-19
lines changed

src/libfetchers/fetchers.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,6 @@ std::pair<StorePath, Input> Input::fetchToStore(ref<Store> store) const
200200
auto narHash = store->queryPathInfo(storePath)->narHash;
201201
result.attrs.insert_or_assign("narHash", narHash.to_string(HashFormat::SRI, true));
202202

203-
// FIXME: we would like to mark inputs as final in
204-
// getAccessorUnchecked(), but then we can't add
205-
// narHash. Or maybe narHash should be excluded from the
206-
// concept of "final" inputs?
207203
result.attrs.insert_or_assign("__final", Explicit<bool>(true));
208204

209205
assert(result.isFinal());
@@ -284,6 +280,8 @@ std::pair<ref<SourceAccessor>, Input> Input::getAccessor(ref<Store> store) const
284280
try {
285281
auto [accessor, result] = getAccessorUnchecked(store);
286282

283+
result.attrs.insert_or_assign("__final", Explicit<bool>(true));
284+
287285
checkLocks(*this, result);
288286

289287
return {accessor, std::move(result)};

src/libflake/flake/flake.cc

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "flake/settings.hh"
1313
#include "value-to-json.hh"
1414
#include "local-fs-store.hh"
15+
#include "fetch-to-store.hh"
1516

1617
#include <nlohmann/json.hpp>
1718

@@ -24,7 +25,7 @@ namespace flake {
2425
struct FetchedFlake
2526
{
2627
FlakeRef lockedRef;
27-
StorePath storePath;
28+
ref<SourceAccessor> accessor;
2829
};
2930

3031
typedef std::map<FlakeRef, FetchedFlake> FlakeCache;
@@ -40,7 +41,7 @@ static std::optional<FetchedFlake> lookupInFlakeCache(
4041
return i->second;
4142
}
4243

43-
static std::tuple<StorePath, FlakeRef, FlakeRef> fetchOrSubstituteTree(
44+
static std::tuple<ref<SourceAccessor>, FlakeRef, FlakeRef> fetchOrSubstituteTree(
4445
EvalState & state,
4546
const FlakeRef & originalRef,
4647
bool useRegistries,
@@ -51,8 +52,8 @@ static std::tuple<StorePath, FlakeRef, FlakeRef> fetchOrSubstituteTree(
5152

5253
if (!fetched) {
5354
if (originalRef.input.isDirect()) {
54-
auto [storePath, lockedRef] = originalRef.fetchTree(state.store);
55-
fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .storePath = storePath});
55+
auto [accessor, lockedRef] = originalRef.lazyFetch(state.store);
56+
fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .accessor = accessor});
5657
} else {
5758
if (useRegistries) {
5859
resolvedRef = originalRef.resolve(
@@ -64,8 +65,8 @@ static std::tuple<StorePath, FlakeRef, FlakeRef> fetchOrSubstituteTree(
6465
});
6566
fetched = lookupInFlakeCache(flakeCache, originalRef);
6667
if (!fetched) {
67-
auto [storePath, lockedRef] = resolvedRef.fetchTree(state.store);
68-
fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .storePath = storePath});
68+
auto [accessor, lockedRef] = resolvedRef.lazyFetch(state.store);
69+
fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .accessor = accessor});
6970
}
7071
flakeCache.insert_or_assign(resolvedRef, *fetched);
7172
}
@@ -76,14 +77,28 @@ static std::tuple<StorePath, FlakeRef, FlakeRef> fetchOrSubstituteTree(
7677
flakeCache.insert_or_assign(originalRef, *fetched);
7778
}
7879

79-
debug("got tree '%s' from '%s'",
80-
state.store->printStorePath(fetched->storePath), fetched->lockedRef);
80+
debug("got tree '%s' from '%s'", fetched->accessor, fetched->lockedRef);
8181

82-
state.allowPath(fetched->storePath);
82+
return {fetched->accessor, resolvedRef, fetched->lockedRef};
83+
}
84+
85+
static StorePath copyInputToStore(
86+
EvalState & state,
87+
fetchers::Input & input,
88+
ref<SourceAccessor> accessor)
89+
{
90+
auto storePath = fetchToStore(*state.store, accessor, FetchMode::Copy, input.getName());
91+
92+
state.allowPath(storePath);
8393

94+
auto narHash = state.store->queryPathInfo(storePath)->narHash;
95+
input.attrs.insert_or_assign("narHash", narHash.to_string(HashFormat::SRI, true));
96+
97+
#if 0
8498
assert(!originalRef.input.getNarHash() || fetched->storePath == originalRef.input.computeStorePath(*state.store));
99+
#endif
85100

86-
return {fetched->storePath, resolvedRef, fetched->lockedRef};
101+
return storePath;
87102
}
88103

89104
static void forceTrivialValue(EvalState & state, Value & value, const PosIdx pos)
@@ -136,7 +151,9 @@ static FlakeInput parseFlakeInput(
136151
url = attr.value->string_view();
137152
else if (attr.value->type() == nPath) {
138153
auto path = attr.value->path();
139-
if (path.accessor != flakeDir.accessor)
154+
if (path.accessor != flakeDir.accessor
155+
// FIXME: hack necessary since the parser currently stores all paths as inside rootFS.
156+
&& flakeDir.accessor == state.rootFS)
140157
throw Error("input attribute path '%s' at %s must be in the same source tree as %s",
141158
path, state.positions[attr.pos], flakeDir);
142159
url = "path:" + flakeDir.path.makeRelative(path.path);
@@ -301,10 +318,12 @@ static Flake readFlake(
301318
state.symbols[setting.name],
302319
std::string(state.forceStringNoCtx(*setting.value, setting.pos, "")));
303320
else if (setting.value->type() == nPath) {
304-
NixStringContext emptyContext = {};
321+
// FIXME: hack necessary since the parser currently stores all paths as inside rootFS.
322+
SourcePath path(rootDir.accessor, setting.value->path().path);
323+
auto storePath = fetchToStore(*state.store, path, FetchMode::Copy);
305324
flake.config.settings.emplace(
306325
state.symbols[setting.name],
307-
state.coerceToString(setting.pos, *setting.value, emptyContext, "", false, true, true).toOwned());
326+
state.store->toRealPath(storePath));
308327
}
309328
else if (setting.value->type() == nInt)
310329
flake.config.settings.emplace(
@@ -349,9 +368,14 @@ static Flake getFlake(
349368
FlakeCache & flakeCache,
350369
const InputAttrPath & lockRootAttrPath)
351370
{
352-
auto [storePath, resolvedRef, lockedRef] = fetchOrSubstituteTree(
371+
// Fetch a lazy tree first.
372+
auto [accessor, resolvedRef, lockedRef] = fetchOrSubstituteTree(
353373
state, originalRef, useRegistries, flakeCache);
354374

375+
// Copy the tree to the store.
376+
auto storePath = copyInputToStore(state, lockedRef.input, accessor);
377+
378+
// Re-parse flake.nix from the store.
355379
return readFlake(state, originalRef, resolvedRef, lockedRef, state.rootPath(state.store->toRealPath(storePath)), lockRootAttrPath);
356380
}
357381

@@ -707,8 +731,12 @@ LockedFlake lockFlake(
707731
if (auto resolvedPath = resolveRelativePath()) {
708732
return {*resolvedPath, *input.ref};
709733
} else {
710-
auto [storePath, resolvedRef, lockedRef] = fetchOrSubstituteTree(
734+
auto [accessor, resolvedRef, lockedRef] = fetchOrSubstituteTree(
711735
state, *input.ref, useRegistries, flakeCache);
736+
737+
// FIXME: allow input to be lazy.
738+
auto storePath = copyInputToStore(state, lockedRef.input, accessor);
739+
712740
return {state.rootPath(state.store->toRealPath(storePath)), lockedRef};
713741
}
714742
}();

src/libflake/flake/flakeref.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,12 @@ std::pair<StorePath, FlakeRef> FlakeRef::fetchTree(ref<Store> store) const
289289
return {std::move(storePath), FlakeRef(std::move(lockedInput), subdir)};
290290
}
291291

292+
std::pair<ref<SourceAccessor>, FlakeRef> FlakeRef::lazyFetch(ref<Store> store) const
293+
{
294+
auto [accessor, lockedInput] = input.getAccessor(store);
295+
return {accessor, FlakeRef(std::move(lockedInput), subdir)};
296+
}
297+
292298
std::tuple<FlakeRef, std::string, ExtendedOutputsSpec> parseFlakeRefWithFragmentAndExtendedOutputsSpec(
293299
const fetchers::Settings & fetchSettings,
294300
const std::string & url,

src/libflake/flake/flakeref.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,10 @@ struct FlakeRef
7171
const fetchers::Settings & fetchSettings,
7272
const fetchers::Attrs & attrs);
7373

74+
// FIXME: remove
7475
std::pair<StorePath, FlakeRef> fetchTree(ref<Store> store) const;
76+
77+
std::pair<ref<SourceAccessor>, FlakeRef> lazyFetch(ref<Store> store) const;
7578
};
7679

7780
std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef);

0 commit comments

Comments
 (0)