summaryrefslogtreecommitdiff
path: root/src/buildtool/execution_engine/executor/executor.hpp
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2024-12-06 09:47:31 +0100
committerKlaus Aehlig <klaus.aehlig@huawei.com>2024-12-06 11:14:18 +0100
commit665b324e15b76472364e0e984012f0308a298b3a (patch)
tree1661102011e1db38d242cf147239783a62929e64 /src/buildtool/execution_engine/executor/executor.hpp
parent2a74efbff53c5901b4044da3531698171431cc87 (diff)
downloadjustbuild-665b324e15b76472364e0e984012f0308a298b3a.tar.gz
Log: report outputs of failed actions by default
Some actions are allowed to fail, typically tests. By reporting the output of failed such actions early, the user can already have a look at those artifacts, typically a test log, while the build is still going on.
Diffstat (limited to 'src/buildtool/execution_engine/executor/executor.hpp')
-rw-r--r--src/buildtool/execution_engine/executor/executor.hpp45
1 files changed, 34 insertions, 11 deletions
diff --git a/src/buildtool/execution_engine/executor/executor.hpp b/src/buildtool/execution_engine/executor/executor.hpp
index 89d92570..f2f1b880 100644
--- a/src/buildtool/execution_engine/executor/executor.hpp
+++ b/src/buildtool/execution_engine/executor/executor.hpp
@@ -591,17 +591,15 @@ class ExecutorImpl {
progress->TaskTracker().Stop(action->Content().Id());
PrintInfo(logger, action, response);
+ bool action_failed = false;
bool should_fail_outputs = false;
for (auto const& [local_path, node] : action->Dependencies()) {
should_fail_outputs |= node->Content().Info()->failed;
}
if (response->ExitCode() != 0) {
if (action->MayFail()) {
- logger.Emit(LogLevel::Warning,
- "{} (exit code {})",
- *(action->MayFail()),
- response->ExitCode());
should_fail_outputs = true;
+ action_failed = true;
}
else {
logger.Emit(LogLevel::Error,
@@ -625,23 +623,48 @@ class ExecutorImpl {
not CheckOutputsExist(*artifacts.value(),
action->OutputDirPaths(),
action->Content().Cwd())) {
- logger.Emit(LogLevel::Error, [&] {
- std::string message{
- "action executed with missing outputs.\n"
- " Action outputs should be the following artifacts:"};
+ logger.Emit(LogLevel::Error, [&]() {
+ std::ostringstream message{};
+ if (action_failed) {
+ message << *(action->MayFail()) << " (exit code "
+ << response->ExitCode() << ")\nMoreover ";
+ }
+ message << "action executed with missing outputs.\nAction "
+ "outputs should be the following artifacts:";
for (auto const& output : action->OutputFilePaths()) {
- message += "\n - file: " + output;
+ message << "\n - file: " << output;
}
for (auto const& output : action->OutputDirPaths()) {
- message += "\n - dir: " + output;
+ message << "\n - dir: " << output;
}
- return message;
+ return message.str();
});
PrintError(logger, action, progress);
return false;
}
SaveObjectInfo(*artifacts.value(), action, should_fail_outputs);
+ if (action_failed) {
+ logger.Emit(LogLevel::Warning, [&]() {
+ std::ostringstream message{};
+ auto base = action->Content().Cwd();
+ message << *(action->MayFail()) << " (exit code "
+ << response->ExitCode() << "); outputs:";
+ for (auto const& [name, node] : action->OutputFiles()) {
+ message << "\n - " << nlohmann::json(name).dump() << " "
+ << artifacts.value()
+ ->at(RebasePathStringRelativeTo(base, name))
+ .ToString();
+ }
+ for (auto const& [name, node] : action->OutputDirs()) {
+ message << "\n - " << nlohmann::json(name).dump() << " "
+ << artifacts.value()
+ ->at(RebasePathStringRelativeTo(base, name))
+ .ToString();
+ }
+ return message.str();
+ });
+ }
return true;
}