@@ -137,12 +137,31 @@ struct DummyStoreImpl : DummyStore
137137 void queryPathInfoUncached (
138138 const StorePath & path, Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept override
139139 {
140- bool visited = contents.cvisit (path, [&](const auto & kv) {
141- callback (std::make_shared<ValidPathInfo>(StorePath{kv.first }, kv.second .info ));
142- });
140+ if (path.isDerivation ()) {
141+ if (auto accessor_ = getMemoryFSAccessor (path)) {
142+ ref<MemorySourceAccessor> accessor = ref{std::move (accessor_)};
143+ /* compute path info on demand */
144+ auto narHash =
145+ hashPath ({accessor, CanonPath::root}, FileSerialisationMethod::NixArchive, HashAlgorithm::SHA256);
146+ auto info = std::make_shared<ValidPathInfo>(path, UnkeyedValidPathInfo{narHash.hash });
147+ info->narSize = narHash.numBytesDigested ;
148+ info->ca = ContentAddress{
149+ .method = ContentAddressMethod::Raw::Text,
150+ .hash = hashString (
151+ HashAlgorithm::SHA256,
152+ std::get<MemorySourceAccessor::File::Regular>(accessor->root ->raw ).contents ),
153+ };
154+ callback (std::move (info));
155+ return ;
156+ }
157+ } else {
158+ if (contents.cvisit (path, [&](const auto & kv) {
159+ callback (std::make_shared<ValidPathInfo>(StorePath{kv.first }, kv.second .info ));
160+ }))
161+ return ;
162+ }
143163
144- if (!visited)
145- callback (nullptr );
164+ callback (nullptr );
146165 }
147166
148167 /* *
@@ -169,18 +188,25 @@ struct DummyStoreImpl : DummyStore
169188 if (checkSigs)
170189 throw Error (" checking signatures is not supported for '%s' store" , config->getHumanReadableURI ());
171190
172- auto temp = make_ref<MemorySourceAccessor>();
173- MemorySink tempSink{*temp };
191+ auto accessor = make_ref<MemorySourceAccessor>();
192+ MemorySink tempSink{*accessor };
174193 parseDump (tempSink, source);
175194 auto path = info.path ;
176195
177- auto accessor = make_ref<MemorySourceAccessor>(std::move (*temp));
178- contents.insert (
179- {path,
180- PathInfoAndContents{
181- std::move (info),
182- accessor,
183- }});
196+ if (info.path .isDerivation ()) {
197+ warn (" back compat supporting `addToStore` for inserting derivations in dummy store" );
198+ writeDerivation (
199+ parseDerivation (*this , accessor->readFile (CanonPath::root), Derivation::nameFromPath (info.path )));
200+ return ;
201+ }
202+
203+ contents.insert ({
204+ path,
205+ PathInfoAndContents{
206+ std::move (info),
207+ accessor,
208+ },
209+ });
184210 wholeStoreView->addObject (path.to_string (), accessor);
185211 }
186212
@@ -193,6 +219,9 @@ struct DummyStoreImpl : DummyStore
193219 const StorePathSet & references = StorePathSet(),
194220 RepairFlag repair = NoRepair) override
195221 {
222+ if (isDerivation (name))
223+ throw Error (" Do not insert derivation into dummy store with `addToStoreFromDump`" );
224+
196225 if (config->readOnly )
197226 unsupported (" addToStoreFromDump" );
198227
@@ -239,17 +268,47 @@ struct DummyStoreImpl : DummyStore
239268
240269 auto path = info.path ;
241270 auto accessor = make_ref<MemorySourceAccessor>(std::move (*temp));
242- contents.insert (
243- {path,
244- PathInfoAndContents{
245- std::move (info),
246- accessor,
247- }});
271+ contents.insert ({
272+ path,
273+ PathInfoAndContents{
274+ std::move (info),
275+ accessor,
276+ },
277+ });
248278 wholeStoreView->addObject (path.to_string (), accessor);
249279
250280 return path;
251281 }
252282
283+ StorePath writeDerivation (const Derivation & drv, RepairFlag repair = NoRepair) override
284+ {
285+ auto drvPath = ::nix::writeDerivation (*this , drv, repair, /* readonly=*/ true );
286+
287+ if (!derivations.contains (drvPath) || repair) {
288+ if (config->readOnly )
289+ unsupported (" writeDerivation" );
290+ derivations.insert ({drvPath, drv});
291+ }
292+
293+ return drvPath;
294+ }
295+
296+ Derivation readDerivation (const StorePath & drvPath) override
297+ {
298+ if (std::optional res = getConcurrent (derivations, drvPath))
299+ return *res;
300+ else
301+ throw Error (" derivation '%s' is not valid" , printStorePath (drvPath));
302+ }
303+
304+ /* *
305+ * No such thing as an "invalid derivation" with the dummy store
306+ */
307+ Derivation readInvalidDerivation (const StorePath & drvPath) override
308+ {
309+ return readDerivation (drvPath);
310+ }
311+
253312 void registerDrvOutput (const Realisation & output) override
254313 {
255314 auto ref = make_ref<UnkeyedRealisation>(output);
@@ -273,13 +332,28 @@ struct DummyStoreImpl : DummyStore
273332 callback (nullptr );
274333 }
275334
276- std::shared_ptr<SourceAccessor> getFSAccessor (const StorePath & path, bool requireValidPath) override
335+ std::shared_ptr<MemorySourceAccessor> getMemoryFSAccessor (const StorePath & path, bool requireValidPath = true )
277336 {
278- std::shared_ptr<SourceAccessor> res;
279- contents.cvisit (path, [&](const auto & kv) { res = kv.second .contents .get_ptr (); });
337+ std::shared_ptr<MemorySourceAccessor> res;
338+ if (path.isDerivation ())
339+ derivations.cvisit (path, [&](const auto & kv) {
340+ /* compute path info on demand */
341+ auto res2 = make_ref<MemorySourceAccessor>();
342+ res2->root = MemorySourceAccessor::File::Regular{
343+ .contents = kv.second .unparse (*this , false ),
344+ };
345+ res = std::move (res2).get_ptr ();
346+ });
347+ else
348+ contents.cvisit (path, [&](const auto & kv) { res = kv.second .contents .get_ptr (); });
280349 return res;
281350 }
282351
352+ std::shared_ptr<SourceAccessor> getFSAccessor (const StorePath & path, bool requireValidPath = true ) override
353+ {
354+ return getMemoryFSAccessor (path, requireValidPath);
355+ }
356+
283357 ref<SourceAccessor> getFSAccessor (bool requireValidPath) override
284358 {
285359 return wholeStoreView;
0 commit comments