summaryrefslogtreecommitdiff
path: root/src/other_tools/utils/parse_archive.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/other_tools/utils/parse_archive.cpp')
-rw-r--r--src/other_tools/utils/parse_archive.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/other_tools/utils/parse_archive.cpp b/src/other_tools/utils/parse_archive.cpp
new file mode 100644
index 00000000..ff5d20bf
--- /dev/null
+++ b/src/other_tools/utils/parse_archive.cpp
@@ -0,0 +1,133 @@
+// Copyright 2024 Huawei Cloud Computing Technology Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/other_tools/utils/parse_archive.hpp"
+
+namespace {
+auto ParseArchiveContent(ExpressionPtr const& repo_desc,
+ std::string const& origin,
+ const AsyncMapConsumerLoggerPtr& logger)
+ -> std::optional<ArchiveContent> {
+
+ // enforce mandatory fields
+ auto repo_desc_content = repo_desc->At("content");
+ if (not repo_desc_content) {
+ (*logger)("ArchiveCheckout: Mandatory field \"content\" is missing",
+ /*fatal=*/true);
+ return std::nullopt;
+ }
+ if (not repo_desc_content->get()->IsString()) {
+ (*logger)(fmt::format("ArchiveCheckout: Unsupported value {} for "
+ "mandatory field \"content\"",
+ repo_desc_content->get()->ToString()),
+ /*fatal=*/true);
+ return std::nullopt;
+ }
+ auto repo_desc_fetch = repo_desc->At("fetch");
+ if (not repo_desc_fetch) {
+ (*logger)("ArchiveCheckout: Mandatory field \"fetch\" is missing",
+ /*fatal=*/true);
+ return std::nullopt;
+ }
+ if (not repo_desc_fetch->get()->IsString()) {
+ (*logger)(fmt::format("ArchiveCheckout: Unsupported value {} for "
+ "mandatory field \"fetch\"",
+ repo_desc_fetch->get()->ToString()),
+ /*fatal=*/true);
+ return std::nullopt;
+ }
+ auto repo_desc_distfile = repo_desc->Get("distfile", Expression::none_t{});
+ auto repo_desc_sha256 = repo_desc->Get("sha256", Expression::none_t{});
+ auto repo_desc_sha512 = repo_desc->Get("sha512", Expression::none_t{});
+ // check optional mirrors
+ auto repo_desc_mirrors = repo_desc->Get("mirrors", Expression::list_t{});
+ std::vector<std::string> mirrors{};
+ if (repo_desc_mirrors->IsList()) {
+ mirrors.reserve(repo_desc_mirrors->List().size());
+ for (auto const& elem : repo_desc_mirrors->List()) {
+ if (not elem->IsString()) {
+ (*logger)(fmt::format("ArchiveCheckout: Unsupported list entry "
+ "{} in optional field \"mirrors\"",
+ elem->ToString()),
+ /*fatal=*/true);
+ return std::nullopt;
+ }
+ mirrors.emplace_back(elem->String());
+ }
+ }
+ else {
+ (*logger)(fmt::format("ArchiveCheckout: Optional field \"mirrors\" "
+ "should be a list of strings, but found: {}",
+ repo_desc_mirrors->ToString()),
+ /*fatal=*/true);
+ return std::nullopt;
+ }
+
+ return ArchiveContent{
+ .content = repo_desc_content->get()->String(),
+ .distfile = repo_desc_distfile->IsString()
+ ? std::make_optional(repo_desc_distfile->String())
+ : std::nullopt,
+ .fetch_url = repo_desc_fetch->get()->String(),
+ .mirrors = std::move(mirrors),
+ .sha256 = repo_desc_sha256->IsString()
+ ? std::make_optional(repo_desc_sha256->String())
+ : std::nullopt,
+ .sha512 = repo_desc_sha512->IsString()
+ ? std::make_optional(repo_desc_sha512->String())
+ : std::nullopt,
+ .origin = origin};
+}
+} // namespace
+
+auto ParseArchiveDescription(ExpressionPtr const& repo_desc,
+ std::string const& repo_type,
+ std::string const& origin,
+ const AsyncMapConsumerLoggerPtr& logger)
+ -> std::optional<ArchiveRepoInfo> {
+ auto archive_content = ParseArchiveContent(repo_desc, origin, logger);
+ if (not archive_content) {
+ return std::nullopt;
+ }
+ // additional mandatory fields
+ auto repo_desc_subdir = repo_desc->Get("subdir", Expression::none_t{});
+ auto subdir = std::filesystem::path(repo_desc_subdir->IsString()
+ ? repo_desc_subdir->String()
+ : "")
+ .lexically_normal();
+
+ // check "special" pragma
+ auto repo_desc_pragma = repo_desc->At("pragma");
+ bool const& pragma_is_map =
+ repo_desc_pragma and repo_desc_pragma->get()->IsMap();
+ auto pragma_special =
+ pragma_is_map ? repo_desc_pragma->get()->At("special") : std::nullopt;
+ auto pragma_special_value =
+ pragma_special and pragma_special->get()->IsString() and
+ kPragmaSpecialMap.contains(pragma_special->get()->String())
+ ? std::make_optional(
+ kPragmaSpecialMap.at(pragma_special->get()->String()))
+ : std::nullopt;
+ // check "absent" pragma
+ auto pragma_absent =
+ pragma_is_map ? repo_desc_pragma->get()->At("absent") : std::nullopt;
+ auto pragma_absent_value = pragma_absent and
+ pragma_absent->get()->IsBool() and
+ pragma_absent->get()->Bool();
+ return ArchiveRepoInfo{.archive = *archive_content,
+ .repo_type = repo_type,
+ .subdir = subdir.empty() ? "." : subdir.string(),
+ .pragma_special = pragma_special_value,
+ .absent = pragma_absent_value};
+}