diff options
author | Maksim Denisov <denisov.maksim@huawei.com> | 2025-01-14 17:59:01 +0100 |
---|---|---|
committer | Maksim Denisov <denisov.maksim@huawei.com> | 2025-01-21 09:58:36 +0100 |
commit | aa8635c6863646f5df78b54832f51db16aac25ba (patch) | |
tree | 6dd9d592b463e2968c42c4e0b7b891e2c6013e06 /src | |
parent | 6fa286a674059f2f4a4dd6033aacb13b2d6d1e40 (diff) | |
download | justbuild-aa8635c6863646f5df78b54832f51db16aac25ba.tar.gz |
TreeStructureUtils: export from git
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/computed_roots/TARGETS | 1 | ||||
-rw-r--r-- | src/buildtool/computed_roots/evaluate.cpp | 55 | ||||
-rw-r--r-- | src/buildtool/tree_structure/TARGETS | 2 | ||||
-rw-r--r-- | src/buildtool/tree_structure/tree_structure_utils.cpp | 38 | ||||
-rw-r--r-- | src/buildtool/tree_structure/tree_structure_utils.hpp | 15 |
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 |