aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd
diff options
context:
space:
mode:
authorMaximilian Bosch <maximilian@mbosch.me>2024-05-13 20:58:54 +0200
committerMaximilian Bosch <maximilian@mbosch.me>2024-05-15 15:35:18 +0200
commite1463931833670970fbcebd9bece326ac7146205 (patch)
treeca32bd8009d50101d7731866de07a520f5d182e9 /src/libcmd
parentf6dc40cd1c3cdb38d104fb18ca76b9acf374190a (diff)
nix3-build: show all FOD errors with `--keep-going`
Basically I'd expect the same behavior as with `nix-build`, i.e. with `--keep-going` the hash-mismatch error of each failing fixed-output derivation is shown. The approach is derived from `Store::buildPaths` (`entry-point.cc`): instead of throwing the first build-result, check if there are any build errors and if so, display all of them and throw after that. Unfortunately, the BuildResult struct doesn't have an `ErrorInfo` (there's a FIXME for that at least), so I have to construct my own here. This is a rather cheap bugfix and I decided against touching too many parts of libstore for that (also I don't know if that's in line with the ongoing refactoring work). Closes https://git.lix.systems/lix-project/lix/issues/302 Change-Id: I378ab984fa271e6808c6897c45e0f070eb4c6fac
Diffstat (limited to 'src/libcmd')
-rw-r--r--src/libcmd/installables.cc38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index dca17555a..2c18653e4 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -547,6 +547,37 @@ std::vector<BuiltPathWithResult> Installable::build(
return res;
}
+static void throwBuildErrors(
+ std::vector<KeyedBuildResult> & buildResults,
+ const Store & store)
+{
+ std::vector<KeyedBuildResult> failed;
+ for (auto & buildResult : buildResults) {
+ if (!buildResult.success()) {
+ failed.push_back(buildResult);
+ }
+ }
+
+ auto failedResult = failed.begin();
+ if (failedResult != failed.end()) {
+ if (failed.size() == 1) {
+ failedResult->rethrow();
+ } else {
+ StringSet failedPaths;
+ for (; failedResult != failed.end(); failedResult++) {
+ if (!failedResult->errorMsg.empty()) {
+ logError(ErrorInfo{
+ .level = lvlError,
+ .msg = failedResult->errorMsg,
+ });
+ }
+ failedPaths.insert(failedResult->path.to_string(store));
+ }
+ throw Error("build of %s failed", concatStringsSep(", ", quoteStrings(failedPaths)));
+ }
+ }
+}
+
std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build2(
ref<Store> evalStore,
ref<Store> store,
@@ -608,10 +639,9 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
if (settings.printMissing)
printMissing(store, pathsToBuild, lvlInfo);
- for (auto & buildResult : store->buildPathsWithResults(pathsToBuild, bMode, evalStore)) {
- if (!buildResult.success())
- buildResult.rethrow();
-
+ auto buildResults = store->buildPathsWithResults(pathsToBuild, bMode, evalStore);
+ throwBuildErrors(buildResults, *store);
+ for (auto & buildResult : buildResults) {
for (auto & aux : backmap[buildResult.path]) {
std::visit(overloaded {
[&](const DerivedPath::Built & bfd) {