diff options
Diffstat (limited to 'src/buildtool/storage/local_cas.tpp')
-rw-r--r-- | src/buildtool/storage/local_cas.tpp | 52 |
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>, |