diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 4040a3fac..18bb9b12e 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -2883,7 +2883,7 @@ struct RestrictedStore : public LocalFSStore DerivationGoal & goal; RestrictedStore(const Params & params, ref next, DerivationGoal & goal) - : StoreConfig(params), LocalFSStoreConfig(params), Store(params), LocalFSStore(params), next(next), goal(goal) + : StoreConfig(params), Store(params), LocalFSStore(params), next(next), goal(goal) { } Path getRealStoreDir() override diff --git a/src/libstore/dummy-store.cc b/src/libstore/dummy-store.cc index 210e5b11c..074953b1d 100644 --- a/src/libstore/dummy-store.cc +++ b/src/libstore/dummy-store.cc @@ -2,7 +2,7 @@ namespace nix { -struct DummyStoreConfig : StoreConfig { +struct DummyStoreConfig : virtual StoreConfig { using StoreConfig::StoreConfig; }; @@ -14,7 +14,6 @@ struct DummyStore : public Store, public virtual DummyStoreConfig DummyStore(const Params & params) : StoreConfig(params) - , DummyStoreConfig(params) , Store(params) { } diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index 095eaa82c..bd65273eb 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -33,9 +33,7 @@ public: const Path & _cacheUri, const Params & params) : StoreConfig(params) - , BinaryCacheStoreConfig(params) , BinaryCacheStore(params) - , HttpBinaryCacheStoreConfig(params) , cacheUri(scheme + "://" + _cacheUri) { if (cacheUri.back() == '/') diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index 6dc83e288..ce9051d20 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -45,7 +45,6 @@ struct LegacySSHStore : public Store, public virtual LegacySSHStoreConfig LegacySSHStore(const string & scheme, const string & host, const Params & params) : StoreConfig(params) - , LegacySSHStoreConfig(params) , Store(params) , host(host) , connections(make_ref>( diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc index 4d11e0f2a..b893befbc 100644 --- a/src/libstore/local-binary-cache-store.cc +++ b/src/libstore/local-binary-cache-store.cc @@ -22,8 +22,6 @@ public: const Path & binaryCacheDir, const Params & params) : StoreConfig(params) - , BinaryCacheStoreConfig(params) - , LocalBinaryCacheStoreConfig(params) , BinaryCacheStore(params) , binaryCacheDir(binaryCacheDir) { diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 4e9840f3b..c618203f0 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -44,8 +44,6 @@ namespace nix { LocalStore::LocalStore(const Params & params) : StoreConfig(params) , Store(params) - , LocalFSStoreConfig(params) - , LocalStoreConfig(params) , LocalFSStore(params) , realStoreDir_{this, false, rootDir != "" ? rootDir + "/nix/store" : storeDir, "real", "physical path to the Nix store"} diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 561502cbe..4c8ffe71e 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -126,9 +126,6 @@ ref RemoteStore::openConnectionWrapper() UDSRemoteStore::UDSRemoteStore(const Params & params) : StoreConfig(params) , Store(params) - , LocalFSStoreConfig(params) - , RemoteStoreConfig(params) - , UDSRemoteStoreConfig(params) , LocalFSStore(params) , RemoteStore(params) { diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc index 020b20c37..e4548dd22 100644 --- a/src/libstore/s3-binary-cache-store.cc +++ b/src/libstore/s3-binary-cache-store.cc @@ -201,8 +201,6 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore, virtual S3BinaryCache const std::string & bucketName, const Params & params) : StoreConfig(params) - , BinaryCacheStoreConfig(params) - , S3BinaryCacheStoreConfig(params) , S3BinaryCacheStore(params) , bucketName(bucketName) , s3Helper(profile, region, scheme, endpoint) diff --git a/src/libstore/ssh-store.cc b/src/libstore/ssh-store.cc index 13265e127..fac251d8f 100644 --- a/src/libstore/ssh-store.cc +++ b/src/libstore/ssh-store.cc @@ -25,9 +25,7 @@ public: SSHStore([[maybe_unused]] const std::string & scheme, const std::string & host, const Params & params) : StoreConfig(params) , Store(params) - , RemoteStoreConfig(params) , RemoteStore(params) - , SSHStoreConfig(params) , host(host) , master( host, diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 6f7893e41..a67123ff0 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -24,6 +24,31 @@ namespace nix { +/** + * About the class hierarchy of the store implementations: + * + * Each store type `Foo` consists of two classes: + * + * 1. A class `FooConfig : virtual StoreConfig` that contains the configuration + * for the store + * + * It should only contain members of type `const Setting` (or subclasses + * of it) and inherit the constructors of `StoreConfig` + * (`using StoreConfig::StoreConfig`). + * + * 2. A class `Foo : virtual Store, virtual FooConfig` that contains the + * implementation of the store. + * + * This class is expected to have a constructor `Foo(const Params & params)` + * that calls `StoreConfig(params)` (otherwise you're gonna encounter an + * `assertion failure` when trying to instantiate it). + * + * You can then register the new store using: + * + * ``` + * cpp static RegisterStoreImplementation regStore; + * ``` + */ MakeError(SubstError, Error); MakeError(BuildError, Error); // denotes a permanent build failure @@ -148,7 +173,26 @@ struct BuildResult struct StoreConfig : public Config { using Config::Config; - StoreConfig() = delete; + + /** + * When constructing a store implementation, we pass in a map `params` of + * parameters that's supposed to initialize the associated config. + * To do that, we must use the `StoreConfig(StringMap & params)` + * constructor, so we'd like to `delete` its default constructor to enforce + * it. + * + * However, actually deleting it means that all the subclasses of + * `StoreConfig` will have their default constructor deleted (because it's + * supposed to call the deleted default constructor of `StoreConfig`). But + * because we're always using virtual inheritance, the constructors of + * child classes will never implicitely call this one, so deleting it will + * be more painful than anything else. + * + * So we `assert(false)` here to ensure at runtime that the right + * constructor is always called without having to redefine a custom + * constructor for each `*Config` class. + */ + StoreConfig() { assert(false); } const PathSetting storeDir_{this, false, settings.nixStore,