about summary refs log tree commit diff
path: root/third_party/nix/src/nix-instantiate/nix-instantiate.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/nix/src/nix-instantiate/nix-instantiate.cc')
-rw-r--r--third_party/nix/src/nix-instantiate/nix-instantiate.cc219
1 files changed, 219 insertions, 0 deletions
diff --git a/third_party/nix/src/nix-instantiate/nix-instantiate.cc b/third_party/nix/src/nix-instantiate/nix-instantiate.cc
new file mode 100644
index 000000000000..236037299d8b
--- /dev/null
+++ b/third_party/nix/src/nix-instantiate/nix-instantiate.cc
@@ -0,0 +1,219 @@
+#include <iostream>
+#include <map>
+
+#include "libexpr/attr-path.hh"
+#include "libexpr/common-eval-args.hh"
+#include "libexpr/eval-inline.hh"
+#include "libexpr/eval.hh"
+#include "libexpr/get-drvs.hh"
+#include "libexpr/value-to-json.hh"
+#include "libexpr/value-to-xml.hh"
+#include "libmain/shared.hh"
+#include "libstore/globals.hh"
+#include "libstore/store-api.hh"
+#include "libutil/util.hh"
+#include "nix/legacy.hh"
+
+using namespace nix;
+
+static Path gcRoot;
+static int rootNr = 0;
+static bool indirectRoot = false;
+
+enum OutputKind { okPlain, okXML, okJSON };
+
+void processExpr(EvalState& state, const Strings& attrPaths, bool parseOnly,
+                 bool strict, Bindings* autoArgs, bool evalOnly,
+                 OutputKind output, bool location, Expr* e) {
+  if (parseOnly) {
+    std::cout << format("%1%\n") % *e;
+    return;
+  }
+
+  Value vRoot;
+  state.eval(e, vRoot);
+
+  for (auto& i : attrPaths) {
+    Value& v(*findAlongAttrPath(state, i, autoArgs, vRoot));
+    state.forceValue(v);
+
+    PathSet context;
+    if (evalOnly) {
+      Value vRes;
+      if (autoArgs->empty()) {
+        vRes = v;
+      } else {
+        state.autoCallFunction(autoArgs, v, vRes);
+      }
+      if (output == okXML) {
+        printValueAsXML(state, strict, location, vRes, std::cout, context);
+      } else if (output == okJSON) {
+        printValueAsJSON(state, strict, vRes, std::cout, context);
+      } else {
+        if (strict) {
+          state.forceValueDeep(vRes);
+        }
+        std::cout << vRes << std::endl;
+      }
+    } else {
+      DrvInfos drvs;
+      getDerivations(state, v, "", autoArgs, drvs, false);
+      for (auto& i : drvs) {
+        Path drvPath = i.queryDrvPath();
+
+        /* What output do we want? */
+        std::string outputName = i.queryOutputName();
+        if (outputName.empty()) {
+          throw Error(
+              format("derivation '%1%' lacks an 'outputName' attribute ") %
+              drvPath);
+        }
+
+        if (gcRoot.empty()) {
+          printGCWarning();
+        } else {
+          Path rootName = indirectRoot ? absPath(gcRoot) : gcRoot;
+          if (++rootNr > 1) {
+            rootName += "-" + std::to_string(rootNr);
+          }
+          auto store2 = state.store.dynamic_pointer_cast<LocalFSStore>();
+          if (store2) {
+            drvPath = store2->addPermRoot(drvPath, rootName, indirectRoot);
+          }
+        }
+        std::cout << format("%1%%2%\n") % drvPath %
+                         (outputName != "out" ? "!" + outputName : "");
+      }
+    }
+  }
+}
+
+static int _main(int argc, char** argv) {
+  {
+    Strings files;
+    bool readStdin = false;
+    bool fromArgs = false;
+    bool findFile = false;
+    bool evalOnly = false;
+    bool parseOnly = false;
+    bool traceFileAccess = false;
+    OutputKind outputKind = okPlain;
+    bool xmlOutputSourceLocation = true;
+    bool strict = false;
+    Strings attrPaths;
+    bool wantsReadWrite = false;
+    RepairFlag repair = NoRepair;
+
+    struct MyArgs : LegacyArgs, MixEvalArgs {
+      using LegacyArgs::LegacyArgs;
+    };
+
+    MyArgs myArgs(baseNameOf(argv[0]),
+                  [&](Strings::iterator& arg, const Strings::iterator& end) {
+                    if (*arg == "--help") {
+                      showManPage("nix-instantiate");
+                    } else if (*arg == "--version") {
+                      printVersion("nix-instantiate");
+                    } else if (*arg == "-") {
+                      readStdin = true;
+                    } else if (*arg == "--expr" || *arg == "-E") {
+                      fromArgs = true;
+                    } else if (*arg == "--eval" || *arg == "--eval-only") {
+                      evalOnly = true;
+                    } else if (*arg == "--read-write-mode") {
+                      wantsReadWrite = true;
+                    } else if (*arg == "--parse" || *arg == "--parse-only") {
+                      parseOnly = evalOnly = true;
+                    } else if (*arg == "--find-file") {
+                      findFile = true;
+                    } else if (*arg == "--attr" || *arg == "-A") {
+                      attrPaths.push_back(getArg(*arg, arg, end));
+                    } else if (*arg == "--add-root") {
+                      gcRoot = getArg(*arg, arg, end);
+                    } else if (*arg == "--indirect") {
+                      indirectRoot = true;
+                    } else if (*arg == "--xml") {
+                      outputKind = okXML;
+                    } else if (*arg == "--json") {
+                      outputKind = okJSON;
+                    } else if (*arg == "--no-location") {
+                      xmlOutputSourceLocation = false;
+                    } else if (*arg == "--strict") {
+                      strict = true;
+                    } else if (*arg == "--repair") {
+                      repair = Repair;
+                    } else if (*arg == "--dry-run") {
+                      settings.readOnlyMode = true;
+                    } else if (*arg == "--trace-file-access") {
+                      traceFileAccess = true;
+                    } else if (*arg == "--trace-file-access=true") {
+                      traceFileAccess = true;
+                    } else if (*arg == "--trace-file-access=false") {
+                      traceFileAccess = false;
+                    } else if (*arg == "--notrace-file-access") {
+                      traceFileAccess = false;
+                    } else if (*arg != "" && arg->at(0) == '-') {
+                      return false;
+                    } else {
+                      files.push_back(*arg);
+                    }
+                    return true;
+                  });
+
+    myArgs.parseCmdline(argvToStrings(argc, argv));
+
+    if (evalOnly && !wantsReadWrite) {
+      settings.readOnlyMode = true;
+    }
+
+    auto store = openStore();
+
+    auto state = std::make_unique<EvalState>(myArgs.searchPath, store);
+    state->repair = repair;
+    if (traceFileAccess) {
+      state->EnableFileAccessTracing([](const Path& path) {
+        std::cerr << "trace: depot-scan: " << path << "\n";
+      });
+    }
+
+    std::unique_ptr<Bindings> autoArgs = myArgs.getAutoArgs(*state);
+
+    if (attrPaths.empty()) {
+      attrPaths = {""};
+    }
+
+    if (findFile) {
+      for (auto& i : files) {
+        Path p = state->findFile(i);
+        if (p.empty()) {
+          throw Error(format("unable to find '%1%'") % i);
+        }
+        std::cout << p << std::endl;
+      }
+      return 0;
+    }
+
+    if (readStdin) {
+      Expr* e = state->parseStdin();
+      processExpr(*state, attrPaths, parseOnly, strict, autoArgs.get(),
+                  evalOnly, outputKind, xmlOutputSourceLocation, e);
+    } else if (files.empty() && !fromArgs) {
+      files.push_back("./default.nix");
+    }
+
+    for (auto& i : files) {
+      Expr* e = fromArgs
+                    ? state->parseExprFromString(i, absPath("."))
+                    : state->parseExprFromFile(resolveExprPath(
+                          state->checkSourcePath(lookupFileArg(*state, i))));
+      processExpr(*state, attrPaths, parseOnly, strict, autoArgs.get(),
+                  evalOnly, outputKind, xmlOutputSourceLocation, e);
+    }
+
+    state->printStats();
+
+    return 0;
+  }
+}
+
+static RegisterLegacyCommand s1("nix-instantiate", _main);