1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
// 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_BLOB_HPP
#define INCLUDED_SRC_BUILDTOOL_COMMON_ARTIFACT_BLOB_HPP
#include <cstddef>
#include <filesystem>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <variant>
#include "src/buildtool/common/artifact_digest.hpp"
#include "src/buildtool/crypto/hash_function.hpp"
#include "src/buildtool/file_system/object_type.hpp"
#include "src/utils/cpp/expected.hpp"
#include "src/utils/cpp/incremental_reader.hpp"
#include "src/utils/cpp/tmp_dir.hpp"
class ArtifactBlob final {
public:
/// \brief Create ArtifactBlob and keep the given content in memory. 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 content String to be stored
/// \return Valid ArtifactBlob on success or an error message on failure.
[[nodiscard]] static auto FromMemory(HashFunction hash_function,
ObjectType type,
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>;
/// \brief Create ArtifactBlob based on the existing temporary file. The
/// content is hashed based on the given hash function and ObjectType.
/// \param hash_function HashFunction that must be used for hashing.
/// \param type Type of the content.
/// \param file Temporary file to be used as the source of
/// content.
/// \return Valid ArtifactBlob on success or an error message on failure.
[[nodiscard]] static auto FromTempFile(HashFunction hash_function,
ObjectType type,
TmpFile::Ptr file) noexcept
-> expected<ArtifactBlob, std::string>;
/// \brief Create ArtifactBlob and write the given content to the temporary
/// space. The content is hashed based on the given hash function and
/// ObjectType.
/// \param hash_function HashFunction that must be used for hashing.
/// \param type Type of the content.
/// \param temp_space Temporary space where a new temporary file may
/// be created.
/// \param content Content to be stored in the temporary file.
/// \return Valid ArtifactBlob on success or an error message on failure.
[[nodiscard]] static auto FromTempFile(HashFunction hash_type,
ObjectType type,
TmpDir::Ptr const& temp_space,
std::string const& content) noexcept
-> expected<ArtifactBlob, std::string>;
[[nodiscard]] auto operator==(ArtifactBlob const& other) const noexcept
-> bool {
return digest_ == other.digest_ and
is_executable_ == other.is_executable_;
}
/// \brief Obtain the digest of the content.
[[nodiscard]] auto GetDigest() const noexcept -> ArtifactDigest const& {
return digest_;
}
/// \brief Obtain the size of the content.
[[nodiscard]] auto GetContentSize() const noexcept -> std::size_t {
return digest_.size();
}
/// \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>;
/// \brief Create an IncrementalReader that uses this ArtifactBlob's content
/// source.
/// \param chunk_size Size of chunk, must be greater than 0.
/// \return Valid IncrementalReader on success or an error message on
/// failure.
[[nodiscard]] auto ReadIncrementally(std::size_t chunk_size) const& noexcept
-> expected<IncrementalReader, std::string>;
/// \brief Obtain the path to the file that is used as the content source.
/// If ArtifactBlob doesn't use a filesystem source or an internal error
/// occurs, std::nullopt is returned.
[[nodiscard]] auto GetFilePath() const& noexcept
-> std::optional<std::filesystem::path>;
/// \brief Set executable permission.
void SetExecutable(bool is_executable) noexcept {
is_executable_ = is_executable;
}
/// \brief Obtain executable permission.
[[nodiscard]] auto IsExecutable() const noexcept -> bool {
return is_executable_;
}
private:
using InMemory = std::shared_ptr<std::string const>;
using InFile = std::filesystem::path;
using InTempFile = TmpFile::Ptr;
using ContentSource = std::variant<InMemory, InFile, InTempFile>;
ArtifactDigest digest_;
ContentSource content_;
bool is_executable_;
explicit ArtifactBlob(ArtifactDigest digest,
ContentSource content,
bool is_executable) noexcept
: digest_{std::move(digest)},
content_{std::move(content)},
is_executable_{is_executable} {}
};
namespace std {
template <>
struct hash<ArtifactBlob> {
[[nodiscard]] auto operator()(ArtifactBlob const& blob) const noexcept
-> std::size_t;
};
} // namespace std
#endif // INCLUDED_SRC_BUILDTOOL_COMMON_ARTIFACT_BLOB_HPP
|