about summary refs log tree commit diff
path: root/src/libutil/config.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/config.cc')
-rw-r--r--src/libutil/config.cc100
1 files changed, 68 insertions, 32 deletions
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index e7a810cec4d2..62c6433c741b 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -1,5 +1,6 @@
 #include "config.hh"
 #include "args.hh"
+#include "json.hh"
 
 namespace nix {
 
@@ -9,6 +10,7 @@ void Config::set(const std::string & name, const std::string & value)
     if (i == _settings.end())
         throw UsageError("unknown setting '%s'", name);
     i->second.setting->set(value);
+    i->second.setting->overriden = true;
 }
 
 void Config::addSetting(AbstractSetting * setting)
@@ -22,6 +24,7 @@ void Config::addSetting(AbstractSetting * setting)
     auto i = initials.find(setting->name);
     if (i != initials.end()) {
         setting->set(i->second);
+        setting->overriden = true;
         initials.erase(i);
         set = true;
     }
@@ -34,6 +37,7 @@ void Config::addSetting(AbstractSetting * setting)
                     alias, setting->name);
             else {
                 setting->set(i->second);
+                setting->overriden = true;
                 initials.erase(i);
                 set = true;
             }
@@ -47,11 +51,11 @@ void Config::warnUnknownSettings()
         warn("unknown setting '%s'", i.first);
 }
 
-StringMap Config::getSettings()
+StringMap Config::getSettings(bool overridenOnly)
 {
     StringMap res;
     for (auto & opt : _settings)
-        if (!opt.second.isAlias)
+        if (!opt.second.isAlias && (!overridenOnly || opt.second.setting->overriden))
             res.emplace(opt.first, opt.second.setting->to_string());
     return res;
 }
@@ -94,6 +98,23 @@ void Config::applyConfigFile(const Path & path, bool fatal)
     } catch (SysError &) { }
 }
 
+void Config::resetOverriden()
+{
+    for (auto & s : _settings)
+        s.second.setting->overriden = false;
+}
+
+void Config::toJSON(JSONObject & out)
+{
+    for (auto & s : _settings)
+        if (!s.second.isAlias) {
+            JSONObject out2(out.object(s.first));
+            out2.attr("description", s.second.setting->description);
+            JSONPlaceholder out3(out2.placeholder("value"));
+            s.second.setting->toJSON(out3);
+        }
+}
+
 AbstractSetting::AbstractSetting(
     const std::string & name,
     const std::string & description,
@@ -102,83 +123,98 @@ AbstractSetting::AbstractSetting(
 {
 }
 
-template<> void Setting<std::string>::set(const std::string & str)
+void AbstractSetting::toJSON(JSONPlaceholder & out)
+{
+    out.write(to_string());
+}
+
+template<typename T>
+void BaseSetting<T>::toJSON(JSONPlaceholder & out)
+{
+    out.write(value);
+}
+
+template<> void BaseSetting<std::string>::set(const std::string & str)
 {
     value = str;
 }
 
-template<> std::string Setting<std::string>::to_string()
+template<> std::string BaseSetting<std::string>::to_string()
 {
     return value;
 }
 
-template<typename T, typename Tag>
-void Setting<T, Tag>::set(const std::string & str)
+template<typename T>
+void BaseSetting<T>::set(const std::string & str)
 {
     static_assert(std::is_integral<T>::value, "Integer required.");
     if (!string2Int(str, value))
         throw UsageError("setting '%s' has invalid value '%s'", name, str);
 }
 
-template<typename T, typename Tag>
-std::string Setting<T, Tag>::to_string()
+template<typename T>
+std::string BaseSetting<T>::to_string()
 {
     static_assert(std::is_integral<T>::value, "Integer required.");
     return std::to_string(value);
 }
 
-bool AbstractSetting::parseBool(const std::string & str)
+template<> void BaseSetting<bool>::set(const std::string & str)
 {
     if (str == "true" || str == "yes" || str == "1")
-        return true;
+        value = true;
     else if (str == "false" || str == "no" || str == "0")
-        return false;
+        value = false;
     else
         throw UsageError("Boolean setting '%s' has invalid value '%s'", name, str);
 }
 
-template<> void Setting<bool>::set(const std::string & str)
+template<> std::string BaseSetting<bool>::to_string()
 {
-    value = parseBool(str);
+    return value ? "true" : "false";
 }
 
-std::string AbstractSetting::printBool(bool b)
+template<> void BaseSetting<Strings>::set(const std::string & str)
 {
-    return b ? "true" : "false";
+    value = tokenizeString<Strings>(str);
 }
 
-
-template<> std::string Setting<bool>::to_string()
+template<> std::string BaseSetting<Strings>::to_string()
 {
-    return printBool(value);
+    return concatStringsSep(" ", value);
 }
 
-template<> void Setting<Strings>::set(const std::string & str)
+template<> void BaseSetting<Strings>::toJSON(JSONPlaceholder & out)
 {
-    value = tokenizeString<Strings>(str);
+    JSONList list(out.list());
+    for (auto & s : value)
+        list.elem(s);
 }
 
-template<> std::string Setting<Strings>::to_string()
+template<> void BaseSetting<StringSet>::set(const std::string & str)
 {
-    return concatStringsSep(" ", value);
+    value = tokenizeString<StringSet>(str);
 }
 
-template<> void Setting<StringSet>::set(const std::string & str)
+template<> std::string BaseSetting<StringSet>::to_string()
 {
-    value = tokenizeString<StringSet>(str);
+    return concatStringsSep(" ", value);
 }
 
-template<> std::string Setting<StringSet>::to_string()
+template<> void BaseSetting<StringSet>::toJSON(JSONPlaceholder & out)
 {
-    return concatStringsSep(" ", value);
+    JSONList list(out.list());
+    for (auto & s : value)
+        list.elem(s);
 }
 
-template class Setting<int>;
-template class Setting<unsigned int>;
-template class Setting<long>;
-template class Setting<unsigned long>;
-template class Setting<long long>;
-template class Setting<unsigned long long>;
+template class BaseSetting<int>;
+template class BaseSetting<unsigned int>;
+template class BaseSetting<long>;
+template class BaseSetting<unsigned long>;
+template class BaseSetting<long long>;
+template class BaseSetting<unsigned long long>;
+template class BaseSetting<bool>;
 
 void PathSetting::set(const std::string & str)
 {