about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-11-14T13·23+0100
committerEelco Dolstra <edolstra@gmail.com>2017-11-14T13·23+0100
commitbac8055652964d9ad5202011befb6b199463ddef (patch)
treeb37165578b2e6b5bf0c0739af636acbfa63c0be9
parentc0d93a01ee996427a1ec6b7602e655c8405624d9 (diff)
nix ls-{store,nar}: Add --json flag
-rw-r--r--src/libstore/binary-cache-store.cc35
-rw-r--r--src/libstore/nar-accessor.cc33
-rw-r--r--src/libstore/nar-accessor.hh4
-rw-r--r--src/nix/ls.cc21
4 files changed, 53 insertions, 40 deletions
diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc
index 67607ab3d43a..9c6424a496e6 100644
--- a/src/libstore/binary-cache-store.cc
+++ b/src/libstore/binary-cache-store.cc
@@ -119,42 +119,9 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
                 accessor_->addToCache(info.path, *nar);
             }
 
-            std::function<void(const Path &, JSONPlaceholder &)> recurse;
-
-            recurse = [&](const Path & path, JSONPlaceholder & res) {
-                auto st = narAccessor->stat(path);
-
-                auto obj = res.object();
-
-                switch (st.type) {
-                case FSAccessor::Type::tRegular:
-                    obj.attr("type", "regular");
-                    obj.attr("size", st.fileSize);
-                    if (st.isExecutable)
-                        obj.attr("executable", true);
-                    break;
-                case FSAccessor::Type::tDirectory:
-                    obj.attr("type", "directory");
-                    {
-                        auto res2 = obj.object("entries");
-                        for (auto & name : narAccessor->readDirectory(path)) {
-                            auto res3 = res2.placeholder(name);
-                            recurse(path + "/" + name, res3);
-                        }
-                    }
-                    break;
-                case FSAccessor::Type::tSymlink:
-                    obj.attr("type", "symlink");
-                    obj.attr("target", narAccessor->readLink(path));
-                    break;
-                default:
-                    abort();
-                }
-            };
-
             {
                 auto res = jsonRoot.placeholder("root");
-                recurse("", res);
+                listNar(res, narAccessor, "");
             }
         }
 
diff --git a/src/libstore/nar-accessor.cc b/src/libstore/nar-accessor.cc
index 2afdeb021a93..b2d15c395f10 100644
--- a/src/libstore/nar-accessor.cc
+++ b/src/libstore/nar-accessor.cc
@@ -1,5 +1,6 @@
 #include "nar-accessor.hh"
 #include "archive.hh"
+#include "json.hh"
 
 #include <map>
 #include <stack>
@@ -181,4 +182,36 @@ ref<FSAccessor> makeNarAccessor(ref<const std::string> nar)
     return make_ref<NarAccessor>(nar);
 }
 
+void listNar(JSONPlaceholder & res, ref<FSAccessor> accessor, const Path & path)
+{
+    auto st = accessor->stat(path);
+
+    auto obj = res.object();
+
+    switch (st.type) {
+    case FSAccessor::Type::tRegular:
+        obj.attr("type", "regular");
+        obj.attr("size", st.fileSize);
+        if (st.isExecutable)
+            obj.attr("executable", true);
+        break;
+    case FSAccessor::Type::tDirectory:
+        obj.attr("type", "directory");
+        {
+            auto res2 = obj.object("entries");
+            for (auto & name : accessor->readDirectory(path)) {
+                auto res3 = res2.placeholder(name);
+                listNar(res3, accessor, path + "/" + name);
+            }
+        }
+        break;
+    case FSAccessor::Type::tSymlink:
+        obj.attr("type", "symlink");
+        obj.attr("target", accessor->readLink(path));
+        break;
+    default:
+        abort();
+    }
+}
+
 }
diff --git a/src/libstore/nar-accessor.hh b/src/libstore/nar-accessor.hh
index 83c570be4c7b..7699cbbb587d 100644
--- a/src/libstore/nar-accessor.hh
+++ b/src/libstore/nar-accessor.hh
@@ -8,4 +8,8 @@ namespace nix {
    file. */
 ref<FSAccessor> makeNarAccessor(ref<const std::string> nar);
 
+class JSONPlaceholder;
+
+void listNar(JSONPlaceholder & res, ref<FSAccessor> accessor, const Path & path);
+
 }
diff --git a/src/nix/ls.cc b/src/nix/ls.cc
index 5a5fa8f62d92..8566b8b0682c 100644
--- a/src/nix/ls.cc
+++ b/src/nix/ls.cc
@@ -2,10 +2,12 @@
 #include "store-api.hh"
 #include "fs-accessor.hh"
 #include "nar-accessor.hh"
+#include "common-args.hh"
+#include "json.hh"
 
 using namespace nix;
 
-struct MixLs : virtual Args
+struct MixLs : virtual Args, MixJSON
 {
     std::string path;
 
@@ -20,7 +22,7 @@ struct MixLs : virtual Args
         mkFlag('d', "directory", "show directories rather than their contents", &showDirectory);
     }
 
-    void list(ref<FSAccessor> accessor)
+    void listText(ref<FSAccessor> accessor)
     {
         std::function<void(const FSAccessor::Stat &, const Path &, const std::string &, bool)> doPath;
 
@@ -61,10 +63,6 @@ struct MixLs : virtual Args
                 showFile(curPath, relPath);
         };
 
-        if (path == "/") {
-            path = "";
-        }
-
         auto st = accessor->stat(path);
         if (st.type == FSAccessor::Type::tMissing)
             throw Error(format("path '%1%' does not exist") % path);
@@ -72,6 +70,17 @@ struct MixLs : virtual Args
             st.type == FSAccessor::Type::tDirectory ? "." : baseNameOf(path),
             showDirectory);
     }
+
+    void list(ref<FSAccessor> accessor)
+    {
+        if (path == "/") path = "";
+
+        if (json) {
+            JSONPlaceholder jsonRoot(std::cout, true);
+            listNar(jsonRoot, accessor, path);
+        } else
+            listText(accessor);
+    }
 };
 
 struct CmdLsStore : StoreCommand, MixLs