summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaksim Denisov <denisov.maksim@huawei.com>2025-01-14 17:59:01 +0100
committerMaksim Denisov <denisov.maksim@huawei.com>2025-01-21 09:58:36 +0100
commitaa8635c6863646f5df78b54832f51db16aac25ba (patch)
tree6dd9d592b463e2968c42c4e0b7b891e2c6013e06 /src
parent6fa286a674059f2f4a4dd6033aacb13b2d6d1e40 (diff)
downloadjustbuild-aa8635c6863646f5df78b54832f51db16aac25ba.tar.gz
TreeStructureUtils: export from git
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/computed_roots/TARGETS1
-rw-r--r--src/buildtool/computed_roots/evaluate.cpp55
-rw-r--r--src/buildtool/tree_structure/TARGETS2
-rw-r--r--src/buildtool/tree_structure/tree_structure_utils.cpp38
-rw-r--r--src/buildtool/tree_structure/tree_structure_utils.hpp15
5 files changed, 78 insertions, 33 deletions
diff --git a/src/buildtool/computed_roots/TARGETS b/src/buildtool/computed_roots/TARGETS
index fde38693..4d620db3 100644
--- a/src/buildtool/computed_roots/TARGETS
+++ b/src/buildtool/computed_roots/TARGETS
@@ -78,7 +78,6 @@
, ["src/buildtool/crypto", "hash_function"]
, ["src/buildtool/execution_api/common", "api_bundle"]
, ["src/buildtool/execution_api/common", "common"]
- , ["src/buildtool/execution_api/git", "git"]
, ["src/buildtool/execution_api/local", "config"]
, ["src/buildtool/execution_api/local", "context"]
, ["src/buildtool/execution_api/local", "local"]
diff --git a/src/buildtool/computed_roots/evaluate.cpp b/src/buildtool/computed_roots/evaluate.cpp
index 0905c240..ffac5e04 100644
--- a/src/buildtool/computed_roots/evaluate.cpp
+++ b/src/buildtool/computed_roots/evaluate.cpp
@@ -46,7 +46,6 @@
#include "src/buildtool/crypto/hash_function.hpp"
#include "src/buildtool/execution_api/common/api_bundle.hpp"
#include "src/buildtool/execution_api/common/execution_api.hpp"
-#include "src/buildtool/execution_api/git/git_api.hpp"
#include "src/buildtool/execution_api/local/config.hpp"
#include "src/buildtool/execution_api/local/context.hpp"
#include "src/buildtool/execution_api/local/local_api.hpp"
@@ -411,6 +410,7 @@ void ComputeTreeStructureAndFill(
if (not resolved_hash) {
// If the tree is not in the storage, it must be added:
if (not storage.CAS().TreePath(*digest).has_value()) {
+ std::vector<std::filesystem::path> known_repos;
auto const path_to_git_cas = ref_root.GetGitCasRoot();
if (not path_to_git_cas) {
std::invoke(*logger,
@@ -420,45 +420,36 @@ void ComputeTreeStructureAndFill(
true);
return;
}
+ known_repos.push_back(*path_to_git_cas);
+ known_repos.push_back(native_storage_config.GitRoot());
- RepositoryConfig root_config{};
- if (not root_config.SetGitCAS(*path_to_git_cas)) {
- std::invoke(
- *logger,
- fmt::format("Failed to set git cas for {}", key.ToString()),
- true);
+ auto in_cas = TreeStructureUtils::ExportFromGit(
+ *digest, known_repos, native_local_api);
+ if (not in_cas.has_value()) {
+ std::invoke(*logger, std::move(in_cas).error(), /*fatal=*/true);
return;
}
+ }
- GitApi const git_api{&root_config};
- if (not git_api.RetrieveToCas(
- {Artifact::ObjectInfo{*digest, ObjectType::Tree}},
- native_local_api) or
- not storage.CAS().TreePath(*digest).has_value()) {
- std::invoke(*logger,
- fmt::format("Failed to retrieve {} to CAS for {}",
- digest->hash(),
- key.ToString()),
- true);
+ if (storage.CAS().TreePath(*digest).has_value()) {
+ // Compute tree structure and add it to the cache:
+ auto const tree_structure = TreeStructureUtils::Compute(
+ *digest, storage, tree_structure_cache);
+ if (not tree_structure) {
+ std::invoke(*logger, tree_structure.error(), /*fatal=*/true);
return;
}
- }
- // Compute tree structure and add it to the cache:
- auto const tree_structure =
- TreeStructureUtils::Compute(*digest, storage, tree_structure_cache);
- if (not tree_structure) {
- std::invoke(*logger, tree_structure.error(), /*fatal=*/true);
- return;
- }
-
- auto to_git = TreeStructureUtils::ImportToGit(
- *tree_structure, native_local_api, native_storage_config, git_lock);
- if (not to_git.has_value()) {
- std::invoke(*logger, std::move(to_git).error(), /*fatal=*/true);
- return;
+ auto to_git = TreeStructureUtils::ImportToGit(*tree_structure,
+ native_local_api,
+ native_storage_config,
+ git_lock);
+ if (not to_git.has_value()) {
+ std::invoke(*logger, std::move(to_git).error(), /*fatal=*/true);
+ return;
+ }
+ resolved_hash = tree_structure->hash();
}
- resolved_hash = tree_structure->hash();
}
if (not resolved_hash) {
diff --git a/src/buildtool/tree_structure/TARGETS b/src/buildtool/tree_structure/TARGETS
index 45244119..0c9dc676 100644
--- a/src/buildtool/tree_structure/TARGETS
+++ b/src/buildtool/tree_structure/TARGETS
@@ -38,8 +38,10 @@
, "private-deps":
[ ["@", "fmt", "", "fmt"]
, ["src/buildtool/common", "artifact_digest_factory"]
+ , ["src/buildtool/common", "config"]
, ["src/buildtool/common", "protocol_traits"]
, ["src/buildtool/crypto", "hash_function"]
+ , ["src/buildtool/execution_api/git", "git"]
, ["src/buildtool/file_system", "file_system_manager"]
, ["src/buildtool/file_system", "git_repo"]
, ["src/buildtool/file_system", "object_type"]
diff --git a/src/buildtool/tree_structure/tree_structure_utils.cpp b/src/buildtool/tree_structure/tree_structure_utils.cpp
index b607cb9f..7cc04b6f 100644
--- a/src/buildtool/tree_structure/tree_structure_utils.cpp
+++ b/src/buildtool/tree_structure/tree_structure_utils.cpp
@@ -15,6 +15,7 @@
#include "src/buildtool/tree_structure/tree_structure_utils.hpp"
#include <algorithm>
+#include <cstddef>
#include <filesystem>
#include <functional>
#include <memory>
@@ -27,7 +28,9 @@
#include "src/buildtool/common/artifact.hpp"
#include "src/buildtool/common/artifact_digest_factory.hpp"
#include "src/buildtool/common/protocol_traits.hpp"
+#include "src/buildtool/common/repository_config.hpp"
#include "src/buildtool/crypto/hash_function.hpp"
+#include "src/buildtool/execution_api/git/git_api.hpp"
#include "src/buildtool/file_system/file_system_manager.hpp"
#include "src/buildtool/file_system/git_repo.hpp"
#include "src/buildtool/file_system/object_type.hpp"
@@ -198,3 +201,38 @@ auto TreeStructureUtils::ImportToGit(
}
return *digest;
}
+
+auto TreeStructureUtils::ExportFromGit(
+ ArtifactDigest const& tree,
+ std::vector<std::filesystem::path> const& source_repos,
+ IExecutionApi const& target_api) noexcept -> expected<bool, std::string> {
+ if (not tree.IsTree() or not ProtocolTraits::IsNative(tree.GetHashType())) {
+ return unexpected{fmt::format("Not a git tree: {}", tree.hash())};
+ }
+
+ // Find git repo that contains the tree:
+ std::filesystem::path const* repo = nullptr;
+ for (std::size_t i = 0; i < source_repos.size() and repo == nullptr; ++i) {
+ auto in_repo = GitRepo::IsTreeInRepo(source_repos[i], tree.hash());
+ if (not in_repo.has_value()) {
+ return unexpected{std::move(in_repo).error()};
+ }
+ if (*in_repo) {
+ repo = &source_repos[i];
+ }
+ }
+
+ // Check that at least one repo contains the tree:
+ if (repo == nullptr) {
+ return false;
+ }
+
+ RepositoryConfig repo_config{};
+ if (not repo_config.SetGitCAS(*repo)) {
+ return unexpected{
+ fmt::format("Failed to set git cas at {}", repo->string())};
+ }
+ auto const git_api = GitApi{&repo_config};
+ return git_api.RetrieveToCas({Artifact::ObjectInfo{tree, ObjectType::Tree}},
+ target_api);
+}
diff --git a/src/buildtool/tree_structure/tree_structure_utils.hpp b/src/buildtool/tree_structure/tree_structure_utils.hpp
index df2f9f5e..4f908640 100644
--- a/src/buildtool/tree_structure/tree_structure_utils.hpp
+++ b/src/buildtool/tree_structure/tree_structure_utils.hpp
@@ -15,8 +15,10 @@
#ifndef INCLUDED_SRC_BUILDTOOL_TREE_STRUCTURE_TREE_STRUCTURE_UTILS_HPP
#define INCLUDED_SRC_BUILDTOOL_TREE_STRUCTURE_TREE_STRUCTURE_UTILS_HPP
+#include <filesystem>
#include <mutex>
#include <string>
+#include <vector>
#include "gsl/gsl"
#include "src/buildtool/common/artifact_digest.hpp"
@@ -59,6 +61,19 @@ class TreeStructureUtils final {
StorageConfig const& target_config,
gsl::not_null<std::mutex*> const& tagging_lock) noexcept
-> expected<ArtifactDigest, std::string>;
+
+ /// \brief Export a tree from source git repositories to target api. Uses
+ /// regular GitApi for retrieval from git and doesn't perform rehashing.
+ /// \param tree Tree to export
+ /// \param source_repos Repositories to check
+ /// \param target_api Api to export the tree to
+ /// \return True if target api contains tree after the call, false if none
+ /// of source repositories contain tree, or an error message on failure.
+ [[nodiscard]] static auto ExportFromGit(
+ ArtifactDigest const& tree,
+ std::vector<std::filesystem::path> const& source_repos,
+ IExecutionApi const& target_api) noexcept
+ -> expected<bool, std::string>;
};
#endif // INCLUDED_SRC_BUILDTOOL_TREE_STRUCTURE_TREE_STRUCTURE_UTILS_HPP