summaryrefslogtreecommitdiff
path: root/src/other_tools/root_maps/fpath_git_map.cpp
diff options
context:
space:
mode:
authorPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2024-01-11 13:03:33 +0100
committerPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2024-01-26 14:51:43 +0100
commite3d36d2c7bb91b1f5a043cefca3f4a6a5a5c9540 (patch)
tree338884e0f967d82647a82359ad989dd6ce7d9891 /src/other_tools/root_maps/fpath_git_map.cpp
parent9942c2762695c57b92ad5e8f83e283a2d68f4d0b (diff)
downloadjustbuild-e3d36d2c7bb91b1f5a043cefca3f4a6a5a5c9540.tar.gz
fpath_git_map: Sync pragma 'to_git' root trees with serve endpoint
Marking a file-type repository as 'to_git' results in a Git-tree type root, which are of course content fixed and can be (and usually are) used by export targets. Therefore, it is beneficial for a serve endpoint, if one is provided, to be aware of such a root and be able to build against it if needed. If the root is marked as absent, this condition becomes mandatory. Generating an absent Git-tree root without being provided a serve endpoint is still allowed, but results in a warning.
Diffstat (limited to 'src/other_tools/root_maps/fpath_git_map.cpp')
-rw-r--r--src/other_tools/root_maps/fpath_git_map.cpp127
1 files changed, 102 insertions, 25 deletions
diff --git a/src/other_tools/root_maps/fpath_git_map.cpp b/src/other_tools/root_maps/fpath_git_map.cpp
index 79767b95..7ca438c1 100644
--- a/src/other_tools/root_maps/fpath_git_map.cpp
+++ b/src/other_tools/root_maps/fpath_git_map.cpp
@@ -22,10 +22,64 @@
#include "src/buildtool/storage/config.hpp"
#include "src/buildtool/storage/fs_utils.hpp"
#include "src/other_tools/git_operations/git_repo_remote.hpp"
+#include "src/other_tools/root_maps/root_utils.hpp"
#include "src/utils/cpp/tmp_dir.hpp"
namespace {
+/// \brief Does the serve endpoint checks and sets the workspace root.
+/// It guarantees the logger is called exactly once with fatal on failure, and
+/// the setter on success.
+void CheckServeAndSetRoot(
+ std::string const& tree_id,
+ std::string const& repo_root,
+ bool absent,
+ bool serve_api_exists,
+ std::optional<gsl::not_null<IExecutionApi*>> const& remote_api,
+ FilePathGitMap::SetterPtr const& ws_setter,
+ FilePathGitMap::LoggerPtr const& logger) {
+ // if serve endpoint is given, try to ensure it has this tree available to
+ // be able to build against it
+ if (serve_api_exists) {
+ auto has_tree = CheckServeHasAbsentRoot(tree_id, logger);
+ if (not has_tree) {
+ return; // fatal
+ }
+ if (not *has_tree) {
+ if (not remote_api) {
+ (*logger)(fmt::format(
+ "Missing remote-execution endpoint needed to "
+ "sync workspace root {} with the serve endpoint.",
+ tree_id),
+ /*fatal=*/true);
+ return;
+ }
+ if (not EnsureAbsentRootOnServe(tree_id,
+ repo_root,
+ remote_api,
+ logger,
+ /*no_sync_is_fatal=*/absent)) {
+ return; // fatal
+ }
+ }
+ }
+ else {
+ if (absent) {
+ // give warning
+ (*logger)(fmt::format("Workspace root {} marked absent but no "
+ "serve endpoint provided.",
+ tree_id),
+ /*fatal=*/false);
+ }
+ }
+ // set the workspace root
+ auto root = nlohmann::json::array({FileRoot::kGitTreeMarker, tree_id});
+ if (not absent) {
+ root.emplace_back(repo_root);
+ }
+ (*ws_setter)(std::move(root));
+}
+
void ResolveFilePathTree(
std::string const& repo_root,
std::string const& target_path,
@@ -33,6 +87,8 @@ void ResolveFilePathTree(
std::optional<PragmaSpecial> const& pragma_special,
bool absent,
gsl::not_null<ResolveSymlinksMap*> const& resolve_symlinks_map,
+ bool serve_api_exists,
+ std::optional<gsl::not_null<IExecutionApi*>> const& remote_api,
gsl::not_null<TaskSystem*> const& ts,
FilePathGitMap::SetterPtr const& ws_setter,
FilePathGitMap::LoggerPtr const& logger) {
@@ -44,19 +100,21 @@ void ResolveFilePathTree(
// read resolved tree id
auto resolved_tree_id = FileSystemManager::ReadFile(tree_id_file);
if (not resolved_tree_id) {
- (*logger)(fmt::format("Failed to read resolved "
- "tree id from file {}",
- tree_id_file.string()),
- /*fatal=*/true);
+ (*logger)(
+ fmt::format("Failed to read resolved tree id from file {}",
+ tree_id_file.string()),
+ /*fatal=*/true);
return;
}
- // set the workspace root
- auto root = nlohmann::json::array(
- {FileRoot::kGitTreeMarker, *resolved_tree_id});
- if (not absent) {
- root.emplace_back(repo_root);
- }
- (*ws_setter)(std::move(root));
+ // if serve endpoint is given, try to ensure it has this tree
+ // available to be able to build against it
+ CheckServeAndSetRoot(*resolved_tree_id,
+ repo_root,
+ absent,
+ serve_api_exists,
+ remote_api,
+ ws_setter,
+ logger);
}
else {
// resolve tree
@@ -71,6 +129,8 @@ void ResolveFilePathTree(
repo_root,
tree_id_file,
absent,
+ serve_api_exists,
+ remote_api,
ws_setter,
logger](auto const& hashes) {
if (not hashes[0]) {
@@ -101,13 +161,15 @@ void ResolveFilePathTree(
/*fatal=*/true);
return;
}
- // set the workspace root
- auto root = nlohmann::json::array(
- {FileRoot::kGitTreeMarker, resolved_tree.id});
- if (not absent) {
- root.emplace_back(repo_root);
- }
- (*ws_setter)(std::move(root));
+ // if serve endpoint is given, try to ensure it has this
+ // tree available to be able to build against it
+ CheckServeAndSetRoot(resolved_tree.id,
+ repo_root,
+ absent,
+ serve_api_exists,
+ remote_api,
+ ws_setter,
+ logger);
},
[logger, target_path](auto const& msg, bool fatal) {
(*logger)(fmt::format(
@@ -119,13 +181,16 @@ void ResolveFilePathTree(
}
}
else {
- // set the workspace root as-is
- auto root =
- nlohmann::json::array({FileRoot::kGitTreeMarker, tree_hash});
- if (not absent) {
- root.emplace_back(repo_root);
- }
- (*ws_setter)(std::move(root));
+ // tree needs no further processing;
+ // if serve endpoint is given, try to ensure it has this tree available
+ // to be able to build against it
+ CheckServeAndSetRoot(tree_hash,
+ repo_root,
+ absent,
+ serve_api_exists,
+ remote_api,
+ ws_setter,
+ logger);
}
}
@@ -136,6 +201,8 @@ auto CreateFilePathGitMap(
gsl::not_null<CriticalGitOpMap*> const& critical_git_op_map,
gsl::not_null<ImportToGitMap*> const& import_to_git_map,
gsl::not_null<ResolveSymlinksMap*> const& resolve_symlinks_map,
+ bool serve_api_exists,
+ std::optional<gsl::not_null<IExecutionApi*>> const& remote_api,
std::size_t jobs,
std::string multi_repo_tool_name,
std::string build_tool_name) -> FilePathGitMap {
@@ -143,6 +210,8 @@ auto CreateFilePathGitMap(
critical_git_op_map,
import_to_git_map,
resolve_symlinks_map,
+ serve_api_exists,
+ remote_api,
multi_repo_tool_name,
build_tool_name](auto ts,
auto setter,
@@ -196,6 +265,8 @@ auto CreateFilePathGitMap(
git_cas = std::move(git_cas),
repo_root = std::move(*repo_root),
resolve_symlinks_map,
+ serve_api_exists,
+ remote_api,
ts,
setter,
logger](auto const& values) {
@@ -237,6 +308,8 @@ auto CreateFilePathGitMap(
pragma_special,
absent,
resolve_symlinks_map,
+ serve_api_exists,
+ remote_api,
ts,
setter,
logger);
@@ -291,6 +364,8 @@ auto CreateFilePathGitMap(
pragma_special = key.pragma_special,
absent = key.absent,
resolve_symlinks_map,
+ serve_api_exists,
+ remote_api,
ts,
setter,
logger](auto const& values) {
@@ -309,6 +384,8 @@ auto CreateFilePathGitMap(
pragma_special,
absent,
resolve_symlinks_map,
+ serve_api_exists,
+ remote_api,
ts,
setter,
logger);