aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/misc.cc
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-07-19 14:52:35 -0400
committerJohn Ericson <John.Ericson@Obsidian.Systems>2023-07-20 15:59:52 -0400
commit6bc98c7fba9f783414692fcef41d90ed80928b6c (patch)
treec6e79f43ed32d133a62135497b35b73d6c2b1126 /src/libstore/misc.cc
parentf62543fe1cc544a5684af327f63a1aeb1bdeba94 (diff)
Give `queryPartialDerivationOutputMap` an `evalStore` parameter
This makes it more useful. In general, the derivation will be in one store, and the realisation info is in another. This also helps us avoid duplication. See how `resolveDerivedPath` is now simpler because it uses `queryPartialDerivationOutputMap`. In #8369 we get more flavors of derived path, and need more code to resolve them all, and this problem only gets worse. The fact that we need a new method to deal with the multiple dispatch is unfortunate, but this generally relates to the fact that `Store` is a sub-par interface, too bulky/unwieldy and conflating separate concerns. Solving that is out of scope of this PR. This is part of the RFC 92 work. See tracking issue #6316
Diffstat (limited to 'src/libstore/misc.cc')
-rw-r--r--src/libstore/misc.cc53
1 files changed, 22 insertions, 31 deletions
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 50336c779..14160dc8b 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -310,43 +310,34 @@ std::map<DrvOutput, StorePath> drvOutputReferences(
OutputPathMap resolveDerivedPath(Store & store, const DerivedPath::Built & bfd, Store * evalStore_)
{
- auto & evalStore = evalStore_ ? *evalStore_ : store;
+ auto outputsOpt_ = store.queryPartialDerivationOutputMap(bfd.drvPath, evalStore_);
- OutputPathMap outputs;
- auto drv = evalStore.readDerivation(bfd.drvPath);
- auto outputHashes = staticOutputHashes(store, drv);
- auto drvOutputs = drv.outputsAndOptPaths(store);
- auto outputNames = std::visit(overloaded {
+ auto outputsOpt = std::visit(overloaded {
[&](const OutputsSpec::All &) {
- StringSet names;
- for (auto & [outputName, _] : drv.outputs)
- names.insert(outputName);
- return names;
+ // Keep all outputs
+ return std::move(outputsOpt_);
},
[&](const OutputsSpec::Names & names) {
- return static_cast<std::set<std::string>>(names);
+ // Get just those mentioned by name
+ std::map<std::string, std::optional<StorePath>> outputsOpt;
+ for (auto & output : names) {
+ auto * pOutputPathOpt = get(outputsOpt_, output);
+ if (!pOutputPathOpt)
+ throw Error(
+ "the derivation '%s' doesn't have an output named '%s'",
+ store.printStorePath(bfd.drvPath), output);
+ outputsOpt.insert_or_assign(output, std::move(*pOutputPathOpt));
+ }
+ return outputsOpt;
},
}, bfd.outputs.raw());
- for (auto & output : outputNames) {
- auto outputHash = get(outputHashes, output);
- if (!outputHash)
- throw Error(
- "the derivation '%s' doesn't have an output named '%s'",
- store.printStorePath(bfd.drvPath), output);
- if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
- DrvOutput outputId { *outputHash, output };
- auto realisation = store.queryRealisation(outputId);
- if (!realisation)
- throw MissingRealisation(outputId);
- outputs.insert_or_assign(output, realisation->outPath);
- } else {
- // If ca-derivations isn't enabled, assume that
- // the output path is statically known.
- auto drvOutput = get(drvOutputs, output);
- assert(drvOutput);
- assert(drvOutput->second);
- outputs.insert_or_assign(output, *drvOutput->second);
- }
+
+ OutputPathMap outputs;
+ for (auto & [outputName, outputPathOpt] : outputsOpt) {
+ if (!outputPathOpt)
+ throw MissingRealisation(store.printStorePath(bfd.drvPath), outputName);
+ auto & outputPath = *outputPathOpt;
+ outputs.insert_or_assign(outputName, outputPath);
}
return outputs;
}