diff options
author | Maksim Denisov <denisov.maksim@huawei.com> | 2025-02-25 15:18:44 +0100 |
---|---|---|
committer | Maksim Denisov <denisov.maksim@huawei.com> | 2025-02-27 09:03:30 +0100 |
commit | 0f87d4fb45d27e3f169de99bd4196ebc6eca5e33 (patch) | |
tree | 89e3882ca365cabef7557381ee99925441ae0454 /src | |
parent | 9ef9974db0941587453891e3250ffed8de7e10f1 (diff) | |
download | justbuild-0f87d4fb45d27e3f169de99bd4196ebc6eca5e33.tar.gz |
ArtifactBlob: Support construction from an existing file
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/common/TARGETS | 1 | ||||
-rw-r--r-- | src/buildtool/common/artifact_blob.cpp | 51 | ||||
-rw-r--r-- | src/buildtool/common/artifact_blob.hpp | 19 |
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_; |