Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/libfetchers-tests/git.cc
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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> store = openStore(storeTmpDir);
auto store = [] {
auto cfg = make_ref<DummyStoreConfig>(StoreReference::Params{});
cfg->readOnly = false;
return cfg->openStore();
}();

auto settings = fetchers::Settings{};
auto input = fetchers::Input::fromAttrs(
Expand Down
94 changes: 52 additions & 42 deletions src/libstore/dummy-store.cc
Original file line number Diff line number Diff line change
@@ -1,58 +1,30 @@
#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 {

struct DummyStoreConfig : public std::enable_shared_from_this<DummyStoreConfig>, virtual StoreConfig
std::string DummyStoreConfig::doc()
{
using StoreConfig::StoreConfig;

DummyStoreConfig(std::string_view scheme, std::string_view authority, const Params & params)
: StoreConfig(params)
{
if (!authority.empty())
throw UsageError("`%s` store URIs must not contain an authority part %s", scheme, authority);
}

static const std::string name()
{
return "Dummy Store";
}

static std::string doc()
{
return
return
#include "dummy-store.md"
;
}

static StringSet uriSchemes()
{
return {"dummy"};
}

ref<Store> openStore() const override;

StoreReference getReference() const override
{
return {
.variant =
StoreReference::Specified{
.scheme = *uriSchemes().begin(),
},
};
}
};
;
}

struct DummyStore : virtual Store
{
using Config = DummyStoreConfig;

ref<const Config> config;

ref<MemorySourceAccessor> contents;

DummyStore(ref<const Config> config)
: Store{*config}
, config(config)
, contents(make_ref<MemorySourceAccessor>())
{
}

Expand Down Expand Up @@ -80,16 +52,54 @@ 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,
HashAlgorithm hashAlgo = HashAlgorithm::SHA256,
const StorePathSet & references = StorePathSet(),
RepairFlag repair = NoRepair) override
{
unsupported("addToStore");
if (config->readOnly)
unsupported("addToStoreFromDump");

auto temp = make_ref<MemorySourceAccessor>();

{
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
Expand All @@ -105,7 +115,7 @@ struct DummyStore : virtual Store

virtual ref<SourceAccessor> getFSAccessor(bool requireValidPath) override
{
return makeEmptySourceAccessor();
return this->contents;
}
};

Expand Down
8 changes: 5 additions & 3 deletions src/libstore/dummy-store.md
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
50 changes: 50 additions & 0 deletions src/libstore/include/nix/store/dummy-store.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "nix/store/store-api.hh"

namespace nix {

struct DummyStoreConfig : public std::enable_shared_from_this<DummyStoreConfig>, virtual StoreConfig
{
using StoreConfig::StoreConfig;

DummyStoreConfig(std::string_view scheme, std::string_view authority, const Params & params)
: StoreConfig(params)
{
if (!authority.empty())
throw UsageError("`%s` store URIs must not contain an authority part %s", scheme, authority);
}

Setting<bool> 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";
}

static std::string doc();

static StringSet uriSchemes()
{
return {"dummy"};
}

ref<Store> openStore() const override;

StoreReference getReference() const override
{
return {
.variant =
StoreReference::Specified{
.scheme = *uriSchemes().begin(),
},
};
}
};

} // namespace nix
1 change: 1 addition & 0 deletions src/libstore/include/nix/store/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ headers = [ config_pub_h ] + files(
'derived-path-map.hh',
'derived-path.hh',
'downstream-placeholder.hh',
'dummy-store.hh',
'export-import.hh',
'filetransfer.hh',
'gc-store.hh',
Expand Down
3 changes: 3 additions & 0 deletions src/libutil/include/nix/util/memory-source-accessor.hh
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#pragma once
///@file

#include "nix/util/source-path.hh"
#include "nix/util/fs-sink.hh"
#include "nix/util/variant-wrapper.hh"
Expand Down
Loading