diff --git a/src/libfetchers-tests/git.cc b/src/libfetchers-tests/git.cc index af987e260..4f0e0d974 100644 --- a/src/libfetchers-tests/git.cc +++ b/src/libfetchers-tests/git.cc @@ -1,5 +1,6 @@ #include "nix/store/store-open.hh" #include "nix/store/globals.hh" +#include "nix/store/dummy-store.hh" #include "nix/fetchers/fetch-settings.hh" #include "nix/fetchers/fetchers.hh" #include "nix/fetchers/git-utils.hh" @@ -179,10 +180,11 @@ TEST_F(GitTest, submodulePeriodSupport) // 6) Commit the addition in super commitAll(super.get(), "Add submodule with branch='.'"); - // TODO: Use dummy:// store with MemorySourceAccessor. - Path storeTmpDir = createTempDir(); - auto storeTmpDirAutoDelete = AutoDelete(storeTmpDir, true); - ref store = openStore(storeTmpDir); + auto store = [] { + auto cfg = make_ref(StoreReference::Params{}); + cfg->readOnly = false; + return cfg->openStore(); + }(); auto settings = fetchers::Settings{}; auto input = fetchers::Input::fromAttrs( diff --git a/src/libstore/dummy-store.cc b/src/libstore/dummy-store.cc index defee4a98..2909d20e0 100644 --- a/src/libstore/dummy-store.cc +++ b/src/libstore/dummy-store.cc @@ -1,5 +1,7 @@ #include "nix/store/store-registration.hh" +#include "nix/util/archive.hh" #include "nix/util/callback.hh" +#include "nix/util/memory-source-accessor.hh" #include "nix/store/dummy-store.hh" namespace nix { @@ -17,9 +19,12 @@ struct DummyStore : virtual Store ref config; + ref contents; + DummyStore(ref config) : Store{*config} , config(config) + , contents(make_ref()) { } @@ -47,8 +52,8 @@ struct DummyStore : virtual Store unsupported("addToStore"); } - virtual StorePath addToStoreFromDump( - Source & dump, + StorePath addToStoreFromDump( + Source & source, std::string_view name, FileSerialisationMethod dumpMethod = FileSerialisationMethod::NixArchive, ContentAddressMethod hashMethod = FileIngestionMethod::NixArchive, @@ -56,7 +61,45 @@ struct DummyStore : virtual Store const StorePathSet & references = StorePathSet(), RepairFlag repair = NoRepair) override { - unsupported("addToStore"); + if (config->readOnly) + unsupported("addToStoreFromDump"); + + auto temp = make_ref(); + + { + MemorySink tempSink{*temp}; + + // TODO factor this out into `restorePath`, same todo on it. + switch (dumpMethod) { + case FileSerialisationMethod::NixArchive: + parseDump(tempSink, source); + break; + case FileSerialisationMethod::Flat: { + // Replace root dir with file so next part succeeds. + temp->root = MemorySourceAccessor::File::Regular{}; + tempSink.createRegularFile(CanonPath::root, [&](auto & sink) { source.drainInto(sink); }); + break; + } + } + } + + auto hash = hashPath({temp, CanonPath::root}, hashMethod.getFileIngestionMethod(), hashAlgo).first; + + auto desc = ContentAddressWithReferences::fromParts( + hashMethod, + hash, + { + .others = references, + // caller is not capable of creating a self-reference, because + // this is content-addressed without modulus + .self = false, + }); + + auto dstPath = makeFixedOutputPathFromCA(name, desc); + + contents->open(CanonPath(printStorePath(dstPath)), std::move(temp->root)); + + return dstPath; } void narFromPath(const StorePath & path, Sink & sink) override @@ -72,7 +115,7 @@ struct DummyStore : virtual Store virtual ref getFSAccessor(bool requireValidPath) override { - return makeEmptySourceAccessor(); + return this->contents; } }; diff --git a/src/libstore/dummy-store.md b/src/libstore/dummy-store.md index eb7b4ba0d..3cbec3b3a 100644 --- a/src/libstore/dummy-store.md +++ b/src/libstore/dummy-store.md @@ -2,9 +2,11 @@ R"( **Store URL format**: `dummy://` -This store type represents a store that contains no store paths and -cannot be written to. It's useful when you want to use the Nix -evaluator when no actual Nix store exists, e.g. +This store type represents a store in memory. +Store objects can be read and written, but only so long as the store is open. +Once the store is closed, all data will be forgoton. + +It's useful when you want to use the Nix evaluator when no actual Nix store exists, e.g. ```console # nix eval --store dummy:// --expr '1 + 2' diff --git a/src/libstore/include/nix/store/dummy-store.hh b/src/libstore/include/nix/store/dummy-store.hh index 9cb26d8d4..0a15667b6 100644 --- a/src/libstore/include/nix/store/dummy-store.hh +++ b/src/libstore/include/nix/store/dummy-store.hh @@ -13,6 +13,15 @@ struct DummyStoreConfig : public std::enable_shared_from_this, throw UsageError("`%s` store URIs must not contain an authority part %s", scheme, authority); } + Setting readOnly{ + this, + true, + "read-only", + R"( + Make any sort of write fail instead of succeeding. + No additional memory will be used, because no information needs to be stored. + )"}; + static const std::string name() { return "Dummy Store";