summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/common/TARGETS21
-rw-r--r--src/buildtool/common/artifact_digest.hpp5
-rw-r--r--src/buildtool/common/artifact_digest_factory.cpp48
-rw-r--r--src/buildtool/common/artifact_digest_factory.hpp89
4 files changed, 163 insertions, 0 deletions
diff --git a/src/buildtool/common/TARGETS b/src/buildtool/common/TARGETS
index 88364386..e6d4e126 100644
--- a/src/buildtool/common/TARGETS
+++ b/src/buildtool/common/TARGETS
@@ -55,6 +55,26 @@
, "private-deps": [["src/buildtool/crypto", "hasher"]]
, "stage": ["src", "buildtool", "common"]
}
+, "artifact_digest_factory":
+ { "type": ["@", "rules", "CC", "library"]
+ , "name": ["artifact_digest_factory"]
+ , "hdrs": ["artifact_digest_factory.hpp"]
+ , "srcs": ["artifact_digest_factory.cpp"]
+ , "deps":
+ [ "common"
+ , ["src/buildtool/crypto", "hash_function"]
+ , ["src/buildtool/crypto", "hash_info"]
+ , ["src/buildtool/file_system", "object_type"]
+ , ["src/utils/cpp", "expected"]
+ ]
+ , "private-deps":
+ [ "bazel_digest_factory"
+ , "bazel_types"
+ , ["@", "gsl", "", "gsl"]
+ , ["src/buildtool/compatibility", "compatibility"]
+ ]
+ , "stage": ["src", "buildtool", "common"]
+ }
, "common":
{ "type": ["@", "rules", "CC", "library"]
, "name": ["common"]
@@ -68,6 +88,7 @@
, "deps":
[ "bazel_types"
, ["src/buildtool/crypto", "hash_function"]
+ , ["src/buildtool/crypto", "hash_info"]
, ["src/buildtool/file_system", "object_type"]
, ["src/buildtool/compatibility", "compatibility"]
, ["src/buildtool/logging", "log_level"]
diff --git a/src/buildtool/common/artifact_digest.hpp b/src/buildtool/common/artifact_digest.hpp
index 93c41464..ebd01ceb 100644
--- a/src/buildtool/common/artifact_digest.hpp
+++ b/src/buildtool/common/artifact_digest.hpp
@@ -24,6 +24,7 @@
#include "src/buildtool/common/bazel_types.hpp"
#include "src/buildtool/compatibility/native_support.hpp"
#include "src/buildtool/crypto/hash_function.hpp"
+#include "src/buildtool/crypto/hash_info.hpp"
#include "src/buildtool/file_system/object_type.hpp"
#include "src/utils/cpp/gsl.hpp"
#include "src/utils/cpp/hash_combine.hpp"
@@ -36,6 +37,10 @@ class ArtifactDigest final {
public:
ArtifactDigest() noexcept = default;
+ explicit ArtifactDigest(HashInfo const& hash_info,
+ std::size_t size) noexcept
+ : size_{size}, hash_{hash_info.Hash()}, is_tree_{hash_info.IsTree()} {}
+
explicit ArtifactDigest(bazel_re::Digest const& digest) noexcept
: size_{gsl::narrow<std::size_t>(digest.size_bytes())},
hash_{NativeSupport::Unprefix(digest.hash())},
diff --git a/src/buildtool/common/artifact_digest_factory.cpp b/src/buildtool/common/artifact_digest_factory.cpp
new file mode 100644
index 00000000..05bfd031
--- /dev/null
+++ b/src/buildtool/common/artifact_digest_factory.cpp
@@ -0,0 +1,48 @@
+// Copyright 2024 Huawei Cloud Computing Technology Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/buildtool/common/artifact_digest_factory.hpp"
+
+#include "gsl/gsl"
+#include "src/buildtool/common/bazel_digest_factory.hpp"
+#include "src/buildtool/common/bazel_types.hpp"
+#include "src/buildtool/compatibility/compatibility.hpp"
+
+auto ArtifactDigestFactory::FromBazel(HashFunction::Type hash_type,
+ bazel_re::Digest const& digest) noexcept
+ -> expected<ArtifactDigest, std::string> {
+ auto hash_info = BazelDigestFactory::ToHashInfo(hash_type, digest);
+ if (not hash_info) {
+ return unexpected{std::move(hash_info).error()};
+ }
+ return ArtifactDigest{*hash_info,
+ static_cast<std::size_t>(digest.size_bytes())};
+}
+
+auto ArtifactDigestFactory::ToBazel(ArtifactDigest const& digest)
+ -> bazel_re::Digest {
+ static constexpr std::size_t kGitSHA1Length = 40;
+ // TODO(denisov): The type of the bazel digest produced here doesn't have to
+ // be the same as Compatibility::IsCompatible returns, since we're
+ // computing hashes with a predefined type in many places. Once
+ // ArtifactDigest gets HashInfo as a field, it will be taken from there
+ // directly, but for now it is 'guessed' based on the length of the hash.
+ auto const type = digest.hash().size() == kGitSHA1Length
+ ? HashFunction::Type::GitSHA1
+ : HashFunction::Type::PlainSHA256;
+ auto const hash_info =
+ HashInfo::Create(type, digest.hash(), digest.IsTree());
+ return BazelDigestFactory::Create(*hash_info,
+ gsl::narrow<std::int64_t>(digest.size()));
+}
diff --git a/src/buildtool/common/artifact_digest_factory.hpp b/src/buildtool/common/artifact_digest_factory.hpp
new file mode 100644
index 00000000..09c0b478
--- /dev/null
+++ b/src/buildtool/common/artifact_digest_factory.hpp
@@ -0,0 +1,89 @@
+// Copyright 2024 Huawei Cloud Computing Technology Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef INCLUDED_SRC_BUILDTOOL_COMMON_ARTIFACT_DIGEST_FACTORY_HPP
+#define INCLUDED_SRC_BUILDTOOL_COMMON_ARTIFACT_DIGEST_FACTORY_HPP
+
+#include <cstddef>
+#include <filesystem>
+#include <optional>
+#include <string>
+#include <utility>
+
+#include "src/buildtool/common/artifact_digest.hpp"
+#include "src/buildtool/crypto/hash_function.hpp"
+#include "src/buildtool/crypto/hash_info.hpp"
+#include "src/buildtool/file_system/object_type.hpp"
+#include "src/utils/cpp/expected.hpp"
+
+namespace build::bazel::remote::execution::v2 {
+class Digest;
+}
+namespace bazel_re = build::bazel::remote::execution::v2;
+
+class ArtifactDigestFactory final {
+ public:
+ /// \brief Create ArtifactDigest from bazel_re::Digest
+ /// \param hash_type Type of the hash function that was used for creation of
+ /// the hash
+ /// \param digest Digest to be converted
+ /// \return A valid ArtifactDigest on success or an error message if
+ /// validation fails.
+ [[nodiscard]] static auto FromBazel(HashFunction::Type hash_type,
+ bazel_re::Digest const& digest) noexcept
+ -> expected<ArtifactDigest, std::string>;
+
+ /// \brief Convert ArtifactDigest to bazel_re::Digest. Throws an exception
+ /// on a narrow conversion error.
+ /// \param digest Digest to be converted.
+ /// \return A valid bazel_re::Digest
+ [[nodiscard]] static auto ToBazel(ArtifactDigest const& digest)
+ -> bazel_re::Digest;
+
+ /// \brief Hash content using hash function and return a valid
+ /// ArtifactDigest
+ /// \tparam kType Type of the hashing algorithm to be used
+ /// \param hash_function Hash function to be used for hashing
+ /// \param content Content to be hashed
+ /// \return The digest of the content
+ template <ObjectType kType>
+ [[nodiscard]] static auto HashDataAs(HashFunction hash_function,
+ std::string const& content) noexcept
+ -> ArtifactDigest {
+ auto const hash_info =
+ HashInfo::HashData(hash_function, content, IsTreeObject(kType));
+ return ArtifactDigest{hash_info, content.size()};
+ }
+
+ /// \brief Hash file using hash function and return a valid ArtifactDigest
+ /// \tparam kType Type of the hashing algorithm to be used
+ /// \param hash_function Hash function to be used for hashing
+ /// \param content Content to be hashed
+ /// \return The digest of the file
+ template <ObjectType kType>
+ [[nodiscard]] static auto HashFileAs(
+ HashFunction hash_function,
+ std::filesystem::path const& path) noexcept
+ -> std::optional<ArtifactDigest> {
+ auto const hash_info =
+ HashInfo::HashFile(hash_function, path, IsTreeObject(kType));
+ if (not hash_info) {
+ return std::nullopt;
+ }
+ return ArtifactDigest{hash_info->first,
+ static_cast<std::size_t>(hash_info->second)};
+ }
+};
+
+#endif // INCLUDED_SRC_BUILDTOOL_COMMON_ARTIFACT_DIGEST_FACTORY_HPP