summaryrefslogtreecommitdiff
path: root/src/buildtool/storage/local_cas.tpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildtool/storage/local_cas.tpp')
-rw-r--r--src/buildtool/storage/local_cas.tpp52
1 files changed, 41 insertions, 11 deletions
diff --git a/src/buildtool/storage/local_cas.tpp b/src/buildtool/storage/local_cas.tpp
index b3d95934..f1c7d1cb 100644
--- a/src/buildtool/storage/local_cas.tpp
+++ b/src/buildtool/storage/local_cas.tpp
@@ -126,35 +126,60 @@ template <class T_CAS>
return false;
}
+[[nodiscard]] static inline auto IsDirectoryEmpty(
+ bazel_re::Directory const& dir) noexcept -> bool {
+ return dir.files().empty() and dir.directories().empty() and
+ dir.symlinks().empty();
+}
+
template <class T_CAS>
auto ReadObjectInfosRecursively(
T_CAS const& cas,
BazelMsgFactory::InfoStoreFunc const& store_info,
std::filesystem::path const& parent,
- bazel_re::Digest const& digest) noexcept -> bool {
+ bazel_re::Digest const& digest,
+ bool const include_trees = false) -> bool {
// read from CAS
if (Compatibility::IsCompatible()) {
if (auto dir = ReadDirectory(cas, digest)) {
+ if (include_trees and IsDirectoryEmpty(*dir)) {
+ if (not store_info(
+ parent, {ArtifactDigest{digest}, ObjectType::Tree})) {
+ return false;
+ }
+ }
return BazelMsgFactory::ReadObjectInfosFromDirectory(
- *dir, [&cas, &store_info, &parent](auto path, auto info) {
+ *dir,
+ [&cas, &store_info, &parent, include_trees](auto path,
+ auto info) {
return IsTreeObject(info.type)
? ReadObjectInfosRecursively(cas,
store_info,
parent / path,
- info.digest)
+ info.digest,
+ include_trees)
: store_info(parent / path, info);
});
}
}
else {
if (auto entries = ReadGitTree(cas, digest)) {
+ if (include_trees and entries->empty()) {
+ if (not store_info(
+ parent, {ArtifactDigest{digest}, ObjectType::Tree})) {
+ return false;
+ }
+ }
return BazelMsgFactory::ReadObjectInfosFromGitTree(
- *entries, [&cas, &store_info, &parent](auto path, auto info) {
+ *entries,
+ [&cas, &store_info, &parent, include_trees](auto path,
+ auto info) {
return IsTreeObject(info.type)
? ReadObjectInfosRecursively(cas,
store_info,
parent / path,
- info.digest)
+ info.digest,
+ include_trees)
: store_info(parent / path, info);
});
}
@@ -165,9 +190,10 @@ auto ReadObjectInfosRecursively(
} // namespace detail
template <bool kDoGlobalUplink>
-auto LocalCAS<kDoGlobalUplink>::RecursivelyReadTreeLeafs(
+[[nodiscard]] auto LocalCAS<kDoGlobalUplink>::RecursivelyReadTreeLeafs(
bazel_re::Digest const& tree_digest,
- std::filesystem::path const& parent) const noexcept
+ std::filesystem::path const& parent,
+ bool const include_trees) const noexcept
-> std::optional<std::pair<std::vector<std::filesystem::path>,
std::vector<Artifact::ObjectInfo>>> {
std::vector<std::filesystem::path> paths{};
@@ -179,15 +205,19 @@ auto LocalCAS<kDoGlobalUplink>::RecursivelyReadTreeLeafs(
return true;
};
- if (detail::ReadObjectInfosRecursively(
- *this, store_info, parent, tree_digest)) {
- return std::make_pair(std::move(paths), std::move(infos));
+ try {
+ if (detail::ReadObjectInfosRecursively(
+ *this, store_info, parent, tree_digest, include_trees)) {
+ return std::make_pair(std::move(paths), std::move(infos));
+ }
+ } catch (...) {
+ // fallthrough
}
return std::nullopt;
}
template <bool kDoGlobalUplink>
-auto LocalCAS<kDoGlobalUplink>::ReadDirectTreeEntries(
+[[nodiscard]] auto LocalCAS<kDoGlobalUplink>::ReadDirectTreeEntries(
bazel_re::Digest const& tree_digest,
std::filesystem::path const& parent) const noexcept
-> std::optional<std::pair<std::vector<std::filesystem::path>,