summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2025-01-10 12:43:48 +0100
committerKlaus Aehlig <klaus.aehlig@huawei.com>2025-01-22 10:40:32 +0100
commit6c4ecdb57f9140dc8474da2f83660fc5f977cc6d (patch)
tree280cc0da0321b55e23f731b9d3c6b5e04830d7cf
parent70393c8717c7b3b192928e652e103f12ff89a483 (diff)
downloadjustbuild-6c4ecdb57f9140dc8474da2f83660fc5f977cc6d.tar.gz
Computed roots: extend data structure to support the absent pragma
-rw-r--r--share/man/just-repository-config.5.md12
-rw-r--r--src/buildtool/file_system/precomputed_root.cpp43
-rw-r--r--src/buildtool/file_system/precomputed_root.hpp1
-rw-r--r--src/other_tools/utils/parse_precomputed_root.cpp6
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)