about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2012-01-17T23·07+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2012-01-17T23·07+0000
commit4e624849b686894f8a4c23a56098f4d47634a85c (patch)
tree517d2938dfb90ba4a9a321084169dcadd8edd3c1
parent2a3f4110c54a10ebee67403a699cb8f951fca858 (diff)
* Added a command ‘nix-store --print-env $drvpath’ that prints out the
  environment of the given derivation in a format that can be sourced
  by the shell, e.g.

  $ eval "$(nix-store --print-env $(nix-instantiate /etc/nixos/nixpkgs -A pkg))"
  $ NIX_BUILD_TOP=/tmp
  $ source $stdenv/setup

  This is especially useful to reproduce the environment used to build
  a package outside of its builder for development purposes.

  TODO: add a nix-build option to do the above and fetch the
  dependencies of the derivation as well.

-rw-r--r--doc/manual/release-notes.xml4
-rw-r--r--src/nix-store/nix-store.cc35
2 files changed, 39 insertions, 0 deletions
diff --git a/doc/manual/release-notes.xml b/doc/manual/release-notes.xml
index 3712a8b915ac..7ef25401beaa 100644
--- a/doc/manual/release-notes.xml
+++ b/doc/manual/release-notes.xml
@@ -44,6 +44,10 @@
     <para>TODO: <command>nix-store --verify-path</command> command.</para>
   </listitem>
 
+  <listitem>
+    <para>TODO: <command>nix-store --print-env</command> command.</para>
+  </listitem>
+
 </itemizedlist>
 
 </section>
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index b9f8d927a3a6..2e1d3f044bf5 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -382,6 +382,39 @@ static void opQuery(Strings opFlags, Strings opArgs)
 }
 
 
+static string shellEscape(const string & s)
+{
+    string r;
+    foreach (string::const_iterator, i, s)
+        if (*i == '\'') r += "'\\''"; else r += *i;
+    return r;
+}
+
+
+static void opPrintEnv(Strings opFlags, Strings opArgs)
+{
+    if (!opFlags.empty()) throw UsageError("unknown flag");
+    if (opArgs.size() != 1) throw UsageError("`--print-env' requires one derivation store path");
+
+    Path drvPath = opArgs.front();
+    Derivation drv = derivationFromPath(*store, drvPath);
+
+    /* Print each environment variable in the derivation in a format
+       that can be sourced by the shell. */
+    foreach (StringPairs::iterator, i, drv.env)
+        cout << format("export %1%; %1%='%2%'\n") % i->first % shellEscape(i->second);
+
+    /* Also output the arguments.  This doesn't preserve whitespace in
+       arguments. */
+    cout << "export _args; _args='";
+    foreach (Strings::iterator, i, drv.args) {
+        if (i != drv.args.begin()) cout << ' ';
+        cout << shellEscape(*i);
+    }
+    cout << "'\n";
+}
+
+
 static void opReadLog(Strings opFlags, Strings opArgs)
 {
     if (!opFlags.empty()) throw UsageError("unknown flag");
@@ -754,6 +787,8 @@ void run(Strings args)
             op = opDelete;
         else if (arg == "--query" || arg == "-q")
             op = opQuery;
+        else if (arg == "--print-env")
+            op = opPrintEnv;
         else if (arg == "--read-log" || arg == "-l")
             op = opReadLog;
         else if (arg == "--dump-db")