about summary refs log tree commit diff
path: root/third_party/nix/src/nix/ls.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/nix/src/nix/ls.cc')
-rw-r--r--third_party/nix/src/nix/ls.cc137
1 files changed, 137 insertions, 0 deletions
diff --git a/third_party/nix/src/nix/ls.cc b/third_party/nix/src/nix/ls.cc
new file mode 100644
index 0000000000..1da722babb
--- /dev/null
+++ b/third_party/nix/src/nix/ls.cc
@@ -0,0 +1,137 @@
+#include "libmain/common-args.hh"
+#include "libstore/fs-accessor.hh"
+#include "libstore/nar-accessor.hh"
+#include "libstore/store-api.hh"
+#include "libutil/json.hh"
+#include "nix/command.hh"
+
+namespace nix {
+struct MixLs : virtual Args, MixJSON {
+  std::string path;
+
+  bool recursive = false;
+  bool verbose = false;
+  bool showDirectory = false;
+
+  MixLs() {
+    mkFlag('R', "recursive", "list subdirectories recursively", &recursive);
+    mkFlag('l', "long", "show more file information", &verbose);
+    mkFlag('d', "directory", "show directories rather than their contents",
+           &showDirectory);
+  }
+
+  void listText(ref<FSAccessor> accessor) {
+    std::function<void(const FSAccessor::Stat&, const Path&, const std::string&,
+                       bool)>
+        doPath;
+
+    auto showFile = [&](const Path& curPath, const std::string& relPath) {
+      if (verbose) {
+        auto st = accessor->stat(curPath);
+        std::string tp = st.type == FSAccessor::Type::tRegular
+                             ? (st.isExecutable ? "-r-xr-xr-x" : "-r--r--r--")
+                         : st.type == FSAccessor::Type::tSymlink ? "lrwxrwxrwx"
+                                                                 : "dr-xr-xr-x";
+        std::cout << (format("%s %20d %s") % tp % st.fileSize % relPath);
+        if (st.type == FSAccessor::Type::tSymlink) {
+          std::cout << " -> " << accessor->readLink(curPath);
+        }
+        std::cout << "\n";
+        if (recursive && st.type == FSAccessor::Type::tDirectory) {
+          doPath(st, curPath, relPath, false);
+        }
+      } else {
+        std::cout << relPath << "\n";
+        if (recursive) {
+          auto st = accessor->stat(curPath);
+          if (st.type == FSAccessor::Type::tDirectory) {
+            doPath(st, curPath, relPath, false);
+          }
+        }
+      }
+    };
+
+    doPath = [&](const FSAccessor::Stat& st, const Path& curPath,
+                 const std::string& relPath, bool showDirectory) {
+      if (st.type == FSAccessor::Type::tDirectory && !showDirectory) {
+        auto names = accessor->readDirectory(curPath);
+        for (auto& name : names) {
+          showFile(curPath + "/" + name, relPath + "/" + name);
+        }
+      } else {
+        showFile(curPath, relPath);
+      }
+    };
+
+    auto st = accessor->stat(path);
+    if (st.type == FSAccessor::Type::tMissing) {
+      throw Error(format("path '%1%' does not exist") % path);
+    }
+    doPath(st, path,
+           st.type == FSAccessor::Type::tDirectory ? "." : baseNameOf(path),
+           showDirectory);
+  }
+
+  void list(const ref<FSAccessor>& accessor) {
+    if (path == "/") {
+      path = "";
+    }
+
+    if (json) {
+      JSONPlaceholder jsonRoot(std::cout);
+      listNar(jsonRoot, accessor, path, recursive);
+    } else {
+      listText(accessor);
+    }
+  }
+};
+
+struct CmdLsStore final : StoreCommand, MixLs {
+  CmdLsStore() { expectArg("path", &path); }
+
+  Examples examples() override {
+    return {
+        Example{"To list the contents of a store path in a binary cache:",
+                "nix ls-store --store https://cache.nixos.org/ -lR "
+                "/nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10"},
+    };
+  }
+
+  std::string name() override { return "ls-store"; }
+
+  std::string description() override {
+    return "show information about a store path";
+  }
+
+  void run(ref<Store> store) override { list(store->getFSAccessor()); }
+};
+
+struct CmdLsNar final : Command, MixLs {
+  Path narPath;
+
+  CmdLsNar() {
+    expectArg("nar", &narPath);
+    expectArg("path", &path);
+  }
+
+  Examples examples() override {
+    return {
+        Example{"To list a specific file in a NAR:",
+                "nix ls-nar -l hello.nar /bin/hello"},
+    };
+  }
+
+  std::string name() override { return "ls-nar"; }
+
+  std::string description() override {
+    return "show information about the contents of a NAR file";
+  }
+
+  void run() override {
+    list(makeNarAccessor(make_ref<std::string>(readFile(narPath, true))));
+  }
+};
+}  // namespace nix
+
+static nix::RegisterCommand r1(nix::make_ref<nix::CmdLsStore>());
+static nix::RegisterCommand r2(nix::make_ref<nix::CmdLsNar>());