diff options
author | Maksim Denisov <denisov.maksim@huawei.com> | 2025-01-14 11:50:51 +0100 |
---|---|---|
committer | Maksim Denisov <denisov.maksim@huawei.com> | 2025-01-21 09:58:36 +0100 |
commit | 6fa286a674059f2f4a4dd6033aacb13b2d6d1e40 (patch) | |
tree | c3e6c198b38e39d520b7fc991ebe5d9ef1c127d3 /src/buildtool/tree_structure/tree_structure_utils.cpp | |
parent | 8196d143f343a11026293521e5dbe0a9731d5050 (diff) | |
download | justbuild-6fa286a674059f2f4a4dd6033aacb13b2d6d1e40.tar.gz |
TreeStructureUtils: import to git
Unify logic from evaluator of precomputed roots.
Diffstat (limited to 'src/buildtool/tree_structure/tree_structure_utils.cpp')
-rw-r--r-- | src/buildtool/tree_structure/tree_structure_utils.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/buildtool/tree_structure/tree_structure_utils.cpp b/src/buildtool/tree_structure/tree_structure_utils.cpp index fd897672..b607cb9f 100644 --- a/src/buildtool/tree_structure/tree_structure_utils.cpp +++ b/src/buildtool/tree_structure/tree_structure_utils.cpp @@ -15,13 +15,16 @@ #include "src/buildtool/tree_structure/tree_structure_utils.hpp" #include <algorithm> +#include <filesystem> #include <functional> +#include <memory> #include <optional> #include <unordered_map> #include <utility> #include <vector> #include "fmt/core.h" +#include "src/buildtool/common/artifact.hpp" #include "src/buildtool/common/artifact_digest_factory.hpp" #include "src/buildtool/common/protocol_traits.hpp" #include "src/buildtool/crypto/hash_function.hpp" @@ -30,6 +33,7 @@ #include "src/buildtool/file_system/object_type.hpp" #include "src/utils/cpp/hex_string.hpp" #include "src/utils/cpp/path.hpp" +#include "src/utils/cpp/tmp_dir.hpp" auto TreeStructureUtils::Compute(ArtifactDigest const& tree, Storage const& storage, @@ -133,3 +137,64 @@ auto TreeStructureUtils::Compute(ArtifactDigest const& tree, } return *std::move(tree_structure); } + +auto TreeStructureUtils::ImportToGit( + ArtifactDigest const& tree, + IExecutionApi const& source_api, + StorageConfig const& target_config, + gsl::not_null<std::mutex*> const& tagging_lock) noexcept + -> expected<ArtifactDigest, std::string> { + if (not tree.IsTree() or not ProtocolTraits::IsNative(tree.GetHashType())) { + return unexpected{fmt::format("Not a git tree: {}", tree.hash())}; + } + + // Check the source contains the tree: + if (not source_api.IsAvailable(tree)) { + return unexpected{ + fmt::format("Source doesn't contain tree {}", tree.hash())}; + } + + // Check the tree is in the repository already: + if (auto in_repo = + GitRepo::IsTreeInRepo(target_config.GitRoot(), tree.hash())) { + if (*in_repo) { + return tree; + } + } + else { + return unexpected{std::move(in_repo).error()}; + } + + auto const tmp_dir = + target_config.CreateTypedTmpDir("import_from_cas_to_git"); + if (tmp_dir == nullptr) { + return unexpected{fmt::format( + "Failed to create temporary directory for {}", tree.hash())}; + } + + // Stage the tree to a temporary directory: + if (not source_api.RetrieveToPaths( + {Artifact::ObjectInfo{tree, ObjectType::Tree}}, + {tmp_dir->GetPath()})) { + return unexpected{fmt::format( + "Failed to stage {} to a temporary location.", tree.hash())}; + } + + // Import the result to git: + auto tree_hash = GitRepo::ImportToGit( + target_config, + tmp_dir->GetPath(), + /*commit_message=*/fmt::format("Import {}", tree.hash()), + tagging_lock); + if (not tree_hash) { + return unexpected{std::move(tree_hash).error()}; + } + auto digest = ArtifactDigestFactory::Create(HashFunction::Type::GitSHA1, + tree_hash.value(), + /*size_unknown=*/0, + /*is_tree=*/true); + if (not digest) { + return unexpected{std::move(digest).error()}; + } + return *digest; +} |