aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/archive.cc26
-rw-r--r--src/libutil/archive.hh4
-rw-r--r--src/libutil/config.cc88
-rw-r--r--src/libutil/config.hh81
4 files changed, 150 insertions, 49 deletions
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc
index 154e2d204..1be8934a2 100644
--- a/src/libutil/archive.cc
+++ b/src/libutil/archive.cc
@@ -13,17 +13,25 @@
#include "archive.hh"
#include "util.hh"
-
+#include "config.hh"
namespace nix {
+struct ArchiveSettings : Config
+{
+ Setting<bool> useCaseHack{this,
+ #if __APPLE__
+ true,
+ #else
+ false,
+ #endif
+ "use-case-hack",
+ "Whether to enable a Darwin-specific hack for dealing with file name collisions."};
+};
-bool useCaseHack =
-#if __APPLE__
- true;
-#else
- false;
-#endif
+static ArchiveSettings archiveSettings;
+
+static GlobalConfig::Register r1(&archiveSettings);
const std::string narVersionMagic1 = "nix-archive-1";
@@ -78,7 +86,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
the case hack applied by restorePath(). */
std::map<string, string> unhacked;
for (auto & i : readDirectory(path))
- if (useCaseHack) {
+ if (archiveSettings.useCaseHack) {
string name(i.name);
size_t pos = i.name.find(caseHackSuffix);
if (pos != string::npos) {
@@ -243,7 +251,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
if (name <= prevName)
throw Error("NAR directory is not sorted");
prevName = name;
- if (useCaseHack) {
+ if (archiveSettings.useCaseHack) {
auto i = names.find(name);
if (i != names.end()) {
debug(format("case collision between '%1%' and '%2%'") % i->first % name);
diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh
index 7a0e688e4..25be426c1 100644
--- a/src/libutil/archive.hh
+++ b/src/libutil/archive.hh
@@ -78,10 +78,6 @@ void restorePath(const Path & path, Source & source);
void copyNAR(Source & source, Sink & sink);
-// FIXME: global variables are bad m'kay.
-extern bool useCaseHack;
-
-
extern const std::string narVersionMagic1;
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);
+}
+
}
diff --git a/src/libutil/config.hh b/src/libutil/config.hh
index d2e7faf17..d86c65ff0 100644
--- a/src/libutil/config.hh
+++ b/src/libutil/config.hh
@@ -12,6 +12,40 @@ class AbstractSetting;
class JSONPlaceholder;
class JSONObject;
+class AbstractConfig
+{
+protected:
+ StringMap unknownSettings;
+
+ AbstractConfig(const StringMap & initials = {})
+ : unknownSettings(initials)
+ { }
+
+public:
+
+ virtual bool set(const std::string & name, const std::string & value) = 0;
+
+ struct SettingInfo
+ {
+ std::string value;
+ std::string description;
+ };
+
+ virtual void getSettings(std::map<std::string, SettingInfo> & res, bool overridenOnly = false) = 0;
+
+ void applyConfigFile(const Path & path);
+
+ virtual void resetOverriden() = 0;
+
+ virtual void toJSON(JSONObject & out) = 0;
+
+ virtual void convertToArgs(Args & args, const std::string & category) = 0;
+
+ void warnUnknownSettings();
+
+ void reapplyUnknownSettings();
+};
+
/* A class to simplify providing configuration settings. The typical
use is to inherit Config and add Setting<T> members:
@@ -27,7 +61,7 @@ class JSONObject;
};
*/
-class Config
+class Config : public AbstractConfig
{
friend class AbstractSetting;
@@ -48,31 +82,23 @@ private:
Settings _settings;
- StringMap extras;
-
public:
- Config(const StringMap & initials)
- : extras(initials)
+ Config(const StringMap & initials = {})
+ : AbstractConfig(initials)
{ }
- void set(const std::string & name, const std::string & value);
+ bool set(const std::string & name, const std::string & value) override;
void addSetting(AbstractSetting * setting);
- void handleUnknownSettings();
-
- StringMap getSettings(bool overridenOnly = false);
+ void getSettings(std::map<std::string, SettingInfo> & res, bool overridenOnly = false) override;
- const Settings & _getSettings() { return _settings; }
-
- void applyConfigFile(const Path & path);
+ void resetOverriden() override;
- void resetOverriden();
+ void toJSON(JSONObject & out) override;
- void toJSON(JSONObject & out);
-
- void convertToArgs(Args & args, const std::string & category);
+ void convertToArgs(Args & args, const std::string & category) override;
};
class AbstractSetting
@@ -209,4 +235,27 @@ public:
void operator =(const Path & v) { this->assign(v); }
};
+struct GlobalConfig : public AbstractConfig
+{
+ typedef std::vector<Config*> ConfigRegistrations;
+ static ConfigRegistrations * configRegistrations;
+
+ bool set(const std::string & name, const std::string & value) override;
+
+ void getSettings(std::map<std::string, SettingInfo> & res, bool overridenOnly = false) override;
+
+ void resetOverriden() override;
+
+ void toJSON(JSONObject & out) override;
+
+ void convertToArgs(Args & args, const std::string & category) override;
+
+ struct Register
+ {
+ Register(Config * config);
+ };
+};
+
+extern GlobalConfig globalConfig;
+
}