aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/local-store.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-08-05 16:50:05 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-08-05 16:50:05 +0200
commite48f944e9d9c51afaef1e6aaa8328754c7cbbd7e (patch)
tree1e68391263a07e46002fdeae7ddb9ffd7f98c427 /src/libstore/local-store.cc
parent25f79121564b21ec7c84f33c9348b169f20d2bdc (diff)
parente561a13a5863f25c81e8abc9d235a12925fd454e (diff)
Merge branch 'misc-ca' of https://github.com/obsidiansystems/nix
Diffstat (limited to 'src/libstore/local-store.cc')
-rw-r--r--src/libstore/local-store.cc41
1 files changed, 28 insertions, 13 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 6b0548538..de7ddb84b 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -544,11 +544,8 @@ void LocalStore::checkDerivationOutputs(const StorePath & drvPath, const Derivat
std::string drvName(drvPath.name());
drvName = string(drvName, 0, drvName.size() - drvExtension.size());
- auto check = [&](const StorePath & expected, const StorePath & actual, const std::string & varName)
+ auto envHasRightPath = [&](const StorePath & actual, const std::string & varName)
{
- if (actual != expected)
- throw Error("derivation '%s' has incorrect output '%s', should be '%s'",
- printStorePath(drvPath), printStorePath(actual), printStorePath(expected));
auto j = drv.env.find(varName);
if (j == drv.env.end() || parseStorePath(j->second) != actual)
throw Error("derivation '%s' has incorrect environment variable '%s', should be '%s'",
@@ -556,16 +553,34 @@ void LocalStore::checkDerivationOutputs(const StorePath & drvPath, const Derivat
};
- if (drv.isFixedOutput()) {
- DerivationOutputs::const_iterator out = drv.outputs.find("out");
- if (out == drv.outputs.end())
- throw Error("derivation '%s' does not have an output named 'out'", printStorePath(drvPath));
- }
+ // Don't need the answer, but do this anyways to assert is proper
+ // combination. The code below is more general and naturally allows
+ // combinations that are currently prohibited.
+ drv.type();
- else {
- Hash h = hashDerivationModulo(*this, drv, true);
- for (auto & i : drv.outputs)
- check(makeOutputPath(i.first, h, drvName), i.second.path(*this, drv.name), i.first);
+ std::optional<Hash> h;
+ for (auto & i : drv.outputs) {
+ std::visit(overloaded {
+ [&](DerivationOutputInputAddressed doia) {
+ if (!h) {
+ // somewhat expensive so we do lazily
+ auto temp = hashDerivationModulo(*this, drv, true);
+ h = std::get<Hash>(temp);
+ }
+ StorePath recomputed = makeOutputPath(i.first, *h, drvName);
+ if (doia.path != recomputed)
+ throw Error("derivation '%s' has incorrect output '%s', should be '%s'",
+ printStorePath(drvPath), printStorePath(doia.path), printStorePath(recomputed));
+ envHasRightPath(doia.path, i.first);
+ },
+ [&](DerivationOutputCAFixed dof) {
+ StorePath path = makeFixedOutputPath(dof.hash.method, dof.hash.hash, drvName);
+ envHasRightPath(path, i.first);
+ },
+ [&](DerivationOutputCAFloating _) {
+ throw UnimplementedError("Floating CA output derivations are not yet implemented");
+ },
+ }, i.second.output);
}
}