about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-04-20T15·34+0200
committerEelco Dolstra <edolstra@gmail.com>2017-04-20T15·34+0200
commitefa4bdbfcd1489527bcf6f20a49c9a3bca8bbf6b (patch)
tree0e965a2b8feb129623c221564e7ca208ce16fe2a /src
parent4410e9d995bcd53a7a4cff0bbee3917375adcba3 (diff)
Improve nix show-config --json
In particular, show descriptions. This could be used for manpage
generation etc.
Diffstat (limited to 'src')
-rw-r--r--src/libstore/globals.cc5
-rw-r--r--src/libutil/config.cc38
-rw-r--r--src/libutil/config.hh8
-rw-r--r--src/libutil/json.cc43
-rw-r--r--src/libutil/json.hh11
-rw-r--r--src/nix/show-config.cc3
6 files changed, 68 insertions, 40 deletions
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 3242ef9d63..953bf6aaaa 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -89,6 +89,11 @@ template<> std::string BaseSetting<SandboxMode>::to_string()
     else abort();
 }
 
+template<> void BaseSetting<SandboxMode>::toJSON(JSONPlaceholder & out)
+{
+    AbstractSetting::toJSON(out);
+}
+
 void MaxBuildJobsSetting::set(const std::string & str)
 {
     if (str == "auto") value = std::max(1U, std::thread::hardware_concurrency());
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index 72b6cf8068..62c6433c74 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 {
 
@@ -103,6 +104,17 @@ void Config::resetOverriden()
         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,
@@ -111,6 +123,17 @@ AbstractSetting::AbstractSetting(
 {
 }
 
+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;
@@ -161,6 +184,13 @@ template<> std::string BaseSetting<Strings>::to_string()
     return concatStringsSep(" ", value);
 }
 
+template<> void BaseSetting<Strings>::toJSON(JSONPlaceholder & out)
+{
+    JSONList list(out.list());
+    for (auto & s : value)
+        list.elem(s);
+}
+
 template<> void BaseSetting<StringSet>::set(const std::string & str)
 {
     value = tokenizeString<StringSet>(str);
@@ -171,12 +201,20 @@ template<> std::string BaseSetting<StringSet>::to_string()
     return concatStringsSep(" ", value);
 }
 
+template<> void BaseSetting<StringSet>::toJSON(JSONPlaceholder & out)
+{
+    JSONList list(out.list());
+    for (auto & s : value)
+        list.elem(s);
+}
+
 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)
 {
diff --git a/src/libutil/config.hh b/src/libutil/config.hh
index 130f59e2bd..9196210910 100644
--- a/src/libutil/config.hh
+++ b/src/libutil/config.hh
@@ -9,6 +9,8 @@ namespace nix {
 
 class Args;
 class AbstractSetting;
+class JSONPlaceholder;
+class JSONObject;
 
 /* A class to simplify providing configuration settings. The typical
    use is to inherit Config and add Setting<T> members:
@@ -56,6 +58,8 @@ public:
     void applyConfigFile(const Path & path, bool fatal = false);
 
     void resetOverriden();
+
+    void toJSON(JSONObject & out);
 };
 
 class AbstractSetting
@@ -90,6 +94,8 @@ protected:
 
     virtual std::string to_string() = 0;
 
+    virtual void toJSON(JSONPlaceholder & out);
+
     bool isOverriden() { return overriden; }
 };
 
@@ -122,6 +128,8 @@ public:
     void set(const std::string & str) override;
 
     std::string to_string() override;
+
+    void toJSON(JSONPlaceholder & out) override;
 };
 
 template<typename T>
diff --git a/src/libutil/json.cc b/src/libutil/json.cc
index 6023d1d4fb..b8b8ef9c8c 100644
--- a/src/libutil/json.cc
+++ b/src/libutil/json.cc
@@ -19,49 +19,32 @@ void toJSON(std::ostream & str, const char * start, const char * end)
     str << '"';
 }
 
-void toJSON(std::ostream & str, const std::string & s)
-{
-    toJSON(str, s.c_str(), s.c_str() + s.size());
-}
-
 void toJSON(std::ostream & str, const char * s)
 {
     if (!s) str << "null"; else toJSON(str, s, s + strlen(s));
 }
 
-void toJSON(std::ostream & str, unsigned long long n)
-{
-    str << n;
-}
-
-void toJSON(std::ostream & str, unsigned long n)
-{
-    str << n;
-}
-
-void toJSON(std::ostream & str, long n)
-{
-    str << n;
-}
+template<> void toJSON<int>(std::ostream & str, const int & n) { str << n; }
+template<> void toJSON<unsigned int>(std::ostream & str, const unsigned int & n) { str << n; }
+template<> void toJSON<long>(std::ostream & str, const long & n) { str << n; }
+template<> void toJSON<unsigned long>(std::ostream & str, const unsigned long & n) { str << n; }
+template<> void toJSON<long long>(std::ostream & str, const long long & n) { str << n; }
+template<> void toJSON<unsigned long long>(std::ostream & str, const unsigned long long & n) { str << n; }
+template<> void toJSON<float>(std::ostream & str, const float & n) { str << n; }
 
-void toJSON(std::ostream & str, unsigned int n)
+template<> void toJSON<std::string>(std::ostream & str, const std::string & s)
 {
-    str << n;
-}
-
-void toJSON(std::ostream & str, int n)
-{
-    str << n;
+    toJSON(str, s.c_str(), s.c_str() + s.size());
 }
 
-void toJSON(std::ostream & str, double f)
+template<> void toJSON<bool>(std::ostream & str, const bool & b)
 {
-    str << f;
+    str << (b ? "true" : "false");
 }
 
-void toJSON(std::ostream & str, bool b)
+template<> void toJSON<std::nullptr_t>(std::ostream & str, const std::nullptr_t & b)
 {
-    str << (b ? "true" : "false");
+    str << "null";
 }
 
 JSONWriter::JSONWriter(std::ostream & str, bool indent)
diff --git a/src/libutil/json.hh b/src/libutil/json.hh
index 03eecb7325..595e9bbe34 100644
--- a/src/libutil/json.hh
+++ b/src/libutil/json.hh
@@ -7,15 +7,10 @@
 namespace nix {
 
 void toJSON(std::ostream & str, const char * start, const char * end);
-void toJSON(std::ostream & str, const std::string & s);
 void toJSON(std::ostream & str, const char * s);
-void toJSON(std::ostream & str, unsigned long long n);
-void toJSON(std::ostream & str, unsigned long n);
-void toJSON(std::ostream & str, long n);
-void toJSON(std::ostream & str, unsigned int n);
-void toJSON(std::ostream & str, int n);
-void toJSON(std::ostream & str, double f);
-void toJSON(std::ostream & str, bool b);
+
+template<typename T>
+void toJSON(std::ostream & str, const T & n);
 
 class JSONWriter
 {
diff --git a/src/nix/show-config.cc b/src/nix/show-config.cc
index ba39e2bb29..aade2adeac 100644
--- a/src/nix/show-config.cc
+++ b/src/nix/show-config.cc
@@ -31,8 +31,7 @@ struct CmdShowConfig : Command
         if (json) {
             // FIXME: use appropriate JSON types (bool, ints, etc).
             JSONObject jsonObj(std::cout, true);
-            for (auto & s : settings.getSettings())
-                jsonObj.attr(s.first, s.second);
+            settings.toJSON(jsonObj);
         } else {
             for (auto & s : settings.getSettings())
                 std::cout << s.first + " = " + s.second + "\n";