aboutsummaryrefslogtreecommitdiff
path: root/src/nix
diff options
context:
space:
mode:
authorTaeer Bar-Yam <taeer.bar-yam@tweag.io>2022-11-23 11:39:50 -0500
committerTaeer Bar-Yam <taeer.bar-yam@tweag.io>2022-11-23 11:39:50 -0500
commitb13fd4c58e81b2b2b0d72caa5ce80de861622610 (patch)
treee928cb1cbef90e2493b4b3e8b19077150d3c0140 /src/nix
parent62960f32915909a5104f2ca3a32b25fb3cfd34c7 (diff)
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.
Diffstat (limited to 'src/nix')
-rw-r--r--src/nix/why-depends.cc28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc
index 1d9ab28ba..285e36722 100644
--- a/src/nix/why-depends.cc
+++ b/src/nix/why-depends.cc
@@ -84,19 +84,35 @@ struct CmdWhyDepends : SourceExprCommand
auto package = parseInstallable(store, _package);
auto packagePath = Installable::toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, package);
auto dependency = parseInstallable(store, _dependency);
- auto dependencyPath = Installable::toStorePath(getEvalStore(), store, Realise::Derivation, operateOn, dependency);
- auto dependencyPathHash = dependencyPath.hashPart();
+ auto derivedDependency = dependency->toDerivedPath();
+ 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;
store->computeFSClosure({packagePath}, closure, false, false);
- if (!closure.count(dependencyPath)) {
- printError("'%s' does not depend on '%s'",
- store->printStorePath(packagePath),
- store->printStorePath(dependencyPath));
+ if (!optDependencyPath.has_value() || !closure.count(*optDependencyPath)) {
+ printError("'%s' does not depend on '%s'", package->what(), dependency->what());
return;
}
+ auto dependencyPath = *optDependencyPath;
+ auto dependencyPathHash = dependencyPath.hashPart();
+
stopProgressBar(); // FIXME
auto accessor = store->getFSAccessor();