1
0
Fork 0
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:
Jörg Thalheim 2025-05-06 09:31:09 +02:00 committed by GitHub
commit 10358c630b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 61 additions and 60 deletions

View file

@ -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)

View file

@ -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);

View file

@ -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;
} }
}; };

View file

@ -1,7 +0,0 @@
#include "nix/cmd/legacy.hh"
namespace nix {
RegisterLegacyCommand::Commands * RegisterLegacyCommand::commands = 0;
}

View file

@ -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',

View file

@ -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

View file

@ -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,14 +4969,12 @@ 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;
{ primOpAdjusted.arity = std::max(primOp.args.size(), primOp.arity);
auto primOpAdjusted = primOp; addPrimOp(std::move(primOpAdjusted));
primOpAdjusted.arity = std::max(primOp.args.size(), primOp.arity); }
addPrimOp(std::move(primOpAdjusted));
}
for (auto & primOp : evalSettings.extraPrimOps) { for (auto & primOp : evalSettings.extraPrimOps) {
auto primOpAdjusted = primOp; auto primOpAdjusted = primOp;

View file

@ -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();

View file

@ -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);
} }
}; };

View file

@ -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;
}
} }

View file

@ -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;

View file

@ -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;

View file

@ -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);
} }