2121#include " nix/util/url.hh"
2222#include " nix/fetchers/registry.hh"
2323#include " nix/store/build-result.hh"
24+ #include " nix/util/exit.hh"
2425
2526#include < regex>
2627#include < queue>
@@ -590,46 +591,69 @@ static SingleBuiltPath getBuiltPath(ref<Store> evalStore, ref<Store> store, cons
590591 b.raw ());
591592}
592593
593- std::vector<BuiltPathWithResult> Installable::build (
594- ref<Store> evalStore, ref<Store> store, Realise mode, const Installables & installables, BuildMode bMode)
594+ const BuiltPathWithResult & InstallableWithBuildResult::getSuccess () const
595595{
596- std::vector<BuiltPathWithResult> res;
597- for (auto & [_, builtPathWithResult] : build2 (evalStore, store, mode, installables, bMode))
598- res.push_back (builtPathWithResult);
599- return res;
596+ if (auto * failure = std::get_if<Failure>(&result)) {
597+ auto failure2 = failure->tryGetFailure ();
598+ assert (failure2);
599+ failure2->rethrow ();
600+ } else
601+ return *std::get_if<Success>(&result);
600602}
601603
602- static void throwBuildErrors (std::vector<KeyedBuildResult > & buildResults, const Store & store)
604+ void Installable:: throwBuildErrors (std::vector<InstallableWithBuildResult > & buildResults, const Store & store)
603605{
604- std::vector<std::pair<const KeyedBuildResult *, const KeyedBuildResult::Failure *>> failed;
605606 for (auto & buildResult : buildResults) {
606- if (auto * failure = buildResult.tryGetFailure ()) {
607- failed.push_back ({&buildResult, failure});
608- }
609- }
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+ }
610613
611- auto failedResult = failed.begin ();
612- if (failedResult != failed.end ()) {
613- if (failed.size () == 1 ) {
614- failedResult->second ->rethrow ();
615- } else {
616- StringSet failedPaths;
617- for (; failedResult != failed.end (); failedResult++) {
618- if (!failedResult->second ->errorMsg .empty ()) {
619- logError (
620- ErrorInfo{
621- .level = lvlError,
622- .msg = failedResult->second ->errorMsg ,
623- });
614+ // Then cancelled builds.
615+ for (auto & buildResult : buildResults) {
616+ if (auto failure = std::get_if<InstallableWithBuildResult::Failure>(&buildResult.result )) {
617+ if (failure->isCancelled ())
618+ notice (
619+ " ❓ " ANSI_BOLD " %s" ANSI_NORMAL ANSI_FAINT " (cancelled)" ,
620+ buildResult.installable ->what ());
621+ }
622+ }
623+
624+ // Then failures.
625+ for (auto & buildResult : buildResults) {
626+ if (auto failure = std::get_if<InstallableWithBuildResult::Failure>(&buildResult.result )) {
627+ if (failure->isCancelled ())
628+ continue ;
629+ auto failure2 = failure->tryGetFailure ();
630+ assert (failure2);
631+ printError (" ❌ " ANSI_RED " %s" ANSI_NORMAL, buildResult.installable ->what ());
632+ try {
633+ failure2->rethrow ();
634+ } catch (Error & e) {
635+ logError (e.info ());
636+ }
624637 }
625- failedPaths.insert (failedResult->first ->path .to_string (store));
626638 }
627- throw Error (" build of %s failed" , concatStringsSep (" , " , quoteStrings (failedPaths)));
639+
640+ throw Exit (1 );
628641 }
629642 }
630643}
631644
632- std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build2 (
645+ std::vector<BuiltPathWithResult> Installable::build (
646+ ref<Store> evalStore, ref<Store> store, Realise mode, const Installables & installables, BuildMode bMode)
647+ {
648+ auto results = build2 (evalStore, store, mode, installables, bMode);
649+ throwBuildErrors (results, *store);
650+ std::vector<BuiltPathWithResult> res;
651+ for (auto & b : results)
652+ res.push_back (b.getSuccess ());
653+ return res;
654+ }
655+
656+ std::vector<InstallableWithBuildResult> Installable::build2 (
633657 ref<Store> evalStore, ref<Store> store, Realise mode, const Installables & installables, BuildMode bMode)
634658{
635659 if (mode == Realise::Nothing)
@@ -651,7 +675,7 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
651675 }
652676 }
653677
654- std::vector<std::pair<ref<Installable>, BuiltPathWithResult> > res;
678+ std::vector<InstallableWithBuildResult > res;
655679
656680 switch (mode) {
657681
@@ -666,17 +690,21 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
666690 [&](const DerivedPath::Built & bfd) {
667691 auto outputs = resolveDerivedPath (*store, bfd, &*evalStore);
668692 res.push_back (
669- {aux.installable ,
670- {.path =
671- BuiltPath::Built{
672- .drvPath =
673- make_ref<SingleBuiltPath>(getBuiltPath (evalStore, store, *bfd.drvPath )),
674- .outputs = outputs,
675- },
676- .info = aux.info }});
693+ {.installable = aux.installable ,
694+ .result = InstallableWithBuildResult::Success{
695+ .path =
696+ BuiltPath::Built{
697+ .drvPath = make_ref<SingleBuiltPath>(
698+ getBuiltPath (evalStore, store, *bfd.drvPath )),
699+ .outputs = outputs,
700+ },
701+ .info = aux.info }});
677702 },
678703 [&](const DerivedPath::Opaque & bo) {
679- res.push_back ({aux.installable , {.path = BuiltPath::Opaque{bo.path }, .info = aux.info }});
704+ res.push_back (
705+ {.installable = aux.installable ,
706+ .result = InstallableWithBuildResult::Success{
707+ .path = BuiltPath::Opaque{bo.path }, .info = aux.info }});
680708 },
681709 },
682710 path.raw ());
@@ -690,9 +718,13 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
690718 printMissing (store, pathsToBuild, lvlInfo);
691719
692720 auto buildResults = store->buildPathsWithResults (pathsToBuild, bMode, evalStore);
693- throwBuildErrors (buildResults, *store);
694721 for (auto & buildResult : buildResults) {
695- // If we didn't throw, they must all be sucesses
722+ if (buildResult.tryGetFailure ()) {
723+ for (auto & aux : backmap[buildResult.path ]) {
724+ res.push_back ({.installable = aux.installable , .result = buildResult});
725+ }
726+ continue ;
727+ }
696728 auto & success = std::get<nix::BuildResult::Success>(buildResult.inner );
697729 for (auto & aux : backmap[buildResult.path ]) {
698730 std::visit (
@@ -702,20 +734,22 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
702734 for (auto & [outputName, realisation] : success.builtOutputs )
703735 outputs.emplace (outputName, realisation.outPath );
704736 res.push_back (
705- {aux.installable ,
706- {.path =
707- BuiltPath::Built{
708- .drvPath =
709- make_ref<SingleBuiltPath>(getBuiltPath (evalStore, store, *bfd.drvPath )),
710- .outputs = outputs,
711- },
712- .info = aux.info ,
713- .result = buildResult}});
737+ {.installable = aux.installable ,
738+ .result = InstallableWithBuildResult::Success{
739+ .path =
740+ BuiltPath::Built{
741+ .drvPath = make_ref<SingleBuiltPath>(
742+ getBuiltPath (evalStore, store, *bfd.drvPath )),
743+ .outputs = outputs,
744+ },
745+ .info = aux.info ,
746+ .result = buildResult}});
714747 },
715748 [&](const DerivedPath::Opaque & bo) {
716749 res.push_back (
717- {aux.installable ,
718- {.path = BuiltPath::Opaque{bo.path }, .info = aux.info , .result = buildResult}});
750+ {.installable = aux.installable ,
751+ .result = InstallableWithBuildResult::Success{
752+ .path = BuiltPath::Opaque{bo.path }, .info = aux.info , .result = buildResult}});
719753 },
720754 },
721755 buildResult.path .raw ());
0 commit comments