aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/config.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/config.cc')
-rw-r--r--src/libutil/config.cc80
1 files changed, 62 insertions, 18 deletions
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index 521733025..7467e5ac0 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -8,9 +8,18 @@ namespace nix {
bool Config::set(const std::string & name, const std::string & value)
{
+ bool append = false;
auto i = _settings.find(name);
- if (i == _settings.end()) return false;
- i->second.setting->set(value);
+ if (i == _settings.end()) {
+ if (hasPrefix(name, "extra-")) {
+ i = _settings.find(std::string(name, 6));
+ if (i == _settings.end() || !i->second.setting->isAppendable())
+ return false;
+ append = true;
+ } else
+ return false;
+ }
+ i->second.setting->set(value, append);
i->second.setting->overriden = true;
return true;
}
@@ -181,18 +190,33 @@ void AbstractSetting::convertToArg(Args & args, const std::string & category)
}
template<typename T>
+bool BaseSetting<T>::isAppendable()
+{
+ return false;
+}
+
+template<typename T>
void BaseSetting<T>::convertToArg(Args & args, const std::string & category)
{
args.addFlag({
.longName = name,
- .description = description,
+ .description = fmt("Set the `%s` setting.", name),
.category = category,
.labels = {"value"},
.handler = {[=](std::string s) { overriden = true; set(s); }},
});
+
+ if (isAppendable())
+ args.addFlag({
+ .longName = "extra-" + name,
+ .description = fmt("Append to the `%s` setting.", name),
+ .category = category,
+ .labels = {"value"},
+ .handler = {[=](std::string s) { overriden = true; set(s, true); }},
+ });
}
-template<> void BaseSetting<std::string>::set(const std::string & str)
+template<> void BaseSetting<std::string>::set(const std::string & str, bool append)
{
value = str;
}
@@ -203,10 +227,12 @@ template<> std::string BaseSetting<std::string>::to_string() const
}
template<typename T>
-void BaseSetting<T>::set(const std::string & str)
+void BaseSetting<T>::set(const std::string & str, bool append)
{
static_assert(std::is_integral<T>::value, "Integer required.");
- if (!string2Int(str, value))
+ if (auto n = string2Int<T>(str))
+ value = *n;
+ else
throw UsageError("setting '%s' has invalid value '%s'", name, str);
}
@@ -217,7 +243,7 @@ std::string BaseSetting<T>::to_string() const
return std::to_string(value);
}
-template<> void BaseSetting<bool>::set(const std::string & str)
+template<> void BaseSetting<bool>::set(const std::string & str, bool append)
{
if (str == "true" || str == "yes" || str == "1")
value = true;
@@ -236,21 +262,28 @@ template<> void BaseSetting<bool>::convertToArg(Args & args, const std::string &
{
args.addFlag({
.longName = name,
- .description = description,
+ .description = fmt("Enable the `%s` setting.", name),
.category = category,
.handler = {[=]() { override(true); }}
});
args.addFlag({
.longName = "no-" + name,
- .description = description,
+ .description = fmt("Disable the `%s` setting.", name),
.category = category,
.handler = {[=]() { override(false); }}
});
}
-template<> void BaseSetting<Strings>::set(const std::string & str)
+template<> void BaseSetting<Strings>::set(const std::string & str, bool append)
+{
+ auto ss = tokenizeString<Strings>(str);
+ if (!append) value.clear();
+ for (auto & s : ss) value.push_back(std::move(s));
+}
+
+template<> bool BaseSetting<Strings>::isAppendable()
{
- value = tokenizeString<Strings>(str);
+ return true;
}
template<> std::string BaseSetting<Strings>::to_string() const
@@ -258,9 +291,16 @@ template<> std::string BaseSetting<Strings>::to_string() const
return concatStringsSep(" ", value);
}
-template<> void BaseSetting<StringSet>::set(const std::string & str)
+template<> void BaseSetting<StringSet>::set(const std::string & str, bool append)
+{
+ if (!append) value.clear();
+ for (auto & s : tokenizeString<StringSet>(str))
+ value.insert(s);
+}
+
+template<> bool BaseSetting<StringSet>::isAppendable()
{
- value = tokenizeString<StringSet>(str);
+ return true;
}
template<> std::string BaseSetting<StringSet>::to_string() const
@@ -268,11 +308,10 @@ template<> std::string BaseSetting<StringSet>::to_string() const
return concatStringsSep(" ", value);
}
-template<> void BaseSetting<StringMap>::set(const std::string & str)
+template<> void BaseSetting<StringMap>::set(const std::string & str, bool append)
{
- auto kvpairs = tokenizeString<Strings>(str);
- for (auto & s : kvpairs)
- {
+ if (!append) value.clear();
+ for (auto & s : tokenizeString<Strings>(str)) {
auto eq = s.find_first_of('=');
if (std::string::npos != eq)
value.emplace(std::string(s, 0, eq), std::string(s, eq + 1));
@@ -280,6 +319,11 @@ template<> void BaseSetting<StringMap>::set(const std::string & str)
}
}
+template<> bool BaseSetting<StringMap>::isAppendable()
+{
+ return true;
+}
+
template<> std::string BaseSetting<StringMap>::to_string() const
{
Strings kvstrs;
@@ -300,7 +344,7 @@ template class BaseSetting<Strings>;
template class BaseSetting<StringSet>;
template class BaseSetting<StringMap>;
-void PathSetting::set(const std::string & str)
+void PathSetting::set(const std::string & str, bool append)
{
if (str == "") {
if (allowEmpty)