diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-08-28 18:57:13 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2015-05-11 17:30:29 +0200 |
commit | 3bb89c3a31b9cf6e056f3659389e2d2e7afd17fa (patch) | |
tree | 7d0d1f76d9b6fc3369666112ee8264e95285087d | |
parent | abd9d61e6201ddbde3305dd27c286e883e950bec (diff) | |
download | guix-3bb89c3a31b9cf6e056f3659389e2d2e7afd17fa.tar.gz |
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 ];
-rw-r--r-- | nix/libstore/build.cc | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index 133ea6dbf6..6d90ce9c23 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -2350,33 +2350,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() |