diff options
Diffstat (limited to 'src/libcmd/installables.cc')
-rw-r--r-- | src/libcmd/installables.cc | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 4e6bf4a9a..9ad02b5f0 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -704,23 +704,42 @@ Buildables build(ref<Store> store, Realise mode, return buildables; } -StorePathSet toStorePaths(ref<Store> store, - Realise mode, OperateOn operateOn, +std::set<RealisedPath> toRealisedPaths( + ref<Store> store, + Realise mode, + OperateOn operateOn, std::vector<std::shared_ptr<Installable>> installables) { - StorePathSet outPaths; - + std::set<RealisedPath> res; if (operateOn == OperateOn::Output) { for (auto & b : build(store, mode, installables)) std::visit(overloaded { [&](BuildableOpaque bo) { - outPaths.insert(bo.path); + res.insert(bo.path); }, [&](BuildableFromDrv bfd) { + auto drv = store->readDerivation(bfd.drvPath); + auto outputHashes = staticOutputHashes(*store, drv); for (auto & output : bfd.outputs) { - if (!output.second) - throw Error("Cannot operate on output of unbuilt CA drv"); - outPaths.insert(*output.second); + if (settings.isExperimentalFeatureEnabled("ca-derivations")) { + if (!outputHashes.count(output.first)) + throw Error( + "the derivation '%s' doesn't have an output named '%s'", + store->printStorePath(bfd.drvPath), + output.first); + auto outputId = DrvOutput{outputHashes.at(output.first), output.first}; + auto realisation = store->queryRealisation(outputId); + if (!realisation) + throw Error("cannot operate on an output of unbuilt content-addresed derivation '%s'", outputId.to_string()); + res.insert(RealisedPath{*realisation}); + } + else { + // If ca-derivations isn't enabled, behave as if + // all the paths are opaque to keep the default + // behavior + assert(output.second); + res.insert(*output.second); + } } }, }, b); @@ -731,9 +750,19 @@ StorePathSet toStorePaths(ref<Store> store, for (auto & i : installables) for (auto & b : i->toBuildables()) if (auto bfd = std::get_if<BuildableFromDrv>(&b)) - outPaths.insert(bfd->drvPath); + res.insert(bfd->drvPath); } + return res; +} + +StorePathSet toStorePaths(ref<Store> store, + Realise mode, OperateOn operateOn, + std::vector<std::shared_ptr<Installable>> installables) +{ + StorePathSet outPaths; + for (auto & path : toRealisedPaths(store, mode, operateOn, installables)) + outPaths.insert(path.path()); return outPaths; } |