summaryrefslogtreecommitdiff
path: root/src/buildtool/tree_structure/tree_structure_utils.cpp
diff options
context:
space:
mode:
authorMaksim Denisov <denisov.maksim@huawei.com>2025-01-14 11:50:51 +0100
committerMaksim Denisov <denisov.maksim@huawei.com>2025-01-21 09:58:36 +0100
commit6fa286a674059f2f4a4dd6033aacb13b2d6d1e40 (patch)
treec3e6c198b38e39d520b7fc991ebe5d9ef1c127d3 /src/buildtool/tree_structure/tree_structure_utils.cpp
parent8196d143f343a11026293521e5dbe0a9731d5050 (diff)
downloadjustbuild-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.cpp65
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;
+}