|
21 | 21 | #include "nix/util/url.hh" |
22 | 22 | #include "nix/fetchers/registry.hh" |
23 | 23 | #include "nix/store/build-result.hh" |
| 24 | +#include "nix/util/exit.hh" |
24 | 25 |
|
25 | 26 | #include <regex> |
26 | 27 | #include <queue> |
@@ -600,45 +601,54 @@ const BuiltPathWithResult & InstallableWithBuildResult::getSuccess() const |
600 | 601 | return *std::get_if<Success>(&result); |
601 | 602 | } |
602 | 603 |
|
603 | | -std::vector<BuiltPathWithResult> Installable::build( |
604 | | - ref<Store> evalStore, ref<Store> store, Realise mode, const Installables & installables, BuildMode bMode) |
| 604 | +void Installable::throwBuildErrors(std::vector<InstallableWithBuildResult> & buildResults, const Store & store) |
605 | 605 | { |
606 | | - std::vector<BuiltPathWithResult> res; |
607 | | - for (auto & b : build2(evalStore, store, mode, installables, bMode)) |
608 | | - res.push_back(b.getSuccess()); |
609 | | - return res; |
610 | | -} |
611 | | - |
612 | | -static void throwBuildErrors(std::vector<KeyedBuildResult> & buildResults, const Store & store) |
613 | | -{ |
614 | | - std::vector<std::pair<const KeyedBuildResult *, const KeyedBuildResult::Failure *>> failed; |
615 | 606 | for (auto & buildResult : buildResults) { |
616 | | - if (auto * failure = buildResult.tryGetFailure()) { |
617 | | - failed.push_back({&buildResult, failure}); |
618 | | - } |
619 | | - } |
| 607 | + if (std::get_if<InstallableWithBuildResult::Failure>(&buildResult.result)) { |
| 608 | + // Report success first. |
| 609 | + for (auto & buildResult : buildResults) { |
| 610 | + if (std::get_if<InstallableWithBuildResult::Success>(&buildResult.result)) |
| 611 | + notice("✅ " ANSI_BOLD "%s" ANSI_NORMAL, buildResult.installable->what()); |
| 612 | + } |
620 | 613 |
|
621 | | - auto failedResult = failed.begin(); |
622 | | - if (failedResult != failed.end()) { |
623 | | - if (failed.size() == 1) { |
624 | | - failedResult->second->rethrow(); |
625 | | - } else { |
626 | | - StringSet failedPaths; |
627 | | - for (; failedResult != failed.end(); failedResult++) { |
628 | | - if (!failedResult->second->errorMsg.empty()) { |
629 | | - logError( |
630 | | - ErrorInfo{ |
631 | | - .level = lvlError, |
632 | | - .msg = failedResult->second->errorMsg, |
633 | | - }); |
| 614 | + // Then failures. |
| 615 | + for (auto & buildResult : buildResults) { |
| 616 | + if (auto failure = std::get_if<InstallableWithBuildResult::Failure>(&buildResult.result)) { |
| 617 | + auto failure2 = failure->tryGetFailure(); |
| 618 | + assert(failure2); |
| 619 | + if (failure2->status == BuildResult::Failure::Cancelled |
| 620 | + // FIXME: remove MiscFailure eventually |
| 621 | + || failure2->status == BuildResult::Failure::MiscFailure) |
| 622 | + notice( |
| 623 | + "❓ " ANSI_BOLD "%s" ANSI_NORMAL ANSI_FAINT " (cancelled)", |
| 624 | + buildResult.installable->what()); |
| 625 | + else { |
| 626 | + printError("❌ " ANSI_RED "%s" ANSI_NORMAL, buildResult.installable->what()); |
| 627 | + try { |
| 628 | + failure2->rethrow(); |
| 629 | + } catch (Error & e) { |
| 630 | + logError(e.info()); |
| 631 | + } |
| 632 | + } |
634 | 633 | } |
635 | | - failedPaths.insert(failedResult->first->path.to_string(store)); |
636 | 634 | } |
637 | | - throw Error("build of %s failed", concatStringsSep(", ", quoteStrings(failedPaths))); |
| 635 | + |
| 636 | + throw Exit(1); |
638 | 637 | } |
639 | 638 | } |
640 | 639 | } |
641 | 640 |
|
| 641 | +std::vector<BuiltPathWithResult> Installable::build( |
| 642 | + ref<Store> evalStore, ref<Store> store, Realise mode, const Installables & installables, BuildMode bMode) |
| 643 | +{ |
| 644 | + auto results = build2(evalStore, store, mode, installables, bMode); |
| 645 | + throwBuildErrors(results, *store); |
| 646 | + std::vector<BuiltPathWithResult> res; |
| 647 | + for (auto & b : results) |
| 648 | + res.push_back(b.getSuccess()); |
| 649 | + return res; |
| 650 | +} |
| 651 | + |
642 | 652 | std::vector<InstallableWithBuildResult> Installable::build2( |
643 | 653 | ref<Store> evalStore, ref<Store> store, Realise mode, const Installables & installables, BuildMode bMode) |
644 | 654 | { |
@@ -704,9 +714,13 @@ std::vector<InstallableWithBuildResult> Installable::build2( |
704 | 714 | printMissing(store, pathsToBuild, lvlInfo); |
705 | 715 |
|
706 | 716 | auto buildResults = store->buildPathsWithResults(pathsToBuild, bMode, evalStore); |
707 | | - throwBuildErrors(buildResults, *store); |
708 | 717 | for (auto & buildResult : buildResults) { |
709 | | - // If we didn't throw, they must all be successes. |
| 718 | + if (buildResult.tryGetFailure()) { |
| 719 | + for (auto & aux : backmap[buildResult.path]) { |
| 720 | + res.push_back({.installable = aux.installable, .result = buildResult}); |
| 721 | + } |
| 722 | + continue; |
| 723 | + } |
710 | 724 | auto & success = std::get<nix::BuildResult::Success>(buildResult.inner); |
711 | 725 | for (auto & aux : backmap[buildResult.path]) { |
712 | 726 | std::visit( |
|
0 commit comments