aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/config.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2018-03-27 18:41:31 +0200
committerEelco Dolstra <edolstra@gmail.com>2018-05-30 13:28:01 +0200
commit737ed88f35ffddb2cb0d5e4b192e20a7b9439682 (patch)
tree1ac3d1cfa751d5745a9c8ffe9d4ec5404ef211d5 /src/libutil/config.cc
parente606cd412f6ad0622feff55dc2a023dc4b2fe238 (diff)
Modularize config settings
Allow global config settings to be defined in multiple Config classes. For example, this means that libutil can have settings and evaluator settings can be moved out of libstore. The Config classes are registered in a new GlobalConfig class to which config files etc. are applied. Relevant to https://github.com/NixOS/nix/issues/2009 in that it removes the need for ad hoc handling of useCaseHack, which was the underlying cause of that issue.
Diffstat (limited to 'src/libutil/config.cc')
-rw-r--r--src/libutil/config.cc88
1 files changed, 68 insertions, 20 deletions
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index ce6858f0d..9023cb1bb 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -4,15 +4,13 @@
namespace nix {
-void Config::set(const std::string & name, const std::string & value)
+bool Config::set(const std::string & name, const std::string & value)
{
auto i = _settings.find(name);
- if (i == _settings.end()) {
- extras.emplace(name, value);
- } else {
- i->second.setting->set(value);
- i->second.setting->overriden = true;
- }
+ if (i == _settings.end()) return false;
+ i->second.setting->set(value);
+ i->second.setting->overriden = true;
+ return true;
}
void Config::addSetting(AbstractSetting * setting)
@@ -23,46 +21,51 @@ void Config::addSetting(AbstractSetting * setting)
bool set = false;
- auto i = extras.find(setting->name);
- if (i != extras.end()) {
+ auto i = unknownSettings.find(setting->name);
+ if (i != unknownSettings.end()) {
setting->set(i->second);
setting->overriden = true;
- extras.erase(i);
+ unknownSettings.erase(i);
set = true;
}
for (auto & alias : setting->aliases) {
- auto i = extras.find(alias);
- if (i != extras.end()) {
+ auto i = unknownSettings.find(alias);
+ if (i != unknownSettings.end()) {
if (set)
warn("setting '%s' is set, but it's an alias of '%s' which is also set",
alias, setting->name);
else {
setting->set(i->second);
setting->overriden = true;
- extras.erase(i);
+ unknownSettings.erase(i);
set = true;
}
}
}
}
-void Config::handleUnknownSettings()
+void AbstractConfig::warnUnknownSettings()
{
- for (auto & s : extras)
+ for (auto & s : unknownSettings)
warn("unknown setting '%s'", s.first);
}
-StringMap Config::getSettings(bool overridenOnly)
+void AbstractConfig::reapplyUnknownSettings()
+{
+ auto unknownSettings2 = std::move(unknownSettings);
+ for (auto & s : unknownSettings2)
+ set(s.first, s.second);
+}
+
+void Config::getSettings(std::map<std::string, SettingInfo> & res, bool overridenOnly)
{
- StringMap res;
for (auto & opt : _settings)
if (!opt.second.isAlias && (!overridenOnly || opt.second.setting->overriden))
- res.emplace(opt.first, opt.second.setting->to_string());
- return res;
+ res.emplace(opt.first, SettingInfo{opt.second.setting->to_string(), opt.second.setting->description});
}
-void Config::applyConfigFile(const Path & path)
+void AbstractConfig::applyConfigFile(const Path & path)
{
try {
string contents = readFile(path);
@@ -287,4 +290,49 @@ void PathSetting::set(const std::string & str)
value = canonPath(str);
}
+bool GlobalConfig::set(const std::string & name, const std::string & value)
+{
+ for (auto & config : *configRegistrations)
+ if (config->set(name, value)) return true;
+
+ unknownSettings.emplace(name, value);
+
+ return false;
+}
+
+void GlobalConfig::getSettings(std::map<std::string, SettingInfo> & res, bool overridenOnly)
+{
+ for (auto & config : *configRegistrations)
+ config->getSettings(res, overridenOnly);
+}
+
+void GlobalConfig::resetOverriden()
+{
+ for (auto & config : *configRegistrations)
+ config->resetOverriden();
+}
+
+void GlobalConfig::toJSON(JSONObject & out)
+{
+ for (auto & config : *configRegistrations)
+ config->toJSON(out);
+}
+
+void GlobalConfig::convertToArgs(Args & args, const std::string & category)
+{
+ for (auto & config : *configRegistrations)
+ config->convertToArgs(args, category);
+}
+
+GlobalConfig globalConfig;
+
+GlobalConfig::ConfigRegistrations * GlobalConfig::configRegistrations;
+
+GlobalConfig::Register::Register(Config * config)
+{
+ if (!configRegistrations)
+ configRegistrations = new ConfigRegistrations;
+ configRegistrations->emplace_back(config);
+}
+
}