aboutsummaryrefslogtreecommitdiff
path: root/src/nix
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-02-25 17:57:00 +0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2016-02-25 17:57:00 +0100
commit00b2c05749f9777a91543cad9ecafb0981389be6 (patch)
treefa6695c60ad5c4a53b3ba5e7328fdd3eb2483467 /src/nix
parent24a8f9e27bfe63d83cc7ef47c6f133904567d44e (diff)
nix: Add commands to query contents of NARs / binary caches
For example, $ NIX_REMOTE=file:///my-cache nix ls-store -lR /nix/store/f4kbgl8shhyy76rkk3nbxr0lz8d2ip7q-binutils-2.23.1 dr-xr-xr-x 0 ./bin -r-xr-xr-x 30748 ./bin/addr2line -r-xr-xr-x 66973 ./bin/ar ... Similarly, "nix ls-nar" lists the contents of a NAR file, "nix cat-nar" extracts a file from a NAR file, and "nix cat-store" extract a file from a Nix store.
Diffstat (limited to 'src/nix')
-rw-r--r--src/nix/cat.cc74
-rw-r--r--src/nix/ls.cc123
2 files changed, 197 insertions, 0 deletions
diff --git a/src/nix/cat.cc b/src/nix/cat.cc
new file mode 100644
index 000000000..2405a8cb4
--- /dev/null
+++ b/src/nix/cat.cc
@@ -0,0 +1,74 @@
+#include "command.hh"
+#include "store-api.hh"
+#include "fs-accessor.hh"
+#include "nar-accessor.hh"
+
+using namespace nix;
+
+struct MixCat : virtual Args
+{
+ std::string path;
+
+ void cat(ref<FSAccessor> accessor)
+ {
+ auto st = accessor->stat(path);
+ if (st.type == FSAccessor::Type::tMissing)
+ throw Error(format("path ‘%1%’ does not exist") % path);
+ if (st.type != FSAccessor::Type::tRegular)
+ throw Error(format("path ‘%1%’ is not a regular file") % path);
+
+ std::cout << accessor->readFile(path);
+ }
+};
+
+struct CmdCatStore : StoreCommand, MixCat
+{
+ CmdCatStore()
+ {
+ expectArg("path", &path);
+ }
+
+ std::string name() override
+ {
+ return "cat-store";
+ }
+
+ std::string description() override
+ {
+ return "print the contents of a store file on stdout";
+ }
+
+ void run(ref<Store> store) override
+ {
+ cat(store->getFSAccessor());
+ }
+};
+
+struct CmdCatNar : StoreCommand, MixCat
+{
+ Path narPath;
+
+ CmdCatNar()
+ {
+ expectArg("nar", &narPath);
+ expectArg("path", &path);
+ }
+
+ std::string name() override
+ {
+ return "cat-nar";
+ }
+
+ std::string description() override
+ {
+ return "print the contents of a file inside a NAR file";
+ }
+
+ void run(ref<Store> store) override
+ {
+ cat(makeNarAccessor(make_ref<std::string>(readFile(narPath))));
+ }
+};
+
+static RegisterCommand r1(make_ref<CmdCatStore>());
+static RegisterCommand r2(make_ref<CmdCatNar>());
diff --git a/src/nix/ls.cc b/src/nix/ls.cc
new file mode 100644
index 000000000..3476dfb05
--- /dev/null
+++ b/src/nix/ls.cc
@@ -0,0 +1,123 @@
+#include "command.hh"
+#include "store-api.hh"
+#include "fs-accessor.hh"
+#include "nar-accessor.hh"
+
+using namespace nix;
+
+struct MixLs : virtual Args
+{
+ 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 list(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);
+ }
+};
+
+struct CmdLsStore : StoreCommand, MixLs
+{
+ CmdLsStore()
+ {
+ expectArg("path", &path);
+ }
+
+ 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 : Command, MixLs
+{
+ Path narPath;
+
+ CmdLsNar()
+ {
+ expectArg("nar", &narPath);
+ expectArg("path", &path);
+ }
+
+ 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))));
+ }
+};
+
+static RegisterCommand r1(make_ref<CmdLsStore>());
+static RegisterCommand r2(make_ref<CmdLsNar>());