summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/execution_api/bazel_msg/TARGETS2
-rw-r--r--src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp62
-rw-r--r--src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp16
3 files changed, 80 insertions, 0 deletions
diff --git a/src/buildtool/execution_api/bazel_msg/TARGETS b/src/buildtool/execution_api/bazel_msg/TARGETS
index d2e7aff2..c036451b 100644
--- a/src/buildtool/execution_api/bazel_msg/TARGETS
+++ b/src/buildtool/execution_api/bazel_msg/TARGETS
@@ -6,6 +6,7 @@
[ ["src/buildtool/common", "common"]
, ["src/buildtool/crypto", "hash_function"]
, ["src/buildtool/file_system", "file_system_manager"]
+ , ["src/buildtool/file_system", "git_cas"]
, ["src/utils/cpp", "concepts"]
, ["src/utils/cpp", "type_safe_arithmetic"]
]
@@ -21,6 +22,7 @@
, ["src/buildtool/common", "common"]
, ["src/buildtool/file_system", "file_system_manager"]
, ["src/buildtool/execution_engine/dag", "dag"]
+ , ["src/buildtool/compatibility", "compatibility"]
, ["@", "gsl-lite", "", "gsl-lite"]
]
, "stage": ["src", "buildtool", "execution_api", "bazel_msg"]
diff --git a/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp b/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp
index c6b2eb29..7cd9af69 100644
--- a/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp
+++ b/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp
@@ -12,6 +12,7 @@
#include "gsl-lite/gsl-lite.hpp"
#include "src/buildtool/common/bazel_types.hpp"
+#include "src/buildtool/compatibility/native_support.hpp"
#include "src/buildtool/file_system/file_system_manager.hpp"
namespace {
@@ -544,6 +545,67 @@ auto BazelMsgFactory::CreateDirectoryDigestFromLocalTree(
return std::nullopt;
}
+auto BazelMsgFactory::CreateGitTreeDigestFromLocalTree(
+ std::filesystem::path const& root,
+ FileStoreFunc const& store_file,
+ TreeStoreFunc const& store_tree) noexcept
+ -> std::optional<bazel_re::Digest> {
+ GitCAS::tree_entries_t entries{};
+ auto dir_reader = [&entries, &root, &store_file, &store_tree](auto name,
+ auto type) {
+ if (IsTreeObject(type)) {
+ // create and store sub directory
+ if (auto digest = CreateGitTreeDigestFromLocalTree(
+ root / name, store_file, store_tree)) {
+ if (auto raw_id = FromHexString(
+ NativeSupport::Unprefix(digest->hash()))) {
+ entries[std::move(*raw_id)].emplace_back(name.string(),
+ ObjectType::Tree);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // create and store file
+ try {
+ const auto full_name = root / name;
+ const bool is_executable =
+ FileSystemManager::IsExecutable(full_name, true);
+ if (auto digest = store_file(full_name, is_executable)) {
+ if (auto raw_id = FromHexString(
+ NativeSupport::Unprefix(digest->hash()))) {
+ entries[std::move(*raw_id)].emplace_back(
+ name.string(),
+ is_executable ? ObjectType::Executable
+ : ObjectType::File);
+ return true;
+ }
+ }
+ } catch (std::exception const& ex) {
+ Logger::Log(
+ LogLevel::Error, "storing file failed with:\n{}", ex.what());
+ }
+ return false;
+ };
+
+ if (FileSystemManager::ReadDirectory(root, dir_reader)) {
+ if (auto tree = GitCAS::CreateShallowTree(entries)) {
+ try {
+ if (auto digest = store_tree(tree->second, entries)) {
+ return *digest;
+ }
+ } catch (std::exception const& ex) {
+ Logger::Log(LogLevel::Error,
+ "storing tree failed with:\n{}",
+ ex.what());
+ }
+ return std::nullopt;
+ }
+ }
+ return std::nullopt;
+}
+
auto BazelMsgFactory::CreateActionDigestFromCommandLine(
std::vector<std::string> const& cmdline,
bazel_re::Digest const& exec_dir,
diff --git a/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp b/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp
index d850e6c6..8675cc92 100644
--- a/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp
+++ b/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp
@@ -15,6 +15,7 @@
#include "src/buildtool/execution_api/bazel_msg/bazel_blob.hpp"
#include "src/buildtool/execution_api/bazel_msg/bazel_common.hpp"
#include "src/buildtool/execution_engine/dag/dag.hpp"
+#include "src/buildtool/file_system/git_cas.hpp"
/// \brief Factory for creating Bazel API protobuf messages.
/// Responsible for creating protobuf messages necessary for Bazel API server
@@ -29,6 +30,9 @@ class BazelMsgFactory {
using DirStoreFunc = std::function<std::optional<bazel_re::Digest>(
std::string const&,
bazel_re::Directory const&)>;
+ using TreeStoreFunc = std::function<std::optional<bazel_re::Digest>(
+ std::string const&,
+ GitCAS::tree_entries_t const&)>;
/// \brief Read object infos from directory.
/// \returns true on success.
@@ -60,6 +64,18 @@ class BazelMsgFactory {
DirStoreFunc const& store_dir) noexcept
-> std::optional<bazel_re::Digest>;
+ /// \brief Create Git tree digest from local file root.
+ /// Recursively traverse entire root and store files and directories.
+ /// \param root Path to local file root.
+ /// \param store_file Function for storing local file via path.
+ /// \param store_tree Function for storing git trees.
+ /// \returns Digest representing the entire file root.
+ [[nodiscard]] static auto CreateGitTreeDigestFromLocalTree(
+ std::filesystem::path const& root,
+ FileStoreFunc const& store_file,
+ TreeStoreFunc const& store_tree) noexcept
+ -> std::optional<bazel_re::Digest>;
+
/// \brief Creates Action digest from command line.
/// As part of the internal process, it creates an ActionBundle and
/// CommandBundle that can be captured via BlobStoreFunc.