summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaksim Denisov <denisov.maksim@huawei.com>2025-02-25 15:18:44 +0100
committerMaksim Denisov <denisov.maksim@huawei.com>2025-02-27 09:03:30 +0100
commit0f87d4fb45d27e3f169de99bd4196ebc6eca5e33 (patch)
tree89e3882ca365cabef7557381ee99925441ae0454 /src
parent9ef9974db0941587453891e3250ffed8de7e10f1 (diff)
downloadjustbuild-0f87d4fb45d27e3f169de99bd4196ebc6eca5e33.tar.gz
ArtifactBlob: Support construction from an existing file
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/common/TARGETS1
-rw-r--r--src/buildtool/common/artifact_blob.cpp51
-rw-r--r--src/buildtool/common/artifact_blob.hpp19
3 files changed, 69 insertions, 2 deletions
diff --git a/src/buildtool/common/TARGETS b/src/buildtool/common/TARGETS
index 40539325..80d6ca34 100644
--- a/src/buildtool/common/TARGETS
+++ b/src/buildtool/common/TARGETS
@@ -94,6 +94,7 @@
, "private-deps":
[ "artifact_digest_factory"
, ["@", "fmt", "", "fmt"]
+ , ["src/buildtool/file_system", "file_system_manager"]
, ["src/utils/cpp", "hash_combine"]
, ["src/utils/cpp", "in_place_visitor"]
]
diff --git a/src/buildtool/common/artifact_blob.cpp b/src/buildtool/common/artifact_blob.cpp
index 78a9d54e..a9c70621 100644
--- a/src/buildtool/common/artifact_blob.cpp
+++ b/src/buildtool/common/artifact_blob.cpp
@@ -15,12 +15,25 @@
#include "src/buildtool/common/artifact_blob.hpp"
#include <exception>
+#include <optional>
#include "fmt/core.h"
#include "src/buildtool/common/artifact_digest_factory.hpp"
+#include "src/buildtool/file_system/file_system_manager.hpp"
#include "src/utils/cpp/hash_combine.hpp"
#include "src/utils/cpp/in_place_visitor.hpp"
+namespace {
+[[nodiscard]] auto ReadFromFile(std::filesystem::path const& file) noexcept
+ -> std::shared_ptr<std::string const> {
+ auto content = FileSystemManager::ReadFile(file);
+ if (not content.has_value()) {
+ return nullptr;
+ }
+ return std::make_shared<std::string const>(*std::move(content));
+}
+} // namespace
+
auto ArtifactBlob::FromMemory(HashFunction hash_function,
ObjectType type,
std::string content) noexcept
@@ -44,11 +57,46 @@ auto ArtifactBlob::FromMemory(HashFunction hash_function,
}
}
+auto ArtifactBlob::FromFile(HashFunction hash_function,
+ ObjectType type,
+ std::filesystem::path file) noexcept
+ -> expected<ArtifactBlob, std::string> {
+ try {
+ if (not FileSystemManager::IsFile(file)) {
+ return unexpected{
+ fmt::format("ArtifactBlob::FromFile: Not a regular file:\n{}",
+ file.string())};
+ }
+ auto digest = IsTreeObject(type)
+ ? ArtifactDigestFactory::HashFileAs<ObjectType::Tree>(
+ hash_function, file)
+ : ArtifactDigestFactory::HashFileAs<ObjectType::File>(
+ hash_function, file);
+ if (not digest.has_value()) {
+ return unexpected{fmt::format(
+ "ArtifactBlob::FromFile: Failed to hash {}", file.string())};
+ }
+ return ArtifactBlob{
+ *std::move(digest), std::move(file), IsExecutableObject(type)};
+ } catch (const std::exception& e) {
+ return unexpected{fmt::format(
+ "ArtifactBlob::FromFile: Got an exception while processing {}:\n{}",
+ file.string(),
+ e.what())};
+ } catch (...) {
+ return unexpected{
+ fmt::format("ArtifactBlob::FromFile: Got an unknown exception "
+ "while processing {}",
+ file.string())};
+ }
+}
+
auto ArtifactBlob::ReadContent() const noexcept
-> std::shared_ptr<std::string const> {
using Result = std::shared_ptr<std::string const>;
static constexpr InPlaceVisitor kVisitor{
[](InMemory const& value) -> Result { return value; },
+ [](InFile const& value) -> Result { return ::ReadFromFile(value); },
};
try {
return std::visit(kVisitor, content_);
@@ -68,6 +116,9 @@ auto ArtifactBlob::ReadIncrementally(std::size_t chunk_size) const& noexcept
}
return IncrementalReader::FromMemory(chunk_size, value.get());
},
+ [chunk_size](InFile const& value) -> Result {
+ return IncrementalReader::FromFile(chunk_size, value);
+ },
};
try {
return std::visit(visitor, content_);
diff --git a/src/buildtool/common/artifact_blob.hpp b/src/buildtool/common/artifact_blob.hpp
index c5a03cf9..092dd2b1 100644
--- a/src/buildtool/common/artifact_blob.hpp
+++ b/src/buildtool/common/artifact_blob.hpp
@@ -16,6 +16,7 @@
#define INCLUDED_SRC_BUILDTOOL_COMMON_ARTIFACT_BLOB_HPP
#include <cstddef>
+#include <filesystem>
#include <functional>
#include <memory>
#include <string>
@@ -41,6 +42,18 @@ class ArtifactBlob final {
std::string content) noexcept
-> expected<ArtifactBlob, std::string>;
+ /// \brief Create ArtifactBlob based on the existing file. The content is
+ /// hashed based on the given hash function and ObjectType.
+ /// \param hash_function Hash function that must be used for hashing.
+ /// \param type Type of the content.
+ /// \param file Existing file to be used as the source of
+ /// content.
+ /// \return Valid ArtifactBlob on success or an error message on failure.
+ [[nodiscard]] static auto FromFile(HashFunction hash_function,
+ ObjectType type,
+ std::filesystem::path file) noexcept
+ -> expected<ArtifactBlob, std::string>;
+
[[nodiscard]] auto operator==(ArtifactBlob const& other) const noexcept
-> bool {
return digest_ == other.digest_ and
@@ -57,7 +70,8 @@ class ArtifactBlob final {
return digest_.size();
}
- /// \brief Read the content from source.
+ /// \brief Read the content from source. This operation may result in the
+ /// entire file being read into memory.
[[nodiscard]] auto ReadContent() const noexcept
-> std::shared_ptr<std::string const>;
@@ -81,7 +95,8 @@ class ArtifactBlob final {
private:
using InMemory = std::shared_ptr<std::string const>;
- using ContentSource = std::variant<InMemory>;
+ using InFile = std::filesystem::path;
+ using ContentSource = std::variant<InMemory, InFile>;
ArtifactDigest digest_;
ContentSource content_;