aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorThéophane Hufschmitt <7226587+thufschmitt@users.noreply.github.com>2023-05-10 14:30:42 +0200
committerGitHub <noreply@github.com>2023-05-10 14:30:42 +0200
commit85ff21205104a475c8745c5919aa1378dd49ecad (patch)
tree74a75e8b98b0e06a5d4fd28e6999a510f670e121 /src/libstore
parentaacde38d2c8a0cf159794e5ec87ef63dccf59e35 (diff)
parentd1ff33d2d6f966da4d7ee85918cf6b12b951135f (diff)
Merge pull request #7721 from yorickvP/post-build-hook
Also pass unwanted outputs to post-build-hook
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build/derivation-goal.cc35
-rw-r--r--src/libstore/build/derivation-goal.hh6
-rw-r--r--src/libstore/build/local-derivation-goal.cc3
-rw-r--r--src/libstore/realisation.cc13
-rw-r--r--src/libstore/realisation.hh9
5 files changed, 38 insertions, 28 deletions
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc
index a4bb94b0e..23724b0d9 100644
--- a/src/libstore/build/derivation-goal.cc
+++ b/src/libstore/build/derivation-goal.cc
@@ -1020,43 +1020,33 @@ void DerivationGoal::resolvedFinished()
StorePathSet outputPaths;
- // `wantedOutputs` might merely indicate “all the outputs”
- auto realWantedOutputs = std::visit(overloaded {
- [&](const OutputsSpec::All &) {
- return resolvedDrv.outputNames();
- },
- [&](const OutputsSpec::Names & names) {
- return static_cast<std::set<std::string>>(names);
- },
- }, wantedOutputs.raw());
-
- for (auto & wantedOutput : realWantedOutputs) {
- auto initialOutput = get(initialOutputs, wantedOutput);
- auto resolvedHash = get(resolvedHashes, wantedOutput);
+ for (auto & outputName : resolvedDrv.outputNames()) {
+ auto initialOutput = get(initialOutputs, outputName);
+ auto resolvedHash = get(resolvedHashes, outputName);
if ((!initialOutput) || (!resolvedHash))
throw Error(
"derivation '%s' doesn't have expected output '%s' (derivation-goal.cc/resolvedFinished,resolve)",
- worker.store.printStorePath(drvPath), wantedOutput);
+ worker.store.printStorePath(drvPath), outputName);
auto realisation = [&]{
- auto take1 = get(resolvedResult.builtOutputs, wantedOutput);
+ auto take1 = get(resolvedResult.builtOutputs, outputName);
if (take1) return *take1;
/* The above `get` should work. But sateful tracking of
outputs in resolvedResult, this can get out of sync with the
store, which is our actual source of truth. For now we just
check the store directly if it fails. */
- auto take2 = worker.evalStore.queryRealisation(DrvOutput { *resolvedHash, wantedOutput });
+ auto take2 = worker.evalStore.queryRealisation(DrvOutput { *resolvedHash, outputName });
if (take2) return *take2;
throw Error(
"derivation '%s' doesn't have expected output '%s' (derivation-goal.cc/resolvedFinished,realisation)",
- worker.store.printStorePath(resolvedDrvGoal->drvPath), wantedOutput);
+ worker.store.printStorePath(resolvedDrvGoal->drvPath), outputName);
}();
if (drv->type().isPure()) {
auto newRealisation = realisation;
- newRealisation.id = DrvOutput { initialOutput->outputHash, wantedOutput };
+ newRealisation.id = DrvOutput { initialOutput->outputHash, outputName };
newRealisation.signatures.clear();
if (!drv->type().isFixed())
newRealisation.dependentRealisations = drvOutputReferences(worker.store, *drv, realisation.outPath);
@@ -1064,7 +1054,7 @@ void DerivationGoal::resolvedFinished()
worker.store.registerDrvOutput(newRealisation);
}
outputPaths.insert(realisation.outPath);
- builtOutputs.emplace(wantedOutput, realisation);
+ builtOutputs.emplace(outputName, realisation);
}
runPostBuildHook(
@@ -1406,7 +1396,7 @@ std::pair<bool, SingleDrvOutputs> DerivationGoal::checkPathValidity()
);
}
}
- if (info.wanted && info.known && info.known->isValid())
+ if (info.known && info.known->isValid())
validOutputs.emplace(i.first, Realisation { drvOutput, info.known->path });
}
@@ -1457,8 +1447,9 @@ void DerivationGoal::done(
mcRunningBuilds.reset();
if (buildResult.success()) {
- assert(!builtOutputs.empty());
- buildResult.builtOutputs = std::move(builtOutputs);
+ auto wantedBuiltOutputs = filterDrvOutputs(wantedOutputs, std::move(builtOutputs));
+ assert(!wantedBuiltOutputs.empty());
+ buildResult.builtOutputs = std::move(wantedBuiltOutputs);
if (status == BuildResult::Built)
worker.doneBuilds++;
} else {
diff --git a/src/libstore/build/derivation-goal.hh b/src/libstore/build/derivation-goal.hh
index 7033b7a58..01a08d391 100644
--- a/src/libstore/build/derivation-goal.hh
+++ b/src/libstore/build/derivation-goal.hh
@@ -306,15 +306,13 @@ struct DerivationGoal : public Goal
* Update 'initialOutputs' to determine the current status of the
* outputs of the derivation. Also returns a Boolean denoting
* whether all outputs are valid and non-corrupt, and a
- * 'SingleDrvOutputs' structure containing the valid and wanted
- * outputs.
+ * 'SingleDrvOutputs' structure containing the valid outputs.
*/
std::pair<bool, SingleDrvOutputs> checkPathValidity();
/**
* Aborts if any output is not valid or corrupt, and otherwise
- * returns a 'SingleDrvOutputs' structure containing the wanted
- * outputs.
+ * returns a 'SingleDrvOutputs' structure containing all outputs.
*/
SingleDrvOutputs assertPathValidity();
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index 21cd6e7ee..2f545627b 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -2701,8 +2701,7 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs()
signRealisation(thisRealisation);
worker.store.registerDrvOutput(thisRealisation);
}
- if (wantedOutputs.contains(outputName))
- builtOutputs.emplace(outputName, thisRealisation);
+ builtOutputs.emplace(outputName, thisRealisation);
}
return builtOutputs;
diff --git a/src/libstore/realisation.cc b/src/libstore/realisation.cc
index d63ec5ea2..93ddb5b20 100644
--- a/src/libstore/realisation.cc
+++ b/src/libstore/realisation.cc
@@ -136,6 +136,19 @@ size_t Realisation::checkSignatures(const PublicKeys & publicKeys) const
return good;
}
+
+SingleDrvOutputs filterDrvOutputs(const OutputsSpec& wanted, SingleDrvOutputs&& outputs)
+{
+ SingleDrvOutputs ret = std::move(outputs);
+ for (auto it = ret.begin(); it != ret.end(); ) {
+ if (!wanted.contains(it->first))
+ it = ret.erase(it);
+ else
+ ++it;
+ }
+ return ret;
+}
+
StorePath RealisedPath::path() const {
return std::visit([](auto && arg) { return arg.getPath(); }, raw);
}
diff --git a/src/libstore/realisation.hh b/src/libstore/realisation.hh
index 3922d1267..2a093c128 100644
--- a/src/libstore/realisation.hh
+++ b/src/libstore/realisation.hh
@@ -12,6 +12,7 @@
namespace nix {
class Store;
+struct OutputsSpec;
/**
* A general `Realisation` key.
@@ -93,6 +94,14 @@ typedef std::map<std::string, Realisation> SingleDrvOutputs;
*/
typedef std::map<DrvOutput, Realisation> DrvOutputs;
+/**
+ * Filter a SingleDrvOutputs to include only specific output names
+ *
+ * Moves the `outputs` input.
+ */
+SingleDrvOutputs filterDrvOutputs(const OutputsSpec&, SingleDrvOutputs&&);
+
+
struct OpaquePath {
StorePath path;