diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2025-01-10 12:43:48 +0100 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2025-01-22 10:40:32 +0100 |
commit | 6c4ecdb57f9140dc8474da2f83660fc5f977cc6d (patch) | |
tree | 280cc0da0321b55e23f731b9d3c6b5e04830d7cf | |
parent | 70393c8717c7b3b192928e652e103f12ff89a483 (diff) | |
download | justbuild-6c4ecdb57f9140dc8474da2f83660fc5f977cc6d.tar.gz |
Computed roots: extend data structure to support the absent pragma
-rw-r--r-- | share/man/just-repository-config.5.md | 12 | ||||
-rw-r--r-- | src/buildtool/file_system/precomputed_root.cpp | 43 | ||||
-rw-r--r-- | src/buildtool/file_system/precomputed_root.hpp | 1 | ||||
-rw-r--r-- | src/other_tools/utils/parse_precomputed_root.cpp | 6 |
4 files changed, 49 insertions, 13 deletions
diff --git a/share/man/just-repository-config.5.md b/share/man/just-repository-config.5.md index 9d038641..ca272ea4 100644 --- a/share/man/just-repository-config.5.md +++ b/share/man/just-repository-config.5.md @@ -37,10 +37,14 @@ which determines the type and semantic of the subsequent elements: entry is missing, the root is considered absent and any target requiring this root has to come from a specified serve end point. - - *`"computed"`* refers to a file root that is the result of evaluating - an export target of a content-fixed repository. The list has to have - length 5, with the remaining arguments being the global repository name, - the module name, the target name, and the configuration, in that order. + - *`"computed"`* refers to a file root that is the result of + evaluating an export target of a content-fixed repository. The + list has to have length 5 or 6, with the remaining arguments + being the global repository name, the module name, the target + name, and the configuration, in that order, optionally followed + by a pragma object. If the pragma object contains the entry + `true` for the key `"absent"`, that root is considered absent, + otherwise not. - *`"tree structure"`* refers to the directory structure of a file root. The list has to have length 2 or 3. The second argument contains the diff --git a/src/buildtool/file_system/precomputed_root.cpp b/src/buildtool/file_system/precomputed_root.cpp index 0ff02628..73d99ef1 100644 --- a/src/buildtool/file_system/precomputed_root.cpp +++ b/src/buildtool/file_system/precomputed_root.cpp @@ -51,10 +51,12 @@ template <typename T> template <> [[nodiscard]] auto ParseImpl<ComputedRoot>(nlohmann::json const& root) -> expected<ComputedRoot, std::string> { - if (root.size() != ComputedRoot::kSchemeLength) { + if ((root.size() != ComputedRoot::kSchemeLength) and + (root.size() != ComputedRoot::kSchemeLength + 1)) { return unexpected{fmt::format( "The root has a wrong number of arguments: {}\nThe scheme requires " - "[<scheme>, <root>, <module>, <name>, <config>]", + "[<scheme>, <root>, <module>, <name>, <config>] optionally " + "followed by a pragma object", root.dump())}; } @@ -77,14 +79,37 @@ template <> if (not root[4].is_object()) { return unexpected{ fmt::format("The root has a wrong type of <config>. Expected a " - "plain json, got {}", + "plain json object, got {}", root[4].dump())}; } + auto absent = false; + + if (root.size() > ComputedRoot::kSchemeLength) { + if (not root[ComputedRoot::kSchemeLength].is_object()) { + return unexpected{ + fmt::format("The root has a wrong type of optional pragma " + "argument. Expected a " + "plain json object, got {}", + root[ComputedRoot::kSchemeLength].dump())}; + } + if (root[ComputedRoot::kSchemeLength].contains("absent")) { + auto absent_entry = root[ComputedRoot::kSchemeLength]["absent"]; + if (not absent_entry.is_boolean()) { + return unexpected{ + fmt::format("Expected pragma entry \"absent\" to be " + "boolean, but found {}", + absent_entry.dump())}; + } + absent = absent_entry; + } + } + return ComputedRoot{.repository = std::string{root[1]}, .target_module = std::string{root[2]}, .target_name = std::string{root[3]}, - .config = root[4]}; + .config = root[4], + .absent = absent}; } template <> @@ -135,7 +160,8 @@ auto ComputedRoot::operator==(ComputedRoot const& other) const noexcept -> bool { return repository == other.repository and target_module == other.target_module and - target_name == other.target_name and config == other.config; + target_name == other.target_name and config == other.config and + absent == other.absent; } auto ComputedRoot::operator<(ComputedRoot const& other) const noexcept -> bool { @@ -148,14 +174,18 @@ auto ComputedRoot::operator<(ComputedRoot const& other) const noexcept -> bool { if (auto const res = target_name <=> other.target_name; res != 0) { return res < 0; } + if (absent != other.absent) { + return absent; + } return config < other.config; } auto ComputedRoot::ToString() const -> std::string { - return fmt::format("([\"@\", {}, {}, {}], {})", + return fmt::format("([\"@\", {}, {}, {}{}], {})", nlohmann::json(repository).dump(), nlohmann::json(target_module).dump(), nlohmann::json(target_name).dump(), + absent ? ", {\"absent\": true}" : "", config.dump()); } @@ -165,6 +195,7 @@ auto ComputedRoot::ComputeHash() const -> std::size_t { hash_combine<std::string>(&seed, repository); hash_combine<std::string>(&seed, target_module); hash_combine<std::string>(&seed, target_name); + hash_combine<bool>(&seed, absent); hash_combine<nlohmann::json>(&seed, config); return seed; } diff --git a/src/buildtool/file_system/precomputed_root.hpp b/src/buildtool/file_system/precomputed_root.hpp index f3495418..f95f7d73 100644 --- a/src/buildtool/file_system/precomputed_root.hpp +++ b/src/buildtool/file_system/precomputed_root.hpp @@ -33,6 +33,7 @@ struct ComputedRoot final { std::string target_module; std::string target_name; nlohmann::json config; + bool absent; [[nodiscard]] auto operator==(ComputedRoot 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 f30316e6..c5eebf90 100644 --- a/src/other_tools/utils/parse_precomputed_root.cpp +++ b/src/other_tools/utils/parse_precomputed_root.cpp @@ -84,9 +84,9 @@ namespace { return ComputedRoot{.repository = repo->String(), .target_module = target_module->String(), .target_name = target_module->String(), - .config = config.IsNotNull() - ? config->ToJson() - : nlohmann::json::object()}; + .config = config.IsNotNull() ? config->ToJson() + : nlohmann::json::object(), + .absent = false}; } [[nodiscard]] auto ParseTreeStructureRoot(ExpressionPtr const& repository) |