diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2024-12-06 09:47:31 +0100 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2024-12-06 11:14:18 +0100 |
commit | 665b324e15b76472364e0e984012f0308a298b3a (patch) | |
tree | 1661102011e1db38d242cf147239783a62929e64 /src/buildtool/execution_engine/executor/executor.hpp | |
parent | 2a74efbff53c5901b4044da3531698171431cc87 (diff) | |
download | justbuild-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.hpp | 45 |
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; } |