diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-08-28T16·57+0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-08-28T16·57+0200 |
commit | b72e93bca8fc045b37b1e863c423cf0e91e8c479 (patch) | |
tree | a989f3e94ef1ed8501b382099b6ba6c82730fd6d /src/libstore/build.cc | |
parent | 9eddf6f0b68e1ac69d56de3c5c0899481ad2c6cf (diff) |
Add disallowedReferences / disallowedRequisites
For the "stdenv accidentally referring to bootstrap-tools", it seems easier to specify the path that we don't want to depend on, e.g. disallowedRequisites = [ bootstrapTools ];
Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r-- | src/libstore/build.cc | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 6390a7480e99..0d290d7879b0 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -2318,33 +2318,36 @@ void DerivationGoal::registerOutputs() debug(format("referenced input: ‘%1%’") % *i); } - /* If the derivation specifies an `allowedReferences' - attribute (containing a list of paths that the output may - refer to), check that all references are in that list. !!! - allowedReferences should really be per-output. */ - if (drv.env.find("allowedReferences") != drv.env.end()) { - PathSet allowed = parseReferenceSpecifiers(drv, get(drv.env, "allowedReferences")); - foreach (PathSet::iterator, i, references) - if (allowed.find(*i) == allowed.end()) - throw BuildError(format("output (‘%1%’) is not allowed to refer to path ‘%2%’") % actualPath % *i); - } + /* Enforce `allowedReferences' and friends. */ + auto checkRefs = [&](const string & attrName, bool allowed, bool recursive) { + if (drv.env.find(attrName) == drv.env.end()) return; + + PathSet spec = parseReferenceSpecifiers(drv, get(drv.env, attrName)); + + PathSet used; + if (recursive) { + /* Our requisites are the union of the closures of our references. */ + for (auto & i : references) + /* Don't call computeFSClosure on ourselves. */ + if (actualPath != i) + computeFSClosure(worker.store, i, used); + } else + used = references; + + for (auto & i : used) + if (allowed) { + if (spec.find(i) == spec.end()) + throw BuildError(format("output (‘%1%’) is not allowed to refer to path ‘%2%’") % actualPath % i); + } else { + if (spec.find(i) != spec.end()) + throw BuildError(format("output (‘%1%’) is not allowed to refer to path ‘%2%’") % actualPath % i); + } + }; - /* If the derivation specifies an `allowedRequisites' - attribute (containing a list of paths that the output may - refer to), check that all requisites are in that list. !!! - allowedRequisites should really be per-output. */ - if (drv.env.find("allowedRequisites") != drv.env.end()) { - PathSet allowed = parseReferenceSpecifiers(drv, get(drv.env, "allowedRequisites")); - PathSet requisites; - /* Our requisites are the union of the closures of our references. */ - foreach (PathSet::iterator, i, references) - /* Don't call computeFSClosure on ourselves. */ - if (actualPath != *i) - computeFSClosure(worker.store, *i, requisites); - foreach (PathSet::iterator, i, requisites) - if (allowed.find(*i) == allowed.end()) - throw BuildError(format("output (‘%1%’) is not allowed to refer to requisite path ‘%2%’") % actualPath % *i); - } + checkRefs("allowedReferences", true, false); + checkRefs("allowedRequisites", true, true); + checkRefs("disallowedReferences", false, false); + checkRefs("disallowedRequisites", false, true); worker.store.optimisePath(path); // FIXME: combine with scanForReferences() |