summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/execution_api/common/tree_reader.hpp27
-rw-r--r--src/buildtool/execution_api/local/local_api.hpp38
-rw-r--r--src/buildtool/execution_api/local/local_cas_reader.cpp17
-rw-r--r--src/buildtool/execution_api/local/local_cas_reader.hpp4
-rw-r--r--src/buildtool/execution_api/remote/bazel/bazel_network_reader.hpp8
5 files changed, 62 insertions, 32 deletions
diff --git a/src/buildtool/execution_api/common/tree_reader.hpp b/src/buildtool/execution_api/common/tree_reader.hpp
index 7ec66163..42bf20e6 100644
--- a/src/buildtool/execution_api/common/tree_reader.hpp
+++ b/src/buildtool/execution_api/common/tree_reader.hpp
@@ -15,6 +15,7 @@
#ifndef INCLUDED_SRC_BUILDTOOL_EXECUTION_API_COMMON_TREE_READER_HPP
#define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_COMMON_TREE_READER_HPP
+#include <cstddef>
#include <filesystem>
#include <optional>
#include <utility>
@@ -107,6 +108,32 @@ class TreeReader final {
}
}
+ /// \brief Traverse a tree recursively and stage all artifacts to paths.
+ /// \param infos Infos to be staged
+ /// \param outputs Paths to be used for staging
+ /// \return True if outputs contain corresponding infos.
+ [[nodiscard]] auto StageTo(std::vector<Artifact::ObjectInfo> const& infos,
+ std::vector<std::filesystem::path> const&
+ outputs) const noexcept -> bool {
+ if (infos.size() != outputs.size()) {
+ return false;
+ }
+
+ for (std::size_t i = 0; i < infos.size(); ++i) {
+ auto const& info = infos[i];
+ if (IsTreeObject(info.type)) {
+ auto result = RecursivelyReadTreeLeafs(info.digest, outputs[i]);
+ if (not result or not StageTo(result->infos, result->paths)) {
+ return false;
+ }
+ }
+ else if (not impl_.StageBlobTo(info, outputs[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
private:
TImpl impl_;
diff --git a/src/buildtool/execution_api/local/local_api.hpp b/src/buildtool/execution_api/local/local_api.hpp
index e87c0d23..7e7bee1c 100644
--- a/src/buildtool/execution_api/local/local_api.hpp
+++ b/src/buildtool/execution_api/local/local_api.hpp
@@ -101,39 +101,13 @@ class LocalApi final : public IExecutionApi {
return false;
}
- for (std::size_t i{}; i < artifacts_info.size(); ++i) {
+ auto const reader =
+ TreeReader<LocalCasReader>{&local_context_.storage->CAS()};
+ for (std::size_t i = 0; i < artifacts_info.size(); ++i) {
auto const& info = artifacts_info[i];
- if (IsTreeObject(info.type)) {
- // read object infos from sub tree and call retrieve recursively
- auto reader =
- TreeReader<LocalCasReader>{&local_context_.storage->CAS()};
- auto const result = reader.RecursivelyReadTreeLeafs(
- info.digest, output_paths[i]);
- if (not result) {
- if (git_api_ and not git_api_->RetrieveToPaths(
- {info}, {output_paths[i]})) {
- return false;
- }
- }
- else if (not RetrieveToPaths(result->infos, result->paths)) {
- return false;
- }
- }
- else {
- auto const blob_path = local_context_.storage->CAS().BlobPath(
- info.digest, IsExecutableObject(info.type));
- if (not blob_path) {
- if (git_api_ and not git_api_->RetrieveToPaths(
- {info}, {output_paths[i]})) {
- return false;
- }
- }
- else if (not FileSystemManager::CreateDirectory(
- output_paths[i].parent_path()) or
- not FileSystemManager::CopyFileAs<
- /*kSetEpochTime=*/true,
- /*kSetWritable=*/true>(
- *blob_path, output_paths[i], info.type)) {
+ if (not reader.StageTo({info}, {output_paths[i]})) {
+ if (not git_api_ or
+ not git_api_->RetrieveToPaths({info}, {output_paths[i]})) {
Logger::Log(LogLevel::Error,
"staging to output path {} failed.",
output_paths[i].string());
diff --git a/src/buildtool/execution_api/local/local_cas_reader.cpp b/src/buildtool/execution_api/local/local_cas_reader.cpp
index 5365404f..c88f5c15 100644
--- a/src/buildtool/execution_api/local/local_cas_reader.cpp
+++ b/src/buildtool/execution_api/local/local_cas_reader.cpp
@@ -145,6 +145,23 @@ auto LocalCasReader::DumpBlob(Artifact::ObjectInfo const& info,
return path ? DumpRaw(*path, dumper) : false;
}
+auto LocalCasReader::StageBlobTo(
+ Artifact::ObjectInfo const& info,
+ std::filesystem::path const& output) const noexcept -> bool {
+ if (not IsBlobObject(info.type)) {
+ return false;
+ }
+ auto const blob_path =
+ cas_.BlobPath(info.digest, IsExecutableObject(info.type));
+ if (not blob_path) {
+ return false;
+ }
+ return FileSystemManager::CreateDirectory(output.parent_path()) and
+ FileSystemManager::CopyFileAs</*kSetEpochTime=*/true,
+ /*kSetWritable=*/true>(
+ *blob_path, output, info.type);
+}
+
auto LocalCasReader::DumpRaw(std::filesystem::path const& path,
DumpCallback const& dumper) noexcept -> bool {
auto closer = [](gsl::owner<FILE*> file) -> void {
diff --git a/src/buildtool/execution_api/local/local_cas_reader.hpp b/src/buildtool/execution_api/local/local_cas_reader.hpp
index 8fe9afd4..090aa9d1 100644
--- a/src/buildtool/execution_api/local/local_cas_reader.hpp
+++ b/src/buildtool/execution_api/local/local_cas_reader.hpp
@@ -52,6 +52,10 @@ class LocalCasReader final {
DumpCallback const& dumper) const noexcept
-> bool;
+ [[nodiscard]] auto StageBlobTo(
+ Artifact::ObjectInfo const& info,
+ std::filesystem::path const& output) const noexcept -> bool;
+
[[nodiscard]] auto IsNativeProtocol() const noexcept -> bool;
private:
diff --git a/src/buildtool/execution_api/remote/bazel/bazel_network_reader.hpp b/src/buildtool/execution_api/remote/bazel/bazel_network_reader.hpp
index d5b537f1..0bfa9a84 100644
--- a/src/buildtool/execution_api/remote/bazel/bazel_network_reader.hpp
+++ b/src/buildtool/execution_api/remote/bazel/bazel_network_reader.hpp
@@ -16,6 +16,7 @@
#define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_REMOTE_BAZEL_BAZEL_TREE_READER_HPP
#include <cstddef>
+#include <filesystem>
#include <functional>
#include <iterator>
#include <optional>
@@ -64,6 +65,13 @@ class BazelNetworkReader final {
DumpCallback const& dumper) const noexcept
-> bool;
+ // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
+ [[nodiscard]] auto StageBlobTo(
+ Artifact::ObjectInfo const& /*info*/,
+ std::filesystem::path const& /*output*/) const noexcept -> bool {
+ return false; // not implemented
+ }
+
[[nodiscard]] auto IsNativeProtocol() const noexcept -> bool;
[[nodiscard]] auto ReadSingleBlob(bazel_re::Digest const& digest)