aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd/installables.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcmd/installables.cc')
-rw-r--r--src/libcmd/installables.cc47
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;
}