From 4ffa6374dbf67fe386bab041d67a46c3ce75cc23 Mon Sep 17 00:00:00 2001 From: Maksim Denisov Date: Thu, 16 Jan 2025 09:35:30 +0100 Subject: Just: Support absent tree structure roots --- src/buildtool/file_system/precomputed_root.cpp | 42 ++++++++++++++++++++---- src/buildtool/file_system/precomputed_root.hpp | 2 ++ src/other_tools/utils/parse_precomputed_root.cpp | 2 +- 3 files changed, 39 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/buildtool/file_system/precomputed_root.cpp b/src/buildtool/file_system/precomputed_root.cpp index f62bab64..0ff02628 100644 --- a/src/buildtool/file_system/precomputed_root.cpp +++ b/src/buildtool/file_system/precomputed_root.cpp @@ -90,10 +90,12 @@ template <> template <> [[nodiscard]] auto ParseImpl(nlohmann::json const& root) -> expected { - if (root.size() != TreeStructureRoot::kSchemeLength) { + if (root.size() != TreeStructureRoot::kSchemeLength and + root.size() != TreeStructureRoot::kSchemePragmaLength) { return unexpected{ fmt::format("The root has a wrong number of arguments: {}\nThe " - "scheme requires [, ]", + "scheme requires [, ] optionally " + "followed by a pragma object", root.dump())}; } @@ -103,7 +105,29 @@ template <> root[1].dump())}; } - return TreeStructureRoot{.repository = std::string{root[1]}}; + bool absent = false; + if (root.size() == TreeStructureRoot::kSchemePragmaLength) { + if (not root[2].is_object()) { + return unexpected{ + fmt::format("The root has a wrong type of optional pragma " + "argument. Expected a plain json object, got {}", + root[2].dump())}; + } + if (root[2].contains("absent")) { + auto const& absent_entry = root[2].at("absent"); + if (not absent_entry.is_null() and not absent_entry.is_boolean()) { + return unexpected{ + fmt::format("Expected pragma entry \"absent\" to be " + "boolean, but found {}", + absent_entry.dump())}; + } + absent = + absent_entry.is_boolean() and absent_entry.template get(); + } + } + + return TreeStructureRoot{.repository = root[1].template get(), + .absent = absent}; } } // namespace @@ -147,22 +171,28 @@ auto ComputedRoot::ComputeHash() const -> std::size_t { auto TreeStructureRoot::operator==( TreeStructureRoot const& other) const noexcept -> bool { - return repository == other.repository; + return absent == other.absent and repository == other.repository; } auto TreeStructureRoot::operator<(TreeStructureRoot const& other) const noexcept -> bool { + if (absent != other.absent) { + return absent; + } return repository < other.repository; } auto TreeStructureRoot::ToString() const -> std::string { - return fmt::format("[\"tree structure\", {}]", - nlohmann::json(repository).dump()); + return fmt::format("[\"tree structure\", {}{}]", + nlohmann::json(repository).dump(), + absent ? ", {\"absent\": true}" : ""); } + auto TreeStructureRoot::ComputeHash() const -> std::size_t { std::size_t seed{}; hash_combine(&seed, kMarker); hash_combine(&seed, repository); + hash_combine(&seed, absent); return seed; } diff --git a/src/buildtool/file_system/precomputed_root.hpp b/src/buildtool/file_system/precomputed_root.hpp index 6df59bc9..f3495418 100644 --- a/src/buildtool/file_system/precomputed_root.hpp +++ b/src/buildtool/file_system/precomputed_root.hpp @@ -45,8 +45,10 @@ struct ComputedRoot final { struct TreeStructureRoot final { static constexpr auto kMarker = "tree structure"; static constexpr std::size_t kSchemeLength = 2; + static constexpr std::size_t kSchemePragmaLength = 3; std::string repository; + bool absent; [[nodiscard]] auto operator==(TreeStructureRoot const& other) const noexcept -> bool; diff --git a/src/other_tools/utils/parse_precomputed_root.cpp b/src/other_tools/utils/parse_precomputed_root.cpp index a27c7989..7b9ef519 100644 --- a/src/other_tools/utils/parse_precomputed_root.cpp +++ b/src/other_tools/utils/parse_precomputed_root.cpp @@ -67,7 +67,7 @@ namespace { if (not repo.IsNotNull()) { return unexpected{"Mandatory key \"repo\" is missing"}; } - return TreeStructureRoot{.repository = repo->String()}; + return TreeStructureRoot{.repository = repo->String(), .absent = false}; } } // namespace -- cgit v1.2.3