about summary refs log tree commit diff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2011-09-14T05·59+0000
committerShea Levy <shea@shealevy.com>2011-09-14T05·59+0000
commitc172d16b00dd2126eb7c4f12c26f1e30e4356f07 (patch)
tree57fb1e12235bc9590eb62d8b3c0c3ed8230adba0 /src/libexpr/primops.cc
parent0b34e57eb80dbadd8f24426c4486af97cbfe40bf (diff)
First attempt at the output-as-derivation semantics
For each output, this adds a corresponding attribute to the derivation that is
the same as the derivation except for outPath, which is set to the path specific
to that output. Additionally, an "all" attribute is added that is a list of all
of the output derivations. This has to be done outside of derivationStrict as
each output is itself a derivation that contains itself (and all other outputs)
as an attribute. The derivation itself is equivalent to the first output in the
outputs list (or "out" if that list isn't set).
Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 0e81f7b72f..4d64bf32a6 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -1052,15 +1052,6 @@ void EvalState::createBaseEnv()
     addPrimOp("__getEnv", 1, prim_getEnv);
     addPrimOp("__trace", 2, prim_trace);
 
-    // Derivations
-    addPrimOp("derivationStrict", 1, prim_derivationStrict);
-
-    /* Add a wrapper around the derivation primop that computes the
-       `drvPath' and `outPath' attributes lazily. */
-    string s = "attrs: let res = derivationStrict attrs; in attrs // { drvPath = res.drvPath; outPath = res.outPath; type = \"derivation\"; }";
-    mkThunk_(v, parseExprFromString(s, "/"));
-    addConstant("derivation", v);
-
     // Paths
     addPrimOp("__toPath", 1, prim_toPath);
     addPrimOp("__storePath", 1, prim_storePath);
@@ -1109,6 +1100,33 @@ void EvalState::createBaseEnv()
     addPrimOp("__parseDrvName", 1, prim_parseDrvName);
     addPrimOp("__compareVersions", 2, prim_compareVersions);
 
+    // Derivations
+    addPrimOp("derivationStrict", 1, prim_derivationStrict);
+
+    /* Add a wrapper around the derivation primop that computes the
+       `drvPath' and `outPath' attributes lazily. */
+    string s = "attrs: \
+      let \
+        strict = derivationStrict attrs; \
+        attrValues = attrs: \
+          map (name: builtins.getAttr name attrs) (builtins.attrNames attrs); \
+        outputToAttrListElement = output: \
+          let outPath = builtins.getAttr (output + \"Path\") strict; in { \
+            name = output; \
+            value = attrs // { \
+              drvPath = strict.drvPath; inherit outPath; type = \"derivation\"; \
+            } // outputsAttrs // { all = allList; }; \
+          }; \
+        outputsList = if attrs ? outputs then \
+          map outputToAttrListElement attrs.outputs else \
+          [ (outputToAttrListElement \"out\") ]; \
+        outputsAttrs = builtins.listToAttrs outputsList; \
+        allList = attrValues outputsAttrs; \
+        head = if attrs ? outputs then builtins.head attrs.outputs else \"out\"; \
+      in builtins.getAttr head outputsAttrs";
+    mkThunk_(v, parseExprFromString(s, "/"));
+    addConstant("derivation", v);
+
     /* Now that we've added all primops, sort the `builtins' attribute
        set, because attribute lookups expect it to be sorted. */
     baseEnv.values[0]->attrs->sort();