about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--corepkgs/Makefile.am3
-rw-r--r--corepkgs/imported-drv-to-derivation.nix21
-rw-r--r--src/libexpr/primops.cc26
3 files changed, 48 insertions, 2 deletions
diff --git a/corepkgs/Makefile.am b/corepkgs/Makefile.am
index 729d15e7b191..4b0b8860be68 100644
--- a/corepkgs/Makefile.am
+++ b/corepkgs/Makefile.am
@@ -1,6 +1,7 @@
 all-local: config.nix
 
-files = nar.nix buildenv.nix buildenv.pl unpack-channel.nix unpack-channel.sh derivation.nix fetchurl.nix
+files = nar.nix buildenv.nix buildenv.pl unpack-channel.nix unpack-channel.sh derivation.nix fetchurl.nix \
+	imported-drv-to-derivation.nix
 
 install-exec-local:
 	$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs
diff --git a/corepkgs/imported-drv-to-derivation.nix b/corepkgs/imported-drv-to-derivation.nix
new file mode 100644
index 000000000000..bdb60169860a
--- /dev/null
+++ b/corepkgs/imported-drv-to-derivation.nix
@@ -0,0 +1,21 @@
+attrs @ { drvPath, outputs, ... }:
+
+let
+
+  commonAttrs = (builtins.listToAttrs outputsList) //
+    { all = map (x: x.value) outputsList;
+      inherit drvPath;
+      type = "derivation";
+    };
+
+  outputToAttrListElement = outputName:
+    { name = outputName;
+      value = commonAttrs // {
+        outPath = builtins.getAttr outputName attrs;
+        inherit outputName;
+      };
+    };
+    
+  outputsList = map outputToAttrListElement outputs;
+    
+in (builtins.head outputsList).value
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 5d5f0bfb3b5b..2ab3eda53f43 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -59,7 +59,31 @@ static void prim_import(EvalState & state, Value * * args, Value & v)
             }
     }
 
-    state.evalFile(path, v);
+    if (isStorePath(path) && store->isValidPath(path) && isDerivation(path)) {
+        Derivation drv = parseDerivation(readFile(path));
+        Value w;
+        state.mkAttrs(w, 1 + drv.outputs.size());
+        mkString(*state.allocAttr(w, state.sDrvPath), path, singleton<PathSet>("=" + path));
+        state.mkList(*state.allocAttr(w, state.symbols.create("outputs")), drv.outputs.size());
+        unsigned int outputs_index = 0;
+
+        Value * outputsVal = w.attrs->find(state.symbols.create("outputs"))->value;
+        foreach (DerivationOutputs::iterator, i, drv.outputs) {
+            mkString(*state.allocAttr(w, state.symbols.create(i->first)),
+                i->second.path, singleton<PathSet>("!" + i->first + "!" + path));
+            mkString(*(outputsVal->list.elems[outputs_index++] = state.allocValue()),
+                i->first);
+        }
+        w.attrs->sort();
+        Value fun;
+        state.mkThunk_(fun,
+            state.parseExprFromFile(state.findFile("nix/imported-drv-to-derivation.nix")));
+        state.forceFunction(fun);
+        mkApp(v, fun, w);
+        state.forceAttrs(v);
+    } else {
+        state.evalFile(path, v);
+    }
 }