diff options
author | Maximilian Bosch <maximilian@mbosch.me> | 2024-05-13 20:58:54 +0200 |
---|---|---|
committer | Maximilian Bosch <maximilian@mbosch.me> | 2024-05-15 15:35:18 +0200 |
commit | e1463931833670970fbcebd9bece326ac7146205 (patch) | |
tree | ca32bd8009d50101d7731866de07a520f5d182e9 /src/libcmd | |
parent | f6dc40cd1c3cdb38d104fb18ca76b9acf374190a (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.cc | 38 |
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) { |