summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/other_tools/repo_map/repos_to_setup_map.cpp24
-rw-r--r--src/other_tools/root_maps/commit_git_map.cpp42
-rw-r--r--src/other_tools/root_maps/commit_git_map.hpp2
3 files changed, 64 insertions, 4 deletions
diff --git a/src/other_tools/repo_map/repos_to_setup_map.cpp b/src/other_tools/repo_map/repos_to_setup_map.cpp
index a65a6c50..d0396a0c 100644
--- a/src/other_tools/repo_map/repos_to_setup_map.cpp
+++ b/src/other_tools/repo_map/repos_to_setup_map.cpp
@@ -92,6 +92,29 @@ void GitCheckout(ExpressionPtr const& repo_desc,
? repo_desc_subdir->String()
: "")
.lexically_normal();
+ // 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("GitCheckout: Unsupported list entry {} "
+ "in optional field \"mirrors\"",
+ elem->ToString()),
+ /*fatal=*/true);
+ return;
+ }
+ mirrors.emplace_back(elem->String());
+ }
+ }
+ else {
+ (*logger)(fmt::format("GitCheckout: Optional field \"mirrors\" should "
+ "be a list of strings, but found: {}",
+ repo_desc_mirrors->ToString()),
+ /*fatal=*/true);
+ return;
+ }
// check "special" pragma
auto repo_desc_pragma = repo_desc->At("pragma");
auto pragma_special = repo_desc_pragma
@@ -115,6 +138,7 @@ void GitCheckout(ExpressionPtr const& repo_desc,
.repo_url = repo_desc_repository->get()->String(),
.branch = repo_desc_branch->get()->String(),
.subdir = subdir.empty() ? "." : subdir.string(),
+ .mirrors = std::move(mirrors),
.origin = repo_name,
.ignore_special = pragma_special_value == PragmaSpecial::Ignore,
.absent = pragma_absent_value};
diff --git a/src/other_tools/root_maps/commit_git_map.cpp b/src/other_tools/root_maps/commit_git_map.cpp
index 40399811..6959dfe6 100644
--- a/src/other_tools/root_maps/commit_git_map.cpp
+++ b/src/other_tools/root_maps/commit_git_map.cpp
@@ -355,18 +355,52 @@ void EnsureCommit(GitRepoInfo const& repo_info,
/*fatal=*/true);
return;
}
- // setup wrapped logger
+ // store failed attempts for subsequent logging
+ std::string err_messages{};
auto wrapped_logger = std::make_shared<AsyncMapConsumerLogger>(
- [logger](auto const& msg, bool fatal) {
- (*logger)(fmt::format("While fetching via tmp repo:\n{}", msg),
- fatal);
+ [fetch_repo, &err_messages](auto const& msg, bool /*fatal*/) {
+ err_messages +=
+ fmt::format("\nWhile attempting fetch from remote {}:\n{}",
+ fetch_repo,
+ msg);
});
+ // try the main fetch URL
+ bool fetched{false};
if (not git_repo->FetchViaTmpRepo(tmp_dir->GetPath(),
fetch_repo,
repo_info.branch,
git_bin,
launcher,
wrapped_logger)) {
+ // try to fetch from mirrors, in order, if given
+ for (auto mirror : repo_info.mirrors) {
+ if (GitURLIsPath(mirror)) {
+ mirror = std::filesystem::absolute(mirror).string();
+ }
+ wrapped_logger = std::make_shared<AsyncMapConsumerLogger>(
+ [mirror, &err_messages](auto const& msg, bool /*fatal*/) {
+ err_messages += fmt::format(
+ "\nWhile attempting fetch from mirror {}:\n{}",
+ mirror,
+ msg);
+ });
+ if (git_repo->FetchViaTmpRepo(tmp_dir->GetPath(),
+ mirror,
+ repo_info.branch,
+ git_bin,
+ launcher,
+ wrapped_logger)) {
+ fetched = true;
+ break;
+ }
+ }
+ }
+ if (not fetched) {
+ // log fetch failure details separately to reduce verbosity
+ (*logger)(
+ fmt::format("While fetching via tmp repo:{}", err_messages),
+ /*fatal=*/false);
+ (*logger)("Failed to fetch from provided remotes", /*fatal=*/true);
return;
}
// setup wrapped logger
diff --git a/src/other_tools/root_maps/commit_git_map.hpp b/src/other_tools/root_maps/commit_git_map.hpp
index 26ed018b..a85f04e1 100644
--- a/src/other_tools/root_maps/commit_git_map.hpp
+++ b/src/other_tools/root_maps/commit_git_map.hpp
@@ -17,6 +17,7 @@
#include <string>
#include <utility>
+#include <vector>
#include "nlohmann/json.hpp"
#include "src/buildtool/common/user_structs.hpp"
@@ -32,6 +33,7 @@ struct GitRepoInfo {
std::string repo_url{};
std::string branch{};
std::string subdir{}; /* key */
+ std::vector<std::string> mirrors{};
// name of repository for which work is done; used in progress reporting
std::string origin{};
// create root that ignores symlinks