summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/execution_engine/executor/TARGETS3
-rw-r--r--src/buildtool/execution_engine/executor/executor.hpp53
2 files changed, 56 insertions, 0 deletions
diff --git a/src/buildtool/execution_engine/executor/TARGETS b/src/buildtool/execution_engine/executor/TARGETS
index 2ac64635..d063439e 100644
--- a/src/buildtool/execution_engine/executor/TARGETS
+++ b/src/buildtool/execution_engine/executor/TARGETS
@@ -25,6 +25,9 @@
, ["src/buildtool/execution_api/remote", "config"]
, ["src/buildtool/execution_api/remote", "context"]
, ["src/buildtool/execution_engine/dag", "dag"]
+ , [ "src/buildtool/execution_engine/tree_operations"
+ , "tree_operations_utils"
+ ]
, ["src/buildtool/file_system", "file_root"]
, ["src/buildtool/file_system", "git_tree"]
, ["src/buildtool/file_system", "object_type"]
diff --git a/src/buildtool/execution_engine/executor/executor.hpp b/src/buildtool/execution_engine/executor/executor.hpp
index 41870df2..d274655a 100644
--- a/src/buildtool/execution_engine/executor/executor.hpp
+++ b/src/buildtool/execution_engine/executor/executor.hpp
@@ -18,6 +18,7 @@
#include <algorithm>
#include <chrono>
#include <cmath>
+#include <compare>
#include <exception>
#include <filesystem>
#include <functional>
@@ -59,6 +60,7 @@
#include "src/buildtool/execution_api/remote/context.hpp"
#include "src/buildtool/execution_engine/dag/dag.hpp"
#include "src/buildtool/execution_engine/executor/context.hpp"
+#include "src/buildtool/execution_engine/tree_operations/tree_operations_utils.hpp"
#include "src/buildtool/file_system/file_root.hpp"
#include "src/buildtool/file_system/git_tree.hpp"
#include "src/buildtool/file_system/object_type.hpp"
@@ -77,6 +79,54 @@
/// \brief Implementations for executing actions and uploading artifacts.
class ExecutorImpl {
public:
+ /// \brief Computes the result of a tree-overlay action.
+ /// \returns std::nullopt on success, nullptr on error.
+ [[nodiscard]] static auto ExecuteTreeOverlayAction(
+ Logger const& logger,
+ gsl::not_null<DependencyGraph::ActionNode const*> const& action,
+ IExecutionApi const& api) -> std::optional<IExecutionResponse::Ptr> {
+ std::vector<DependencyGraph::NamedArtifactNodePtr> inputs =
+ action->Dependencies();
+ std::sort(inputs.begin(), inputs.end(), [](auto a, auto b) {
+ return a.path < b.path;
+ });
+ logger.Emit(LogLevel::Debug, [&]() {
+ std::ostringstream oss{};
+ oss << "Requested tree-overlay action is " << action->Content().Id()
+ << "\n";
+ oss << "Trees to overlay:";
+ for (auto const& input : inputs) {
+ oss << "\n - " << input.node->Content().Info()->digest.hash()
+ << ":" << input.node->Content().Info()->digest.size() << ":"
+ << ToChar(input.node->Content().Info()->type);
+ }
+ return oss.str();
+ });
+ auto tree = *inputs[0].node->Content().Info();
+ for (auto const& overlay : inputs) {
+ auto computed_overlay = TreeOperationsUtils::ComputeTreeOverlay(
+ api,
+ tree,
+ *overlay.node->Content().Info(),
+ action->Content().IsOverlayDisjoint());
+ if (not computed_overlay) {
+ logger.Emit(LogLevel::Error,
+ "Tree-overlay computation failed: {}",
+ computed_overlay.error());
+ return nullptr;
+ }
+ tree = computed_overlay.value();
+ }
+ auto const& tree_artifact = action->OutputDirs()[0].node->Content();
+ bool failed_inputs = false;
+ for (auto const& [local_path, artifact] : inputs) {
+ failed_inputs |= artifact->Content().Info()->failed;
+ }
+ tree_artifact.SetObjectInfo(
+ tree.digest, ObjectType::Tree, failed_inputs);
+ return std::nullopt;
+ }
+
/// \brief Execute action and obtain response.
/// \returns std::nullopt for actions without response (e.g., tree actions).
/// \returns nullptr on error.
@@ -91,6 +141,9 @@ class ExecutorImpl {
gsl::not_null<Statistics*> const& stats,
gsl::not_null<Progress*> const& progress)
-> std::optional<IExecutionResponse::Ptr> {
+ if (action->Content().IsTreeOverlayAction()) {
+ return ExecuteTreeOverlayAction(logger, action, api);
+ }
auto const& inputs = action->Dependencies();
auto const tree_action = action->Content().IsTreeAction();