diff options
author | Taeer Bar-Yam <taeer.bar-yam@tweag.io> | 2022-11-23 11:39:50 -0500 |
---|---|---|
committer | Taeer Bar-Yam <taeer.bar-yam@tweag.io> | 2022-11-23 11:39:50 -0500 |
commit | b13fd4c58e81b2b2b0d72caa5ce80de861622610 (patch) | |
tree | e928cb1cbef90e2493b4b3e8b19077150d3c0140 /src | |
parent | 62960f32915909a5104f2ca3a32b25fb3cfd34c7 (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')
-rw-r--r-- | src/nix/why-depends.cc | 28 |
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(); |