aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/misc.cc
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-01-11 18:57:18 -0500
committerJohn Ericson <John.Ericson@Obsidian.Systems>2023-01-11 18:57:18 -0500
commitce2f91d356438297fd795bd3edb8f9f4536db7da (patch)
treef5bfc224151eb15fdd25f1e93b367756ff237cab /src/libstore/misc.cc
parenta7c0cff07f3e1af60bdbcd5bf7e13f8ae768da90 (diff)
Split `OutputsSpec` and `ExtendedOutputsSpec`, use the former more
`DerivedPath::Built` and `DerivationGoal` were previously using a regular set with the convention that the empty set means all outputs. But it is easy to forget about this rule when processing those sets. Using `OutputSpec` forces us to get it right.
Diffstat (limited to 'src/libstore/misc.cc')
-rw-r--r--src/libstore/misc.cc45
1 files changed, 44 insertions, 1 deletions
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index fb985c97b..1ff855cd0 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -185,7 +185,7 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
knownOutputPaths = false;
break;
}
- if (wantOutput(outputName, bfd.outputs) && !isValidPath(*pathOpt))
+ if (bfd.outputs.contains(outputName) && !isValidPath(*pathOpt))
invalid.insert(*pathOpt);
}
if (knownOutputPaths && invalid.empty()) return;
@@ -301,4 +301,47 @@ std::map<DrvOutput, StorePath> drvOutputReferences(
return drvOutputReferences(Realisation::closure(store, inputRealisations), info->references);
}
+OutputPathMap resolveDerivedPath(Store & store, const DerivedPath::Built & bfd, Store * evalStore_)
+{
+ auto & evalStore = evalStore_ ? *evalStore_ : store;
+
+ OutputPathMap outputs;
+ auto drv = evalStore.readDerivation(bfd.drvPath);
+ auto outputHashes = staticOutputHashes(store, drv);
+ auto drvOutputs = drv.outputsAndOptPaths(store);
+ auto outputNames = std::visit(overloaded {
+ [&](const OutputsSpec::All &) {
+ StringSet names;
+ for (auto & [outputName, _] : drv.outputs)
+ names.insert(outputName);
+ return names;
+ },
+ [&](const OutputsSpec::Names & names) {
+ return names;
+ },
+ }, bfd.outputs);
+ 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 (settings.isExperimentalFeatureEnabled(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);
+ }
+ }
+ return outputs;
+}
+
}