about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-09-25T11·43+0200
committerEelco Dolstra <edolstra@gmail.com>2017-09-25T11·43+0200
commite8d6ee7c1b90a2fe6d824f1a875acc56799ae6e2 (patch)
treebbb6f9c3443aa2b25a630a84da5e3bd864c92c0f
parente350671737fc7bb1093cc89cc89ec9884dbbb6c2 (diff)
Add "nix show-derivation"
This debug command prints a store derivation in JSON format. For
example:

  $ nix show-derivation nixpkgs.hello
  {
    "/nix/store/ayjwpwwiyy04nh9z71rsdgd3q7bra7ch-hello-2.10.drv": {
      "outputs": {
        "out": {
          "path": "/nix/store/w5w4v29ql0qwqhczkdxs94ix2lh7ibgs-hello-2.10"
        }
      },
      "inputSrcs": [
        "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"
      ],
      "inputDrvs": {
        "/nix/store/13839aqdf6x4k3b785rw5f2l7857l6y3-bash-4.4-p12.drv": [
          "out"
        ],
        "/nix/store/vgdx7fdc7d4iirmnwj2py1nrvr5qwzj7-hello-2.10.tar.gz.drv": [
          "out"
        ],
        "/nix/store/x3kkd0vsqfflbvwf1055l9mr39bg0ms0-stdenv.drv": [
          "out"
        ]
      },
      "platform": "x86_64-linux",
      "builder": "/nix/store/qp5fw57d38bd1n07ss4zxh88zg67c3vg-bash-4.4-p12/bin/bash",
      "args": [
        "-e",
        "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"
      ],
      "env": {
        "buildInputs": "",
        "builder": "/nix/store/qp5fw57d38bd1n07ss4zxh88zg67c3vg-bash-4.4-p12/bin/bash",
        "configureFlags": "",
        "doCheck": "1",
        "name": "hello-2.10",
        "nativeBuildInputs": "",
        "out": "/nix/store/w5w4v29ql0qwqhczkdxs94ix2lh7ibgs-hello-2.10",
        "propagatedBuildInputs": "",
        "propagatedNativeBuildInputs": "",
        "src": "/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz",
        "stdenv": "/nix/store/6zngq1rdh0ans9qyckqimqibgnlvlfrm-stdenv",
        "system": "x86_64-linux"
      }
    }
  }

This removes the need for pp-aterm.
-rw-r--r--src/nix/command.hh4
-rw-r--r--src/nix/installables.cc24
-rw-r--r--src/nix/show-derivation.cc119
3 files changed, 147 insertions, 0 deletions
diff --git a/src/nix/command.hh b/src/nix/command.hh
index 182b01ef92e3..82400f31c078 100644
--- a/src/nix/command.hh
+++ b/src/nix/command.hh
@@ -207,4 +207,8 @@ PathSet toStorePaths(ref<Store> store, RealiseMode mode,
 Path toStorePath(ref<Store> store, RealiseMode mode,
     std::shared_ptr<Installable> installable);
 
+PathSet toDerivations(ref<Store> store,
+    std::vector<std::shared_ptr<Installable>> installables,
+    bool useDeriver = false);
+
 }
diff --git a/src/nix/installables.cc b/src/nix/installables.cc
index 76df05fa32d2..b60f71b1488b 100644
--- a/src/nix/installables.cc
+++ b/src/nix/installables.cc
@@ -303,6 +303,30 @@ Path toStorePath(ref<Store> store, RealiseMode mode,
     return *paths.begin();
 }
 
+PathSet toDerivations(ref<Store> store,
+    std::vector<std::shared_ptr<Installable>> installables, bool useDeriver)
+{
+    PathSet drvPaths;
+
+    for (auto & i : installables)
+        for (auto & b : i->toBuildables()) {
+            if (b.drvPath.empty()) {
+                if (!useDeriver)
+                    throw Error("argument '%s' did not evaluate to a derivation", i->what());
+                for (auto & output : b.outputs) {
+                    auto derivers = store->queryValidDerivers(output.second);
+                    if (derivers.empty())
+                        throw Error("'%s' does not have a known deriver", i->what());
+                    // FIXME: use all derivers?
+                    drvPaths.insert(*derivers.begin());
+                }
+            } else
+                drvPaths.insert(b.drvPath);
+        }
+
+    return drvPaths;
+}
+
 void InstallablesCommand::prepare()
 {
     installables = parseInstallables(*this, getStore(), _installables, useDefaultInstallables());
diff --git a/src/nix/show-derivation.cc b/src/nix/show-derivation.cc
new file mode 100644
index 000000000000..ee94fded364f
--- /dev/null
+++ b/src/nix/show-derivation.cc
@@ -0,0 +1,119 @@
+// FIXME: integrate this with nix path-info?
+
+#include "command.hh"
+#include "common-args.hh"
+#include "store-api.hh"
+#include "archive.hh"
+#include "json.hh"
+#include "derivations.hh"
+
+using namespace nix;
+
+struct CmdShowDerivation : InstallablesCommand
+{
+    bool recursive = false;
+
+    CmdShowDerivation()
+    {
+        mkFlag()
+            .longName("recursive")
+            .shortName('r')
+            .description("include the dependencies of the specified derivations")
+            .set(&recursive, true);
+    }
+
+    std::string name() override
+    {
+        return "show-derivation";
+    }
+
+    std::string description() override
+    {
+        return "show the contents of a store derivation";
+    }
+
+    Examples examples() override
+    {
+        return {
+            Example{
+                "To show the store derivation that results from evaluating the Hello package:",
+                "nix show-derivation nixpkgs.hello"
+            },
+            Example{
+                "To show the full derivation graph (if available) that produced your NixOS system:",
+                "nix show-derivation -r /run/current-system"
+            },
+        };
+    }
+
+    void run(ref<Store> store) override
+    {
+        auto drvPaths = toDerivations(store, installables, true);
+
+        if (recursive) {
+            PathSet closure;
+            store->computeFSClosure(drvPaths, closure);
+            drvPaths = closure;
+        }
+
+        {
+
+        JSONObject jsonRoot(std::cout, true);
+
+        for (auto & drvPath : drvPaths) {
+            if (!isDerivation(drvPath)) continue;
+
+            auto drvObj(jsonRoot.object(drvPath));
+
+            auto drv = readDerivation(drvPath);
+
+            {
+                auto outputsObj(drvObj.object("outputs"));
+                for (auto & output : drv.outputs) {
+                    auto outputObj(outputsObj.object(output.first));
+                    outputObj.attr("path", output.second.path);
+                    if (output.second.hash != "") {
+                        outputObj.attr("hashAlgo", output.second.hashAlgo);
+                        outputObj.attr("hash", output.second.hash);
+                    }
+                }
+            }
+
+            {
+                auto inputsList(drvObj.list("inputSrcs"));
+                for (auto & input : drv.inputSrcs)
+                    inputsList.elem(input);
+            }
+
+            {
+                auto inputDrvsObj(drvObj.object("inputDrvs"));
+                for (auto & input : drv.inputDrvs) {
+                    auto inputList(inputDrvsObj.list(input.first));
+                    for (auto & outputId : input.second)
+                        inputList.elem(outputId);
+                }
+            }
+
+            drvObj.attr("platform", drv.platform);
+            drvObj.attr("builder", drv.builder);
+
+            {
+                auto argsList(drvObj.list("args"));
+                for (auto & arg : drv.args)
+                    argsList.elem(arg);
+            }
+
+            {
+                auto envObj(drvObj.object("env"));
+                for (auto & var : drv.env)
+                    envObj.attr(var.first, var.second);
+            }
+        }
+
+        }
+
+        std::cout << "\n";
+    }
+};
+
+static RegisterCommand r1(make_ref<CmdShowDerivation>());