aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc32
1 files changed, 22 insertions, 10 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 6876b2853..db27b716b 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -310,16 +310,22 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
throw EvalError("required attribute `name' missing");
string drvName;
Pos & posDrvName(*attr->pos);
- try {
+ try {
drvName = state.forceStringNoCtx(*attr->value);
} catch (Error & e) {
e.addPrefix(format("while evaluating the derivation attribute `name' at %1%:\n") % posDrvName);
throw;
}
-
+
+ /* Check whether null attributes should be ignored. */
+ bool ignoreNulls = false;
+ attr = args[0]->attrs->find(state.sIgnoreNulls);
+ if (attr != args[0]->attrs->end())
+ ignoreNulls = state.forceBool(*attr->value);
+
/* Build the derivation expression by processing the attributes. */
Derivation drv;
-
+
PathSet context;
string outputHash, outputHashAlgo;
@@ -329,11 +335,17 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
outputs.insert("out");
foreach (Bindings::iterator, i, *args[0]->attrs) {
+ if (i->name == state.sIgnoreNulls) continue;
string key = i->name;
startNest(nest, lvlVomit, format("processing attribute `%1%'") % key);
try {
+ if (ignoreNulls) {
+ state.forceValue(*i->value);
+ if (i->value->type == tNull) continue;
+ }
+
/* The `args' attribute is special: it supplies the
command-line arguments to the builder. */
if (key == "args") {
@@ -358,7 +370,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
else if (key == "outputHash") outputHash = s;
else if (key == "outputHashAlgo") outputHashAlgo = s;
else if (key == "outputHashMode") {
- if (s == "recursive") outputHashRecursive = true;
+ if (s == "recursive") outputHashRecursive = true;
else if (s == "flat") outputHashRecursive = false;
else throw EvalError(format("invalid value `%1%' for `outputHashMode' attribute") % s);
}
@@ -390,13 +402,13 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
throw;
}
}
-
+
/* Everything in the context of the strings in the derivation
attributes should be added as dependencies of the resulting
derivation. */
foreach (PathSet::iterator, i, context) {
Path path = *i;
-
+
/* Paths marked with `=' denote that the path of a derivation
is explicitly passed to the builder. Since that allows the
builder to gain access to every path in the dependency
@@ -433,7 +445,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
else
drv.inputSrcs.insert(path);
}
-
+
/* Do we have all required attributes? */
if (drv.builder == "")
throw EvalError("required attribute `builder' missing");
@@ -450,14 +462,14 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
/* Handle fixed-output derivations. */
if (outputs.size() != 1 || *(outputs.begin()) != "out")
throw Error("multiple outputs are not supported in fixed-output derivations");
-
+
HashType ht = parseHashType(outputHashAlgo);
if (ht == htUnknown)
throw EvalError(format("unknown hash algorithm `%1%'") % outputHashAlgo);
Hash h = parseHash16or32(ht, outputHash);
outputHash = printHash(h);
if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo;
-
+
Path outPath = makeFixedOutputPath(outputHashRecursive, ht, h, drvName);
drv.env["out"] = outPath;
drv.outputs["out"] = DerivationOutput(outPath, outputHashAlgo, outputHash);
@@ -477,7 +489,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
/* Use the masked derivation expression to compute the output
path. */
Hash h = hashDerivationModulo(*store, drv);
-
+
foreach (DerivationOutputs::iterator, i, drv.outputs)
if (i->second.path == "") {
Path outPath = makeOutputPath(i->first, h, drvName);