mirror of
https://github.com/NixOS/nix
synced 2025-06-25 19:01:16 +02:00
Merge pull request #13139 from NixOS/singleton-pattern
Simplify plugin registrations
This commit is contained in:
commit
10358c630b
13 changed files with 61 additions and 60 deletions
|
@ -14,12 +14,10 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
RegisterCommand::Commands * RegisterCommand::commands = nullptr;
|
|
||||||
|
|
||||||
nix::Commands RegisterCommand::getCommandsFor(const std::vector<std::string> & prefix)
|
nix::Commands RegisterCommand::getCommandsFor(const std::vector<std::string> & prefix)
|
||||||
{
|
{
|
||||||
nix::Commands res;
|
nix::Commands res;
|
||||||
for (auto & [name, command] : *RegisterCommand::commands)
|
for (auto & [name, command] : RegisterCommand::commands())
|
||||||
if (name.size() == prefix.size() + 1) {
|
if (name.size() == prefix.size() + 1) {
|
||||||
bool equal = true;
|
bool equal = true;
|
||||||
for (size_t i = 0; i < prefix.size(); ++i)
|
for (size_t i = 0; i < prefix.size(); ++i)
|
||||||
|
|
|
@ -285,13 +285,16 @@ struct StorePathCommand : public StorePathsCommand
|
||||||
struct RegisterCommand
|
struct RegisterCommand
|
||||||
{
|
{
|
||||||
typedef std::map<std::vector<std::string>, std::function<ref<Command>()>> Commands;
|
typedef std::map<std::vector<std::string>, std::function<ref<Command>()>> Commands;
|
||||||
static Commands * commands;
|
|
||||||
|
static Commands & commands()
|
||||||
|
{
|
||||||
|
static Commands commands;
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
|
||||||
RegisterCommand(std::vector<std::string> && name, std::function<ref<Command>()> command)
|
RegisterCommand(std::vector<std::string> && name, std::function<ref<Command>()> command)
|
||||||
{
|
{
|
||||||
if (!commands)
|
commands().emplace(name, command);
|
||||||
commands = new Commands;
|
|
||||||
commands->emplace(name, command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static nix::Commands getCommandsFor(const std::vector<std::string> & prefix);
|
static nix::Commands getCommandsFor(const std::vector<std::string> & prefix);
|
||||||
|
|
|
@ -12,12 +12,15 @@ typedef std::function<void(int, char * *)> MainFunction;
|
||||||
struct RegisterLegacyCommand
|
struct RegisterLegacyCommand
|
||||||
{
|
{
|
||||||
typedef std::map<std::string, MainFunction> Commands;
|
typedef std::map<std::string, MainFunction> Commands;
|
||||||
static Commands * commands;
|
|
||||||
|
static Commands & commands() {
|
||||||
|
static Commands commands;
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
|
||||||
RegisterLegacyCommand(const std::string & name, MainFunction fun)
|
RegisterLegacyCommand(const std::string & name, MainFunction fun)
|
||||||
{
|
{
|
||||||
if (!commands) commands = new Commands;
|
commands()[name] = fun;
|
||||||
(*commands)[name] = fun;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
#include "nix/cmd/legacy.hh"
|
|
||||||
|
|
||||||
namespace nix {
|
|
||||||
|
|
||||||
RegisterLegacyCommand::Commands * RegisterLegacyCommand::commands = 0;
|
|
||||||
|
|
||||||
}
|
|
|
@ -71,7 +71,6 @@ sources = files(
|
||||||
'installable-flake.cc',
|
'installable-flake.cc',
|
||||||
'installable-value.cc',
|
'installable-value.cc',
|
||||||
'installables.cc',
|
'installables.cc',
|
||||||
'legacy.cc',
|
|
||||||
'markdown.cc',
|
'markdown.cc',
|
||||||
'misc-store-flags.cc',
|
'misc-store-flags.cc',
|
||||||
'network-proxy.cc',
|
'network-proxy.cc',
|
||||||
|
|
|
@ -27,7 +27,12 @@ constexpr size_t conservativeStackReservation = 16;
|
||||||
struct RegisterPrimOp
|
struct RegisterPrimOp
|
||||||
{
|
{
|
||||||
typedef std::vector<PrimOp> PrimOps;
|
typedef std::vector<PrimOp> PrimOps;
|
||||||
static PrimOps * primOps;
|
|
||||||
|
static PrimOps & primOps()
|
||||||
|
{
|
||||||
|
static PrimOps primOps;
|
||||||
|
return primOps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You can register a constant by passing an arity of 0. fun
|
* You can register a constant by passing an arity of 0. fun
|
||||||
|
|
|
@ -4713,13 +4713,9 @@ static RegisterPrimOp primop_splitVersion({
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
|
||||||
|
|
||||||
RegisterPrimOp::PrimOps * RegisterPrimOp::primOps;
|
|
||||||
|
|
||||||
|
|
||||||
RegisterPrimOp::RegisterPrimOp(PrimOp && primOp)
|
RegisterPrimOp::RegisterPrimOp(PrimOp && primOp)
|
||||||
{
|
{
|
||||||
if (!primOps) primOps = new PrimOps;
|
primOps().push_back(std::move(primOp));
|
||||||
primOps->push_back(std::move(primOp));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4973,10 +4969,8 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings)
|
||||||
)",
|
)",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (RegisterPrimOp::primOps)
|
for (auto & primOp : RegisterPrimOp::primOps())
|
||||||
for (auto & primOp : *RegisterPrimOp::primOps)
|
if (experimentalFeatureSettings.isEnabled(primOp.experimentalFeature)) {
|
||||||
if (experimentalFeatureSettings.isEnabled(primOp.experimentalFeature))
|
|
||||||
{
|
|
||||||
auto primOpAdjusted = primOp;
|
auto primOpAdjusted = primOp;
|
||||||
primOpAdjusted.arity = std::max(primOp.args.size(), primOp.arity);
|
primOpAdjusted.arity = std::max(primOp.args.size(), primOp.arity);
|
||||||
addPrimOp(std::move(primOpAdjusted));
|
addPrimOp(std::move(primOpAdjusted));
|
||||||
|
|
|
@ -12,24 +12,26 @@ namespace nix::fetchers {
|
||||||
|
|
||||||
using InputSchemeMap = std::map<std::string_view, std::shared_ptr<InputScheme>>;
|
using InputSchemeMap = std::map<std::string_view, std::shared_ptr<InputScheme>>;
|
||||||
|
|
||||||
std::unique_ptr<InputSchemeMap> inputSchemes = nullptr;
|
static InputSchemeMap & inputSchemes()
|
||||||
|
{
|
||||||
|
static InputSchemeMap inputSchemeMap;
|
||||||
|
return inputSchemeMap;
|
||||||
|
}
|
||||||
|
|
||||||
void registerInputScheme(std::shared_ptr<InputScheme> && inputScheme)
|
void registerInputScheme(std::shared_ptr<InputScheme> && inputScheme)
|
||||||
{
|
{
|
||||||
if (!inputSchemes)
|
|
||||||
inputSchemes = std::make_unique<InputSchemeMap>();
|
|
||||||
auto schemeName = inputScheme->schemeName();
|
auto schemeName = inputScheme->schemeName();
|
||||||
if (inputSchemes->count(schemeName) > 0)
|
if (!inputSchemes().emplace(schemeName, std::move(inputScheme)).second)
|
||||||
throw Error("Input scheme with name %s already registered", schemeName);
|
throw Error("Input scheme with name %s already registered", schemeName);
|
||||||
inputSchemes->insert_or_assign(schemeName, std::move(inputScheme));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json dumpRegisterInputSchemeInfo() {
|
nlohmann::json dumpRegisterInputSchemeInfo()
|
||||||
|
{
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
auto res = json::object();
|
auto res = json::object();
|
||||||
|
|
||||||
for (auto & [name, scheme] : *inputSchemes) {
|
for (auto & [name, scheme] : inputSchemes()) {
|
||||||
auto & r = res[name] = json::object();
|
auto & r = res[name] = json::object();
|
||||||
r["allowedAttrs"] = scheme->allowedAttrs();
|
r["allowedAttrs"] = scheme->allowedAttrs();
|
||||||
}
|
}
|
||||||
|
@ -57,7 +59,7 @@ Input Input::fromURL(
|
||||||
const Settings & settings,
|
const Settings & settings,
|
||||||
const ParsedURL & url, bool requireTree)
|
const ParsedURL & url, bool requireTree)
|
||||||
{
|
{
|
||||||
for (auto & [_, inputScheme] : *inputSchemes) {
|
for (auto & [_, inputScheme] : inputSchemes()) {
|
||||||
auto res = inputScheme->inputFromURL(settings, url, requireTree);
|
auto res = inputScheme->inputFromURL(settings, url, requireTree);
|
||||||
if (res) {
|
if (res) {
|
||||||
experimentalFeatureSettings.require(inputScheme->experimentalFeature());
|
experimentalFeatureSettings.require(inputScheme->experimentalFeature());
|
||||||
|
@ -91,8 +93,8 @@ Input Input::fromAttrs(const Settings & settings, Attrs && attrs)
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<InputScheme> inputScheme = ({
|
std::shared_ptr<InputScheme> inputScheme = ({
|
||||||
auto i = inputSchemes->find(schemeName);
|
auto i = get(inputSchemes(), schemeName);
|
||||||
i == inputSchemes->end() ? nullptr : i->second;
|
i ? *i : nullptr;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!inputScheme) return raw();
|
if (!inputScheme) return raw();
|
||||||
|
|
|
@ -902,12 +902,11 @@ struct StoreFactory
|
||||||
|
|
||||||
struct Implementations
|
struct Implementations
|
||||||
{
|
{
|
||||||
static std::vector<StoreFactory> * registered;
|
static std::vector<StoreFactory> & registered();
|
||||||
|
|
||||||
template<typename T, typename TConfig>
|
template<typename T, typename TConfig>
|
||||||
static void add()
|
static void add()
|
||||||
{
|
{
|
||||||
if (!registered) registered = new std::vector<StoreFactory>();
|
|
||||||
StoreFactory factory{
|
StoreFactory factory{
|
||||||
.uriSchemes = TConfig::uriSchemes(),
|
.uriSchemes = TConfig::uriSchemes(),
|
||||||
.create =
|
.create =
|
||||||
|
@ -919,7 +918,7 @@ struct Implementations
|
||||||
-> std::shared_ptr<StoreConfig>
|
-> std::shared_ptr<StoreConfig>
|
||||||
{ return std::make_shared<TConfig>(StringMap({})); })
|
{ return std::make_shared<TConfig>(StringMap({})); })
|
||||||
};
|
};
|
||||||
registered->push_back(factory);
|
registered().push_back(factory);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1355,7 +1355,7 @@ ref<Store> openStore(StoreReference && storeURI)
|
||||||
return std::make_shared<LocalStore>(params);
|
return std::make_shared<LocalStore>(params);
|
||||||
},
|
},
|
||||||
[&](const StoreReference::Specified & g) {
|
[&](const StoreReference::Specified & g) {
|
||||||
for (const auto & implem : *Implementations::registered)
|
for (const auto & implem : Implementations::registered())
|
||||||
if (implem.uriSchemes.count(g.scheme))
|
if (implem.uriSchemes.count(g.scheme))
|
||||||
return implem.create(g.scheme, g.authority, params);
|
return implem.create(g.scheme, g.authority, params);
|
||||||
|
|
||||||
|
@ -1399,6 +1399,10 @@ std::list<ref<Store>> getDefaultSubstituters()
|
||||||
return stores;
|
return stores;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<StoreFactory> * Implementations::registered = 0;
|
std::vector<StoreFactory> & Implementations::registered()
|
||||||
|
{
|
||||||
|
static std::vector<StoreFactory> registered;
|
||||||
|
return registered;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace nix {
|
||||||
|
|
||||||
bool GlobalConfig::set(const std::string & name, const std::string & value)
|
bool GlobalConfig::set(const std::string & name, const std::string & value)
|
||||||
{
|
{
|
||||||
for (auto & config : *configRegistrations)
|
for (auto & config : configRegistrations())
|
||||||
if (config->set(name, value))
|
if (config->set(name, value))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -17,20 +17,20 @@ bool GlobalConfig::set(const std::string & name, const std::string & value)
|
||||||
|
|
||||||
void GlobalConfig::getSettings(std::map<std::string, SettingInfo> & res, bool overriddenOnly)
|
void GlobalConfig::getSettings(std::map<std::string, SettingInfo> & res, bool overriddenOnly)
|
||||||
{
|
{
|
||||||
for (auto & config : *configRegistrations)
|
for (auto & config : configRegistrations())
|
||||||
config->getSettings(res, overriddenOnly);
|
config->getSettings(res, overriddenOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalConfig::resetOverridden()
|
void GlobalConfig::resetOverridden()
|
||||||
{
|
{
|
||||||
for (auto & config : *configRegistrations)
|
for (auto & config : configRegistrations())
|
||||||
config->resetOverridden();
|
config->resetOverridden();
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json GlobalConfig::toJSON()
|
nlohmann::json GlobalConfig::toJSON()
|
||||||
{
|
{
|
||||||
auto res = nlohmann::json::object();
|
auto res = nlohmann::json::object();
|
||||||
for (const auto & config : *configRegistrations)
|
for (const auto & config : configRegistrations())
|
||||||
res.update(config->toJSON());
|
res.update(config->toJSON());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -47,19 +47,15 @@ std::string GlobalConfig::toKeyValue()
|
||||||
|
|
||||||
void GlobalConfig::convertToArgs(Args & args, const std::string & category)
|
void GlobalConfig::convertToArgs(Args & args, const std::string & category)
|
||||||
{
|
{
|
||||||
for (auto & config : *configRegistrations)
|
for (auto & config : configRegistrations())
|
||||||
config->convertToArgs(args, category);
|
config->convertToArgs(args, category);
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalConfig globalConfig;
|
GlobalConfig globalConfig;
|
||||||
|
|
||||||
GlobalConfig::ConfigRegistrations * GlobalConfig::configRegistrations;
|
|
||||||
|
|
||||||
GlobalConfig::Register::Register(Config * config)
|
GlobalConfig::Register::Register(Config * config)
|
||||||
{
|
{
|
||||||
if (!configRegistrations)
|
configRegistrations().emplace_back(config);
|
||||||
configRegistrations = new ConfigRegistrations;
|
|
||||||
configRegistrations->emplace_back(config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExperimentalFeatureSettings experimentalFeatureSettings;
|
ExperimentalFeatureSettings experimentalFeatureSettings;
|
||||||
|
|
|
@ -8,7 +8,12 @@ namespace nix {
|
||||||
struct GlobalConfig : public AbstractConfig
|
struct GlobalConfig : public AbstractConfig
|
||||||
{
|
{
|
||||||
typedef std::vector<Config *> ConfigRegistrations;
|
typedef std::vector<Config *> ConfigRegistrations;
|
||||||
static ConfigRegistrations * configRegistrations;
|
|
||||||
|
static ConfigRegistrations & configRegistrations()
|
||||||
|
{
|
||||||
|
static ConfigRegistrations configRegistrations;
|
||||||
|
return configRegistrations;
|
||||||
|
}
|
||||||
|
|
||||||
bool set(const std::string & name, const std::string & value) override;
|
bool set(const std::string & name, const std::string & value) override;
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs, virtual RootArgs
|
||||||
res["args"] = toJSON();
|
res["args"] = toJSON();
|
||||||
|
|
||||||
auto stores = nlohmann::json::object();
|
auto stores = nlohmann::json::object();
|
||||||
for (auto & implem : *Implementations::registered) {
|
for (auto & implem : Implementations::registered()) {
|
||||||
auto storeConfig = implem.getConfig();
|
auto storeConfig = implem.getConfig();
|
||||||
auto storeName = storeConfig->name();
|
auto storeName = storeConfig->name();
|
||||||
auto & j = stores[storeName];
|
auto & j = stores[storeName];
|
||||||
|
@ -373,7 +373,7 @@ void mainWrapped(int argc, char * * argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto legacy = (*RegisterLegacyCommand::commands)[programName];
|
auto legacy = RegisterLegacyCommand::commands()[programName];
|
||||||
if (legacy) return legacy(argc, argv);
|
if (legacy) return legacy(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue