Fix why-depends for CA derivations
why-depends assumed that we knew the output path of the second argument. For CA derivations, we might not know until it's built. One way to solve this would be to build the second installable to get the output path. In this case we don't need to, though. If the first installable (A) depends on the second (B), then getting the store path of A will necessitate having the store path B. The contrapositive is, if the store path of B is not known (i.e. it's a CA derivation which hasn't been built), then A does not depend on B.
This commit is contained in:
parent
62960f3291
commit
b13fd4c58e
|
@ -84,19 +84,35 @@ struct CmdWhyDepends : SourceExprCommand
|
||||||
auto package = parseInstallable(store, _package);
|
auto package = parseInstallable(store, _package);
|
||||||
auto packagePath = Installable::toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, package);
|
auto packagePath = Installable::toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, package);
|
||||||
auto dependency = parseInstallable(store, _dependency);
|
auto dependency = parseInstallable(store, _dependency);
|
||||||
auto dependencyPath = Installable::toStorePath(getEvalStore(), store, Realise::Derivation, operateOn, dependency);
|
auto derivedDependency = dependency->toDerivedPath();
|
||||||
auto dependencyPathHash = dependencyPath.hashPart();
|
auto optDependencyPath = std::visit(overloaded {
|
||||||
|
[](const DerivedPath::Opaque & nodrv) -> std::optional<StorePath> {
|
||||||
|
return { nodrv.path };
|
||||||
|
},
|
||||||
|
[&](const DerivedPath::Built & hasdrv) -> std::optional<StorePath> {
|
||||||
|
if (hasdrv.outputs.size() != 1) {
|
||||||
|
throw Error("argument '%s' should evaluate to one store path", dependency->what());
|
||||||
|
}
|
||||||
|
auto outputMap = store->queryPartialDerivationOutputMap(hasdrv.drvPath);
|
||||||
|
auto maybePath = outputMap.find(*hasdrv.outputs.begin());
|
||||||
|
if (maybePath == outputMap.end()) {
|
||||||
|
throw Error("unexpected end of iterator");
|
||||||
|
}
|
||||||
|
return maybePath->second;
|
||||||
|
},
|
||||||
|
}, derivedDependency.raw());
|
||||||
|
|
||||||
StorePathSet closure;
|
StorePathSet closure;
|
||||||
store->computeFSClosure({packagePath}, closure, false, false);
|
store->computeFSClosure({packagePath}, closure, false, false);
|
||||||
|
|
||||||
if (!closure.count(dependencyPath)) {
|
if (!optDependencyPath.has_value() || !closure.count(*optDependencyPath)) {
|
||||||
printError("'%s' does not depend on '%s'",
|
printError("'%s' does not depend on '%s'", package->what(), dependency->what());
|
||||||
store->printStorePath(packagePath),
|
|
||||||
store->printStorePath(dependencyPath));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto dependencyPath = *optDependencyPath;
|
||||||
|
auto dependencyPathHash = dependencyPath.hashPart();
|
||||||
|
|
||||||
stopProgressBar(); // FIXME
|
stopProgressBar(); // FIXME
|
||||||
|
|
||||||
auto accessor = store->getFSAccessor();
|
auto accessor = store->getFSAccessor();
|
||||||
|
|
Loading…
Reference in a new issue