Make store setting and store flags use StoreReference

This commit is contained in:
John Ericson 2024-01-24 11:05:26 -05:00
parent 4a19f4a866
commit a7c841f704
35 changed files with 269 additions and 105 deletions

View File

@ -75,28 +75,32 @@ CopyCommand::CopyCommand()
.longName = "from", .longName = "from",
.description = "URL of the source Nix store.", .description = "URL of the source Nix store.",
.labels = {"store-uri"}, .labels = {"store-uri"},
.handler = {&srcUri}, .handler = {[&](std::string storeUri) {
srcUri = StoreReference::parse(storeUri);
}},
}); });
addFlag({ addFlag({
.longName = "to", .longName = "to",
.description = "URL of the destination Nix store.", .description = "URL of the destination Nix store.",
.labels = {"store-uri"}, .labels = {"store-uri"},
.handler = {&dstUri}, .handler = {[&](std::string storeUri) {
dstUri = StoreReference::parse(storeUri);
}},
}); });
} }
ref<Store> CopyCommand::createStore() ref<Store> CopyCommand::createStore()
{ {
return srcUri.empty() ? StoreCommand::createStore() : openStore(srcUri); return !srcUri ? StoreCommand::createStore() : openStore(*srcUri);
} }
ref<Store> CopyCommand::getDstStore() ref<Store> CopyCommand::getDstStore()
{ {
if (srcUri.empty() && dstUri.empty()) if (!srcUri && !dstUri)
throw UsageError("you must pass '--from' and/or '--to'"); throw UsageError("you must pass '--from' and/or '--to'");
return dstUri.empty() ? openStore() : openStore(dstUri); return !dstUri ? openStore() : openStore(*dstUri);
} }
EvalCommand::EvalCommand() EvalCommand::EvalCommand()

View File

@ -62,7 +62,7 @@ private:
*/ */
struct CopyCommand : virtual StoreCommand struct CopyCommand : virtual StoreCommand
{ {
std::string srcUri, dstUri; std::optional<StoreReference> srcUri, dstUri;
CopyCommand(); CopyCommand();

View File

@ -164,7 +164,9 @@ MixEvalArgs::MixEvalArgs()
)", )",
.category = category, .category = category,
.labels = {"store-url"}, .labels = {"store-url"},
.handler = {&evalStoreUrl}, .handler = {[&](std::string s) {
evalStoreUrl = StoreReference::parse(s);
}},
}); });
} }

View File

@ -5,6 +5,7 @@
#include "canon-path.hh" #include "canon-path.hh"
#include "common-args.hh" #include "common-args.hh"
#include "search-path.hh" #include "search-path.hh"
#include "store-reference.hh"
#include <filesystem> #include <filesystem>
@ -25,7 +26,7 @@ struct MixEvalArgs : virtual Args, virtual MixRepair
LookupPath lookupPath; LookupPath lookupPath;
std::optional<std::string> evalStoreUrl; std::optional<StoreReference> evalStoreUrl;
private: private:
struct AutoArgExpr { std::string expr; }; struct AutoArgExpr { std::string expr; };

View File

@ -1,3 +1,5 @@
#include <nlohmann/json.hpp>
#include "terminal.hh" #include "terminal.hh"
#include "flake.hh" #include "flake.hh"
#include "eval.hh" #include "eval.hh"

View File

@ -182,23 +182,26 @@ static void prim_fetchClosure(EvalState & state, const PosIdx pos, Value * * arg
.pos = state.positions[pos] .pos = state.positions[pos]
}); });
auto parsedURL = parseURL(*fromStoreUrl); auto parsedURL = StoreReference::parse(*fromStoreUrl);
if (parsedURL.scheme != "http" && auto * storeVariant = std::get_if<StoreReference::Specified>(&parsedURL.variant);
parsedURL.scheme != "https" &&
!(getEnv("_NIX_IN_TEST").has_value() && parsedURL.scheme == "file")) if (!storeVariant ||
(storeVariant->scheme != "http" &&
storeVariant->scheme != "https" &&
!(getEnv("_NIX_IN_TEST").has_value() && storeVariant->scheme == "file")))
throw Error({ throw Error({
.msg = HintFmt("'fetchClosure' only supports http:// and https:// stores"), .msg = HintFmt("'fetchClosure' only supports http:// and https:// stores"),
.pos = state.positions[pos] .pos = state.positions[pos]
}); });
if (!parsedURL.query.empty()) if (!parsedURL.params.empty())
throw Error({ throw Error({
.msg = HintFmt("'fetchClosure' does not support URL query parameters (in '%s')", *fromStoreUrl), .msg = HintFmt("'fetchClosure' does not support URL query parameters (in '%s')", *fromStoreUrl),
.pos = state.positions[pos] .pos = state.positions[pos]
}); });
auto fromStore = openStore(parsedURL.to_string()); auto fromStore = openStore(parsedURL);
if (toPath) if (toPath)
runFetchClosureWithRewrite(state, pos, *fromStore, *fromPath, *toPath, v); runFetchClosureWithRewrite(state, pos, *fromStore, *fromPath, *toPath, v);

View File

@ -15,6 +15,8 @@
#include <iomanip> #include <iomanip>
#include <regex> #include <regex>
#include <nlohmann/json.hpp>
namespace nix { namespace nix {
void emitTreeAttrs( void emitTreeAttrs(

View File

@ -13,6 +13,7 @@
#include "git-utils.hh" #include "git-utils.hh"
#include "logging.hh" #include "logging.hh"
#include "finally.hh" #include "finally.hh"
#include "json-utils.hh"
#include "fetch-settings.hh" #include "fetch-settings.hh"

View File

@ -49,14 +49,15 @@ Store * nix_store_open(nix_c_context * context, const char * uri, const char ***
if (uri_str.empty()) if (uri_str.empty())
return new Store{nix::openStore()}; return new Store{nix::openStore()};
if (!params) auto base_uri = nix::StoreReference::parse(uri_str);
return new Store{nix::openStore(uri_str)};
nix::Store::Params params_map; if (params) {
for (size_t i = 0; params[i] != nullptr; i++) { for (size_t i = 0; params[i] != nullptr; i++) {
params_map[params[i][0]] = params[i][1]; base_uri.params[params[i][0]] = params[i][1];
}
} }
return new Store{nix::openStore(uri_str, params_map)};
return new Store{nix::openStore(std::move(base_uri))};
} }
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL
} }

View File

@ -215,22 +215,22 @@ struct ClientSettings
auto & name(i.first); auto & name(i.first);
auto & value(i.second); auto & value(i.second);
auto setSubstituters = [&](Setting<Strings> & res) { auto setSubstituters = [&](Setting<std::vector<StoreReference>> & res) {
if (name != res.name && res.aliases.count(name) == 0) if (name != res.name && res.aliases.count(name) == 0)
return false; return false;
StringSet trusted = settings.trustedSubstituters; std::set<StoreReference> trusted = settings.trustedSubstituters;
for (auto & s : settings.substituters.get()) for (auto & s : settings.substituters.get())
trusted.insert(s); trusted.insert(s);
Strings subs; std::vector<StoreReference> subs;
auto ss = tokenizeString<Strings>(value); auto ss = tokenizeString<Strings>(value);
for (auto & s : ss) for (auto & s : ss) {
if (trusted.count(s)) auto ref = StoreReference::parse(s);
subs.push_back(s); if (trusted.count(ref))
else if (!hasSuffix(s, "/") && trusted.count(s + "/")) subs.push_back(ref);
subs.push_back(s + "/");
else else
warn("ignoring untrusted substituter '%s', you are not a trusted user.\n" warn("ignoring untrusted substituter '%s', you are not a trusted user.\n"
"Run `man nix.conf` for more information on the `substituters` configuration option.", s); "Run `man nix.conf` for more information on the `substituters` configuration option.", s);
}
res = subs; res = subs;
return true; return true;
}; };

View File

@ -1,3 +1,6 @@
#include <boost/container/small_vector.hpp>
#include <nlohmann/json.hpp>
#include "derivations.hh" #include "derivations.hh"
#include "downstream-placeholder.hh" #include "downstream-placeholder.hh"
#include "store-api.hh" #include "store-api.hh"
@ -7,8 +10,7 @@
#include "split.hh" #include "split.hh"
#include "common-protocol.hh" #include "common-protocol.hh"
#include "common-protocol-impl.hh" #include "common-protocol-impl.hh"
#include <boost/container/small_vector.hpp> #include "json-utils.hh"
#include <nlohmann/json.hpp>
namespace nix { namespace nix {

View File

@ -35,6 +35,10 @@
namespace nix { namespace nix {
DECLARE_CONFIG_SERIALISER(StoreReference)
DECLARE_CONFIG_SERIALISER(std::optional<StoreReference>)
DECLARE_CONFIG_SERIALISER(std::set<StoreReference>)
DECLARE_CONFIG_SERIALISER(std::vector<StoreReference>)
/* The default location of the daemon socket, relative to nixStateDir. /* The default location of the daemon socket, relative to nixStateDir.
The socket is in a directory to allow you to control access to the The socket is in a directory to allow you to control access to the
@ -319,6 +323,66 @@ template<> void BaseSetting<SandboxMode>::convertToArg(Args & args, const std::s
}); });
} }
template<> StoreReference BaseSetting<StoreReference>::parse(const std::string & str) const
{
return StoreReference::parse(str);
}
template<> std::string BaseSetting<StoreReference>::to_string() const
{
return value.render();
}
template<> std::optional<StoreReference> BaseSetting<std::optional<StoreReference>>::parse(const std::string & str) const
{
if (str == "")
return std::nullopt;
else
return StoreReference::parse(str);
}
template<> std::string BaseSetting<std::optional<StoreReference>>::to_string() const
{
return value ? value->render() : "";
}
template<> std::set<StoreReference> BaseSetting<std::set<StoreReference>>::parse(const std::string & str) const
{
std::set<StoreReference> res;
for (const auto & s : tokenizeString<std::vector<std::string>>(str))
res.insert(StoreReference::parse(s));
return res;
}
template<> std::string BaseSetting<std::set<StoreReference>>::to_string() const
{
std::set<std::string> strings;
for (const auto & ref : value)
strings.insert(ref.render());
return concatStringsSep(" ", strings);
}
template<> std::vector<StoreReference> BaseSetting<std::vector<StoreReference>>::parse(const std::string & str) const
{
std::vector<StoreReference> res;
for (const auto & s : tokenizeString<std::vector<std::string>>(str))
res.push_back(StoreReference::parse(s));
return res;
}
template<> std::string BaseSetting<std::vector<StoreReference>>::to_string() const
{
std::vector<std::string> strings;
for (const auto & ref : value)
strings.push_back(ref.render());
return concatStringsSep(" ", strings);
}
template class BaseSetting<StoreReference>;
template class BaseSetting<std::optional<StoreReference>>;
template class BaseSetting<std::set<StoreReference>>;
template class BaseSetting<std::vector<StoreReference>>;
unsigned int MaxBuildJobsSetting::parse(const std::string & str) const unsigned int MaxBuildJobsSetting::parse(const std::string & str) const
{ {
if (str == "auto") return std::max(1U, std::thread::hardware_concurrency()); if (str == "auto") return std::max(1U, std::thread::hardware_concurrency());

View File

@ -5,6 +5,7 @@
#include "config.hh" #include "config.hh"
#include "environment-variables.hh" #include "environment-variables.hh"
#include "experimental-features.hh" #include "experimental-features.hh"
#include "store-reference.hh"
#include "users.hh" #include "users.hh"
#include <map> #include <map>
@ -116,7 +117,7 @@ public:
*/ */
Path nixDaemonSocketFile; Path nixDaemonSocketFile;
Setting<std::string> storeUri{this, getEnv("NIX_REMOTE").value_or("auto"), "store", Setting<StoreReference> storeUri{this, StoreReference::parse(getEnv("NIX_REMOTE").value_or("auto")), "store",
R"( R"(
The [URL of the Nix store](@docroot@/store/types/index.md#store-url-format) The [URL of the Nix store](@docroot@/store/types/index.md#store-url-format)
to use for most operations. to use for most operations.
@ -904,9 +905,16 @@ public:
// Don't document the machine-specific default value // Don't document the machine-specific default value
false}; false};
Setting<Strings> substituters{ Setting<std::vector<StoreReference>> substituters{
this, this,
Strings{"https://cache.nixos.org/"}, {
{
.variant = StoreReference::Specified {
.scheme = "https",
.authority = "cache.nixos.org",
},
},
},
"substituters", "substituters",
R"( R"(
A list of [URLs of Nix stores](@docroot@/store/types/index.md#store-url-format) to be used as substituters, separated by whitespace. A list of [URLs of Nix stores](@docroot@/store/types/index.md#store-url-format) to be used as substituters, separated by whitespace.
@ -925,7 +933,7 @@ public:
)", )",
{"binary-caches"}}; {"binary-caches"}};
Setting<StringSet> trustedSubstituters{ Setting<std::set<StoreReference>> trustedSubstituters{
this, {}, "trusted-substituters", this, {}, "trusted-substituters",
R"( R"(
A list of [Nix store URLs](@docroot@/store/types/index.md#store-url-format), separated by whitespace. A list of [Nix store URLs](@docroot@/store/types/index.md#store-url-format), separated by whitespace.

View File

@ -68,9 +68,9 @@ ref<LegacySSHStore::Connection> LegacySSHStore::openConnection()
Strings command = remoteProgram.get(); Strings command = remoteProgram.get();
command.push_back("--serve"); command.push_back("--serve");
command.push_back("--write"); command.push_back("--write");
if (remoteStore.get() != "") { if (std::optional rs = remoteStore.get()) {
command.push_back("--store"); command.push_back("--store");
command.push_back(remoteStore.get()); command.push_back(rs->render());
} }
conn->sshConn = master.startCommand(std::move(command)); conn->sshConn = master.startCommand(std::move(command));
conn->to = FdSink(conn->sshConn->in.get()); conn->to = FdSink(conn->sshConn->in.get());

View File

@ -1,6 +1,7 @@
#include "globals.hh" #include "globals.hh"
#include "nar-info.hh" #include "nar-info.hh"
#include "store-api.hh" #include "store-api.hh"
#include "json-utils.hh"
namespace nix { namespace nix {

View File

@ -18,7 +18,7 @@ struct CommonSSHStoreConfig : virtual StoreConfig
const Setting<bool> compress{this, false, "compress", const Setting<bool> compress{this, false, "compress",
"Whether to enable SSH compression."}; "Whether to enable SSH compression."};
const Setting<std::string> remoteStore{this, "", "remote-store", const Setting<std::optional<StoreReference>> remoteStore{this, std::nullopt, "remote-store",
R"( R"(
[Store URL](@docroot@/store/types/index.md#store-url-format) [Store URL](@docroot@/store/types/index.md#store-url-format)
to be used on the remote machine. The default is `auto` to be used on the remote machine. The default is `auto`

View File

@ -228,9 +228,9 @@ ref<RemoteStore::Connection> SSHStore::openConnection()
auto conn = make_ref<Connection>(); auto conn = make_ref<Connection>();
Strings command = remoteProgram.get(); Strings command = remoteProgram.get();
command.push_back("--stdio"); command.push_back("--stdio");
if (remoteStore.get() != "") { if (std::optional rs = remoteStore.get()) {
command.push_back("--store"); command.push_back("--store");
command.push_back(remoteStore.get()); command.push_back(rs->render());
} }
command.insert(command.end(), command.insert(command.end(),
extraRemoteProgramArgs.begin(), extraRemoteProgramArgs.end()); extraRemoteProgramArgs.begin(), extraRemoteProgramArgs.end());

View File

@ -1330,9 +1330,9 @@ std::list<ref<Store>> getDefaultSubstituters()
static auto stores([]() { static auto stores([]() {
std::list<ref<Store>> stores; std::list<ref<Store>> stores;
StringSet done; std::set<StoreReference> done;
auto addStore = [&](const std::string & uri) { auto addStore = [&](const StoreReference & uri) {
if (!done.insert(uri).second) return; if (!done.insert(uri).second) return;
try { try {
stores.push_back(openStore(uri)); stores.push_back(openStore(uri));

View File

@ -863,13 +863,10 @@ OutputPathMap resolveDerivedPath(Store &, const DerivedPath::Built &, Store * ev
*/ */
ref<Store> openStore(StoreReference && storeURI); ref<Store> openStore(StoreReference && storeURI);
static inline ref<Store> openStore(const StoreReference & storeURI = settings.storeUri.get())
/** {
* Opens the store at `uri`, where `uri` is in the format expected by `StoreReference::parse` return openStore(StoreReference { storeURI });
}
*/
ref<Store> openStore(const std::string & uri = settings.storeUri.get(),
const Store::Params & extraParams = Store::Params());
/** /**

View File

@ -1,4 +1,5 @@
#include <regex> #include <regex>
#include <nlohmann/json.hpp>
#include "error.hh" #include "error.hh"
#include "url.hh" #include "url.hh"
@ -114,3 +115,22 @@ std::pair<std::string, StoreReference::Params> splitUriAndParams(const std::stri
} }
} }
namespace nlohmann {
using namespace nix;
// TODO support something structured
StoreReference adl_serializer<StoreReference>::from_json(const json & json)
{
auto s = json.get<std::string>();
return StoreReference::parse(s);
}
void adl_serializer<StoreReference>::to_json(json & json, StoreReference ref)
{
json = ref.render();
}
}

View File

@ -4,6 +4,8 @@
#include <variant> #include <variant>
#include "types.hh" #include "types.hh"
#include "json-impls.hh"
#include "json-avoids-null.hh"
namespace nix { namespace nix {
@ -89,4 +91,14 @@ struct StoreReference
*/ */
std::pair<std::string, StoreReference::Params> splitUriAndParams(const std::string & uri); std::pair<std::string, StoreReference::Params> splitUriAndParams(const std::string & uri);
/**
* It is always rendered as a string
*/
template<>
struct json_avoids_null<StoreReference> : std::true_type
{
};
} }
JSON_IMPL(StoreReference)

View File

@ -26,7 +26,7 @@ LocalOverlayStore::LocalOverlayStore(const Params & params)
, Store(params) , Store(params)
, LocalFSStore(params) , LocalFSStore(params)
, LocalStore(params) , LocalStore(params)
, lowerStore(openStore(percentDecode(lowerStoreUri.get())).dynamic_pointer_cast<LocalFSStore>()) , lowerStore(openStore(lowerStoreUri.get()).dynamic_pointer_cast<LocalFSStore>())
{ {
if (checkMount.get()) { if (checkMount.get()) {
std::smatch match; std::smatch match;

View File

@ -13,7 +13,7 @@ struct LocalOverlayStoreConfig : virtual LocalStoreConfig
, LocalStoreConfig(params) , LocalStoreConfig(params)
{ } { }
const Setting<std::string> lowerStoreUri{(StoreConfig*) this, "", "lower-store", const Setting<StoreReference> lowerStoreUri{this, StoreReference{.variant = StoreReference::Auto{}}, "lower-store",
R"( R"(
[Store URL](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format) [Store URL](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format)
for the lower store. The default is `auto` (i.e. use the Nix daemon or `/nix/store` directly). for the lower store. The default is `auto` (i.e. use the Nix daemon or `/nix/store` directly).
@ -22,12 +22,12 @@ struct LocalOverlayStoreConfig : virtual LocalStoreConfig
Must be used as OverlayFS lower layer for this store's store dir. Must be used as OverlayFS lower layer for this store's store dir.
)"}; )"};
const PathSetting upperLayer{(StoreConfig*) this, "", "upper-layer", const PathSetting upperLayer{this, "", "upper-layer",
R"( R"(
Directory containing the OverlayFS upper layer for this store's store dir. Directory containing the OverlayFS upper layer for this store's store dir.
)"}; )"};
Setting<bool> checkMount{(StoreConfig*) this, true, "check-mount", Setting<bool> checkMount{this, true, "check-mount",
R"( R"(
Check that the overlay filesystem is correctly mounted. Check that the overlay filesystem is correctly mounted.
@ -38,7 +38,7 @@ struct LocalOverlayStoreConfig : virtual LocalStoreConfig
default, but can be disabled if needed. default, but can be disabled if needed.
)"}; )"};
const PathSetting remountHook{(StoreConfig*) this, "", "remount-hook", const PathSetting remountHook{this, "", "remount-hook",
R"( R"(
Script or other executable to run when overlay filesystem needs remounting. Script or other executable to run when overlay filesystem needs remounting.

View File

@ -3,7 +3,7 @@
#include "comparator.hh" #include "comparator.hh"
#include "error.hh" #include "error.hh"
#include "json-utils.hh" #include "json-avoids-null.hh"
#include "types.hh" #include "types.hh"
namespace nix { namespace nix {

View File

@ -0,0 +1,57 @@
#pragma once
///@file
#include <list>
#include <nlohmann/json_fwd.hpp>
#include "types.hh"
namespace nix {
/**
* For `adl_serializer<std::optional<T>>` below, we need to track what
* types are not already using `null`. Only for them can we use `null`
* to represent `std::nullopt`.
*/
template<typename T>
struct json_avoids_null;
/**
* Handle numbers in default impl
*/
template<typename T>
struct json_avoids_null : std::bool_constant<std::is_integral<T>::value>
{
};
template<>
struct json_avoids_null<std::nullptr_t> : std::false_type
{
};
template<>
struct json_avoids_null<bool> : std::true_type
{
};
template<>
struct json_avoids_null<std::string> : std::true_type
{
};
template<typename T>
struct json_avoids_null<std::vector<T>> : std::true_type
{
};
template<typename T>
struct json_avoids_null<std::list<T>> : std::true_type
{
};
template<typename K, typename V>
struct json_avoids_null<std::map<K, V>> : std::true_type
{
};
}

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
///@file ///@file
#include "nlohmann/json_fwd.hpp" #include <nlohmann/json_fwd.hpp>
// Following https://github.com/nlohmann/json#how-can-i-use-get-for-non-default-constructiblenon-copyable-types // Following https://github.com/nlohmann/json#how-can-i-use-get-for-non-default-constructiblenon-copyable-types
#define JSON_IMPL(TYPE) \ #define JSON_IMPL(TYPE) \

View File

@ -2,10 +2,9 @@
///@file ///@file
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <list>
#include <nlohmann/json_fwd.hpp>
#include "types.hh" #include "types.hh"
#include "json-avoids-null.hh"
namespace nix { namespace nix {
@ -39,38 +38,6 @@ Strings getStringList(const nlohmann::json & value);
StringMap getStringMap(const nlohmann::json & value); StringMap getStringMap(const nlohmann::json & value);
StringSet getStringSet(const nlohmann::json & value); StringSet getStringSet(const nlohmann::json & value);
/**
* For `adl_serializer<std::optional<T>>` below, we need to track what
* types are not already using `null`. Only for them can we use `null`
* to represent `std::nullopt`.
*/
template<typename T>
struct json_avoids_null;
/**
* Handle numbers in default impl
*/
template<typename T>
struct json_avoids_null : std::bool_constant<std::is_integral<T>::value> {};
template<>
struct json_avoids_null<std::nullptr_t> : std::false_type {};
template<>
struct json_avoids_null<bool> : std::true_type {};
template<>
struct json_avoids_null<std::string> : std::true_type {};
template<typename T>
struct json_avoids_null<std::vector<T>> : std::true_type {};
template<typename T>
struct json_avoids_null<std::list<T>> : std::true_type {};
template<typename K, typename V>
struct json_avoids_null<std::map<K, V>> : std::true_type {};
} }
namespace nlohmann { namespace nlohmann {

View File

@ -47,7 +47,15 @@ static int main_nix_copy_closure(int argc, char ** argv)
if (sshHost.empty()) if (sshHost.empty())
throw UsageError("no host name specified"); throw UsageError("no host name specified");
auto remoteUri = "ssh://" + sshHost + (gzip ? "?compress=true" : ""); StoreReference remoteUri{
.variant =
StoreReference::Specified{
.scheme = "ssh",
.authority = sshHost,
},
.params = gzip ? (StoreReference::Params{{"compress", "true"}}) : (StoreReference::Params{}),
};
auto to = toMode ? openStore(remoteUri) : openStore(); auto to = toMode ? openStore(remoteUri) : openStore();
auto from = toMode ? openStore() : openStore(remoteUri); auto from = toMode ? openStore() : openStore(remoteUri);

View File

@ -1006,7 +1006,7 @@ struct CmdFlakeClone : FlakeCommand
struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun
{ {
std::string dstUri; std::optional<StoreReference> dstUri;
CmdFlakeArchive() CmdFlakeArchive()
{ {
@ -1014,7 +1014,9 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun
.longName = "to", .longName = "to",
.description = "URI of the destination Nix store", .description = "URI of the destination Nix store",
.labels = {"store-uri"}, .labels = {"store-uri"},
.handler = {&dstUri} .handler = {[&](std::string s) {
dstUri = StoreReference::parse(s);
}},
}); });
} }
@ -1075,8 +1077,8 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun
traverse(*flake.lockFile.root); traverse(*flake.lockFile.root);
} }
if (!dryRun && !dstUri.empty()) { if (!dryRun && dstUri) {
ref<Store> dstStore = dstUri.empty() ? openStore() : openStore(dstUri); ref<Store> dstStore = openStore(*dstUri);
copyPaths(*store, *dstStore, sources); copyPaths(*store, *dstStore, sources);
} }
} }

View File

@ -18,6 +18,7 @@
#include "terminal.hh" #include "terminal.hh"
#include "users.hh" #include "users.hh"
#include "network-proxy.hh" #include "network-proxy.hh"
#include "json-utils.hh"
#include <sys/types.h> #include <sys/types.h>
#include <regex> #include <regex>
@ -224,7 +225,7 @@ static void showHelp(std::vector<std::string> subcommand, NixArgs & toplevel)
evalSettings.restrictEval = false; evalSettings.restrictEval = false;
evalSettings.pureEval = false; evalSettings.pureEval = false;
EvalState state({}, openStore("dummy://")); EvalState state({}, openStore({ .variant = StoreReference::Specified { .scheme = "dummy" } }));
auto vGenerateManpage = state.allocValue(); auto vGenerateManpage = state.allocValue();
state.eval(state.parseExprFromString( state.eval(state.parseExprFromString(
@ -400,7 +401,7 @@ void mainWrapped(int argc, char * * argv)
Xp::FetchTree, Xp::FetchTree,
}; };
evalSettings.pureEval = false; evalSettings.pureEval = false;
EvalState state({}, openStore("dummy://")); EvalState state({}, openStore({ .variant = StoreReference::Specified { .scheme = "dummy" } }));
auto res = nlohmann::json::object(); auto res = nlohmann::json::object();
res["builtins"] = ({ res["builtins"] = ({
auto builtinsJson = nlohmann::json::object(); auto builtinsJson = nlohmann::json::object();

View File

@ -30,7 +30,7 @@ struct CmdMakeContentAddressed : virtual CopyCommand, virtual StorePathsCommand,
void run(ref<Store> srcStore, StorePaths && storePaths) override void run(ref<Store> srcStore, StorePaths && storePaths) override
{ {
auto dstStore = dstUri.empty() ? openStore() : openStore(dstUri); auto dstStore = !dstUri ? openStore() : openStore(*dstUri);
auto remappings = makeContentAddressed(*srcStore, *dstStore, auto remappings = makeContentAddressed(*srcStore, *dstStore,
StorePathSet(storePaths.begin(), storePaths.end())); StorePathSet(storePaths.begin(), storePaths.end()));

View File

@ -11,7 +11,7 @@ using namespace nix;
struct CmdCopySigs : StorePathsCommand struct CmdCopySigs : StorePathsCommand
{ {
Strings substituterUris; std::vector<StoreReference> substituterUris;
CmdCopySigs() CmdCopySigs()
{ {
@ -20,7 +20,9 @@ struct CmdCopySigs : StorePathsCommand
.shortName = 's', .shortName = 's',
.description = "Copy signatures from the specified store.", .description = "Copy signatures from the specified store.",
.labels = {"store-uri"}, .labels = {"store-uri"},
.handler = {[&](std::string s) { substituterUris.push_back(s); }}, .handler = {[&](std::string s) {
substituterUris.push_back(StoreReference::parse(s));
}},
}); });
} }

View File

@ -234,10 +234,10 @@ static PeerInfo getPeerInfo(int remote)
*/ */
static ref<Store> openUncachedStore() static ref<Store> openUncachedStore()
{ {
Store::Params params; // FIXME: get params from somewhere StoreReference ref = settings.storeUri.get();
// Disable caching since the client already does that. // Disable caching since the client already does that.
params["path-info-cache-size"] = "0"; ref.params["path-info-cache-size"] = "0";
return openStore(settings.storeUri, params); return openStore(std::move(ref));
} }
/** /**

View File

@ -15,7 +15,7 @@ struct CmdVerify : StorePathsCommand
{ {
bool noContents = false; bool noContents = false;
bool noTrust = false; bool noTrust = false;
Strings substituterUris; std::vector<StoreReference> substituterUris;
size_t sigsNeeded = 0; size_t sigsNeeded = 0;
CmdVerify() CmdVerify()
@ -37,7 +37,9 @@ struct CmdVerify : StorePathsCommand
.shortName = 's', .shortName = 's',
.description = "Use signatures from the specified store.", .description = "Use signatures from the specified store.",
.labels = {"store-uri"}, .labels = {"store-uri"},
.handler = {[&](std::string s) { substituterUris.push_back(s); }} .handler = {[&](std::string s) {
substituterUris.push_back(StoreReference::parse(s));
}}
}); });
addFlag({ addFlag({

View File

@ -16,7 +16,12 @@ class LibStoreTest : public virtual ::testing::Test {
protected: protected:
LibStoreTest() LibStoreTest()
: store(openStore("dummy://")) : store(openStore({
.variant = StoreReference::Specified {
.scheme = "dummy",
.authority = "",
},
}))
{ } { }
ref<Store> store; ref<Store> store;