diff --git a/src/libstore/dummy-store.cc b/src/libstore/dummy-store.cc index c452d38bfc7..6d23cb3b426 100644 --- a/src/libstore/dummy-store.cc +++ b/src/libstore/dummy-store.cc @@ -412,7 +412,7 @@ ref adl_serializer>::from_json(const j { auto & obj = getObject(json); auto cfg = make_ref(DummyStore::Config::Params{}); - const_cast(cfg->storeDir_).set(getString(valueAt(obj, "store"))); + cfg->storeDir_.set(getString(valueAt(obj, "store"))); cfg->readOnly = true; return cfg; } diff --git a/src/libstore/include/nix/store/store-api.hh b/src/libstore/include/nix/store/store-api.hh index 24a2d923031..d7454dbff04 100644 --- a/src/libstore/include/nix/store/store-api.hh +++ b/src/libstore/include/nix/store/store-api.hh @@ -72,6 +72,32 @@ struct MissingPaths uint64_t narSize{0}; }; +/** + * A setting for the Nix store directory. Automatically canonicalises the + * path and rejects the empty string. Stored as `std::string` because + * store directory are valid file paths on *some* OS, but not neccessarily the OS of this build of Nix. + * + * (For example, consider `SSHStore` from Linux to Windows, or vice versa, the foreign path will not be a valid + * `std::filesystem::path`.) + */ +class StoreDirSetting : public BaseSetting +{ +public: + StoreDirSetting( + Config * options, + const std::string & def, + const std::string & name, + const std::string & description, + const StringSet & aliases = {}); + + std::string parse(const std::string & str) const override; + + void operator=(const std::string & v) + { + this->assign(v); + } +}; + /** * Need to make this a separate class so I can get the right * initialization order in the constructor for `StoreConfig`. @@ -86,11 +112,11 @@ private: * Compute the default Nix store directory from environment variables * (`NIX_STORE_DIR`, `NIX_STORE`) or the compile-time default. */ - static Path getDefaultNixStoreDir(); + static std::string getDefaultNixStoreDir(); public: - const PathSetting storeDir_{ + StoreDirSetting storeDir_{ this, getDefaultNixStoreDir(), "store", diff --git a/src/libstore/include/nix/store/store-dir-config.hh b/src/libstore/include/nix/store/store-dir-config.hh index 34e928182ad..78ce4507299 100644 --- a/src/libstore/include/nix/store/store-dir-config.hh +++ b/src/libstore/include/nix/store/store-dir-config.hh @@ -29,7 +29,7 @@ MakeError(BadStorePathName, BadStorePath); */ struct StoreDirConfig { - const Path & storeDir; + const std::string & storeDir; // pure methods diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 13f0d61c2c5..641163b598e 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -32,13 +32,35 @@ using json = nlohmann::json; namespace nix { -Path StoreConfigBase::getDefaultNixStoreDir() +std::string StoreConfigBase::getDefaultNixStoreDir() { return #ifndef _WIN32 canonPath #endif - (getEnvNonEmpty("NIX_STORE_DIR").value_or(getEnvNonEmpty("NIX_STORE").value_or(NIX_STORE_DIR))); + (getEnvNonEmpty("NIX_STORE_DIR").value_or(getEnvNonEmpty("NIX_STORE").value_or(NIX_STORE_DIR))) +#ifndef _WIN32 + .string() +#endif + ; +} + +StoreDirSetting::StoreDirSetting( + Config * options, + const std::string & def, + const std::string & name, + const std::string & description, + const StringSet & aliases) + : BaseSetting(def, true, name, description, aliases) +{ + options->addSetting(this); +} + +std::string StoreDirSetting::parse(const std::string & str) const +{ + if (str.empty()) + throw UsageError("setting '%s' is a path and paths cannot be empty", name); + return canonPath(str).string(); } StoreConfig::StoreConfig(const Params & params) diff --git a/src/libutil/configuration.cc b/src/libutil/configuration.cc index 2fe000e4d92..0262a30e206 100644 --- a/src/libutil/configuration.cc +++ b/src/libutil/configuration.cc @@ -514,46 +514,6 @@ template class BaseSetting; template class BaseSetting>; template class BaseSetting>; -PathSetting::PathSetting( - Config * options, - const Path & def, - const std::string & name, - const std::string & description, - const StringSet & aliases) - : BaseSetting(def, true, name, description, aliases) -{ - options->addSetting(this); -} - -Path PathSetting::parse(const std::string & str) const -{ - return parsePath(*this, str).string(); -} - -OptionalPathSetting::OptionalPathSetting( - Config * options, - const std::optional & def, - const std::string & name, - const std::string & description, - const StringSet & aliases) - : BaseSetting>(def, true, name, description, aliases) -{ - options->addSetting(this); -} - -std::optional OptionalPathSetting::parse(const std::string & str) const -{ - if (str == "") - return std::nullopt; - else - return parsePath(*this, str).string(); -} - -void OptionalPathSetting::operator=(const std::optional & v) -{ - this->assign(v); -} - bool ExperimentalFeatureSettings::isEnabled(const ExperimentalFeature & feature) const { auto & f = experimentalFeatures.get(); diff --git a/src/libutil/include/nix/util/configuration.hh b/src/libutil/include/nix/util/configuration.hh index 541febdb5f9..f09b194baa0 100644 --- a/src/libutil/include/nix/util/configuration.hh +++ b/src/libutil/include/nix/util/configuration.hh @@ -379,58 +379,6 @@ public: } }; -/** - * A special setting for Paths. These are automatically canonicalised - * (e.g. "/foo//bar/" becomes "/foo/bar"). - * - * It is mandatory to specify a path; i.e. the empty string is not - * permitted. - */ -class PathSetting : public BaseSetting -{ -public: - - PathSetting( - Config * options, - const Path & def, - const std::string & name, - const std::string & description, - const StringSet & aliases = {}); - - Path parse(const std::string & str) const override; - - Path operator+(const char * p) const - { - return value + p; - } - - void operator=(const Path & v) - { - this->assign(v); - } -}; - -/** - * Like `PathSetting`, but the absence of a path is also allowed. - * - * `std::optional` is used instead of the empty string for clarity. - */ -class OptionalPathSetting : public BaseSetting> -{ -public: - - OptionalPathSetting( - Config * options, - const std::optional & def, - const std::string & name, - const std::string & description, - const StringSet & aliases = {}); - - std::optional parse(const std::string & str) const override; - - void operator=(const std::optional & v); -}; - struct ExperimentalFeatureSettings : Config {