diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/other_tools/just_mr/setup.cpp | 20 | ||||
-rw-r--r-- | src/other_tools/root_maps/TARGETS | 6 | ||||
-rw-r--r-- | src/other_tools/root_maps/content_git_map.cpp | 780 | ||||
-rw-r--r-- | src/other_tools/root_maps/content_git_map.hpp | 8 |
4 files changed, 695 insertions, 119 deletions
diff --git a/src/other_tools/just_mr/setup.cpp b/src/other_tools/just_mr/setup.cpp index b98fbc25..1d698e3a 100644 --- a/src/other_tools/just_mr/setup.cpp +++ b/src/other_tools/just_mr/setup.cpp @@ -95,7 +95,7 @@ auto MultiRepoSetup(std::shared_ptr<Configuration> const& config, IExecutionApi::Ptr local_api{remote_api ? std::make_unique<LocalApi>() : nullptr}; - // setup the API for serving tree of known commit + // setup the API for serving trees of Gti repos or archives auto serve_api = JustMR::Utils::SetupServeApi( common_args.remote_serve_address, auth_args); @@ -126,12 +126,18 @@ auto MultiRepoSetup(std::shared_ptr<Configuration> const& config, remote_api ? &(*remote_api) : nullptr, common_args.fetch_absent, common_args.jobs); - auto content_git_map = CreateContentGitMap(&content_cas_map, - &import_to_git_map, - &resolve_symlinks_map, - &critical_git_op_map, - common_args.fetch_absent, - common_args.jobs); + auto content_git_map = + CreateContentGitMap(&content_cas_map, + &import_to_git_map, + common_args.just_mr_paths, + common_args.ca_info, + &resolve_symlinks_map, + &critical_git_op_map, + serve_api ? &(*serve_api) : nullptr, + local_api ? &(*local_api) : nullptr, + remote_api ? &(*remote_api) : nullptr, + common_args.fetch_absent, + common_args.jobs); auto fpath_git_map = CreateFilePathGitMap(just_cmd_args.subcmd_name, &critical_git_op_map, &import_to_git_map, diff --git a/src/other_tools/root_maps/TARGETS b/src/other_tools/root_maps/TARGETS index 656e1fab..6d3cd6e4 100644 --- a/src/other_tools/root_maps/TARGETS +++ b/src/other_tools/root_maps/TARGETS @@ -81,7 +81,10 @@ , "hdrs": ["content_git_map.hpp"] , "srcs": ["content_git_map.cpp"] , "deps": - [ ["src/other_tools/ops_maps", "content_cas_map"] + [ ["src/buildtool/serve_api/remote", "serve_api"] + , ["src/buildtool/execution_api/common", "common"] + , ["src/buildtool/common", "user_structs"] + , ["src/other_tools/ops_maps", "content_cas_map"] , ["src/other_tools/ops_maps", "import_to_git_map"] , ["src/buildtool/file_system/symlinks_map", "resolve_symlinks_map"] ] @@ -99,6 +102,7 @@ , ["src/buildtool/file_system", "file_root"] , ["src/buildtool/file_system", "git_repo"] , ["src/other_tools/git_operations", "git_repo_remote"] + , ["src/other_tools/utils", "content"] ] } , "tree_id_git_map": diff --git a/src/other_tools/root_maps/content_git_map.cpp b/src/other_tools/root_maps/content_git_map.cpp index 19c8644a..bc9f55a2 100644 --- a/src/other_tools/root_maps/content_git_map.cpp +++ b/src/other_tools/root_maps/content_git_map.cpp @@ -22,6 +22,7 @@ #include "src/buildtool/storage/storage.hpp" #include "src/other_tools/just_mr/progress_reporting/progress.hpp" #include "src/other_tools/just_mr/progress_reporting/statistics.hpp" +#include "src/other_tools/utils/content.hpp" #include "src/utils/archive/archive_ops.hpp" namespace { @@ -148,19 +149,176 @@ void ResolveContentTree( } } +// Helper function for improved readability. It guarantees the logger is called +// exactly once with fatal if failure. +void WriteIdFileAndSetWSRoot( + std::string const& archive_tree_id, + GitCASPtr const& just_git_cas, + std::filesystem::path const& archive_tree_id_file, + std::string const& content_id, + std::string const& subdir, + std::optional<PragmaSpecial> const& pragma_special, + bool absent, + bool fetch_absent, + gsl::not_null<ResolveSymlinksMap*> const& resolve_symlinks_map, + gsl::not_null<TaskSystem*> const& ts, + ContentGitMap::SetterPtr const& setter, + ContentGitMap::LoggerPtr const& logger) { + // write to tree id file + if (not StorageUtils::WriteTreeIDFile(archive_tree_id_file, + archive_tree_id)) { + (*logger)(fmt::format("Failed to write tree id to file {}", + archive_tree_id_file.string()), + /*fatal=*/true); + return; + } + // we look for subtree in Git cache + auto just_git_repo = GitRepoRemote::Open(just_git_cas); + if (not just_git_repo) { + (*logger)("Could not open Git cache repository!", + /*fatal=*/true); + return; + } + // setup wrapped logger + auto wrapped_logger = std::make_shared<AsyncMapConsumerLogger>( + [&logger, subdir, tree = archive_tree_id](auto const& msg, bool fatal) { + (*logger)(fmt::format("While getting subdir {} from tree {}:\n{}", + subdir, + tree, + msg), + fatal); + }); + // get subtree id + auto subtree_hash = just_git_repo->GetSubtreeFromTree( + archive_tree_id, subdir, wrapped_logger); + if (not subtree_hash) { + return; + } + // resolve tree and set workspace root + ResolveContentTree(content_id, + *subtree_hash, + false, /*is_cache_hit*/ + pragma_special, + absent, + fetch_absent, + resolve_symlinks_map, + ts, + setter, + logger); +} + +// Helper function for improved readability. It guarantees the logger is called +// exactly once with fatal if failure. +void ExtractAndImportToGit( + std::filesystem::path const& content_cas_path, + std::filesystem::path const& archive_tree_id_file, + std::string const& repo_type, + std::string const& content_id, + std::string const& subdir, + std::optional<PragmaSpecial> const& pragma_special, + bool absent, + bool fetch_absent, + gsl::not_null<ImportToGitMap*> const& import_to_git_map, + gsl::not_null<ResolveSymlinksMap*> const& resolve_symlinks_map, + gsl::not_null<TaskSystem*> const& ts, + ContentGitMap::SetterPtr const& setter, + ContentGitMap::LoggerPtr const& logger) { + // extract archive + auto tmp_dir = StorageUtils::CreateTypedTmpDir(repo_type); + if (not tmp_dir) { + (*logger)(fmt::format("Failed to create tmp path for {} target {}", + repo_type, + content_id), + /*fatal=*/true); + return; + } + auto res = ExtractArchive(content_cas_path, repo_type, tmp_dir->GetPath()); + if (res != std::nullopt) { + (*logger)(fmt::format("Failed to extract archive {} " + "from CAS with error: {}", + content_cas_path.string(), + *res), + /*fatal=*/true); + return; + } + // import to git + CommitInfo c_info{tmp_dir->GetPath(), repo_type, content_id}; + import_to_git_map->ConsumeAfterKeysReady( + ts, + {std::move(c_info)}, + [tmp_dir, // keep tmp_dir alive + archive_tree_id_file, + content_id, + subdir, + pragma_special, + absent, + fetch_absent, + resolve_symlinks_map, + ts, + setter, + logger](auto const& values) { + // check for errors + if (not values[0]->second) { + (*logger)("Importing to git failed", + /*fatal=*/true); + return; + } + // only tree id is needed + std::string archive_tree_id = values[0]->first; + // open Git CAS + auto just_git_cas = GitCAS::Open(StorageConfig::GitRoot()); + if (not just_git_cas) { + (*logger)("Could not open Git cache object database!", + /*fatal=*/true); + return; + } + // write to id file and process subdir tree + WriteIdFileAndSetWSRoot(archive_tree_id, + just_git_cas, + archive_tree_id_file, + content_id, + subdir, + pragma_special, + absent, + fetch_absent, + resolve_symlinks_map, + ts, + setter, + logger); + }, + [logger, target_path = tmp_dir->GetPath()](auto const& msg, + bool fatal) { + (*logger)(fmt::format("While importing target {} " + "to Git:\n{}", + target_path.string(), + msg), + fatal); + }); +} + } // namespace auto CreateContentGitMap( gsl::not_null<ContentCASMap*> const& content_cas_map, gsl::not_null<ImportToGitMap*> const& import_to_git_map, + LocalPathsPtr const& just_mr_paths, + CAInfoPtr const& ca_info, gsl::not_null<ResolveSymlinksMap*> const& resolve_symlinks_map, gsl::not_null<CriticalGitOpMap*> const& critical_git_op_map, + ServeApi* serve_api, + IExecutionApi* local_api, + IExecutionApi* remote_api, bool fetch_absent, std::size_t jobs) -> ContentGitMap { auto gitify_content = [content_cas_map, import_to_git_map, resolve_symlinks_map, critical_git_op_map, + just_mr_paths, + ca_info, + serve_api, + local_api, + remote_api, fetch_absent](auto ts, auto setter, auto logger, @@ -255,7 +413,504 @@ auto CreateContentGitMap( }); } else { - // do the fetch and import_to_git + if (key.absent) { + // check if content already in CAS + auto const& cas = Storage::Instance().CAS(); + auto digest = ArtifactDigest(key.archive.content, 0, false); + if (auto content_cas_path = + cas.BlobPath(digest, /*is_executable=*/false)) { + ExtractAndImportToGit(*content_cas_path, + archive_tree_id_file, + key.repo_type, + key.archive.content, + key.subdir, + key.pragma_special, + key.absent, + fetch_absent, + import_to_git_map, + resolve_symlinks_map, + ts, + setter, + logger); + // done + return; + } + JustMRProgress::Instance().TaskTracker().Start( + key.archive.origin); + // add disfile to CAS + auto repo_distfile = + (key.archive.distfile + ? key.archive.distfile.value() + : std::filesystem::path(key.archive.fetch_url) + .filename() + .string()); + StorageUtils::AddDistfileToCAS(repo_distfile, just_mr_paths); + // check if content is in CAS now + if (auto content_cas_path = + cas.BlobPath(digest, /*is_executable=*/false)) { + JustMRProgress::Instance().TaskTracker().Stop( + key.archive.origin); + ExtractAndImportToGit(*content_cas_path, + archive_tree_id_file, + key.repo_type, + key.archive.content, + key.subdir, + key.pragma_special, + key.absent, + fetch_absent, + import_to_git_map, + resolve_symlinks_map, + ts, + setter, + logger); + // done + return; + } + // check if content is known to remote serve service + if (serve_api != nullptr) { + // if fetching absent, request (and sync) the whole archive + // tree, UNRESOLVED, to ensure we maintain the id file + // association + if (fetch_absent) { + if (auto root_tree_id = + serve_api->RetrieveTreeFromArchive( + key.archive.content, + key.repo_type, + /*subdir = */ ".", + /* resolve_symlinks = */ std::nullopt, + /*sync_tree = */ true)) { + // ensure Git cache + // define Git operation to be done + GitOpKey op_key = { + .params = + { + StorageConfig:: + GitRoot(), // target_path + "", // git_hash + "", // branch + std::nullopt, // message + true // init_bare + }, + .op_type = GitOpType::ENSURE_INIT}; + critical_git_op_map->ConsumeAfterKeysReady( + ts, + {std::move(op_key)}, + [root_tree_id, + repo_type = key.repo_type, + subdir = key.subdir, + archive_tree_id_file, + content = key.archive.content, + fetch_url = key.archive.fetch_url, + sha256 = key.archive.sha256, + sha512 = key.archive.sha512, + pragma_special = key.pragma_special, + ca_info, + origin = key.archive.origin, + absent = key.absent, + fetch_absent, + import_to_git_map, + resolve_symlinks_map, + local_api, + remote_api, + ts, + setter, + logger](auto const& values) { + GitOpValue op_result = *values[0]; + // check flag + if (not op_result.result) { + (*logger)("Git init failed", + /*fatal=*/true); + return; + } + // verify if we know the tree already + // locally + auto just_git_cas = + GitCAS::Open(StorageConfig::GitRoot()); + if (not just_git_cas) { + (*logger)( + "Could not open Git cache object " + "database!", + /*fatal=*/true); + return; + } + auto just_git_repo = + GitRepoRemote::Open(just_git_cas); + if (not just_git_repo) { + (*logger)( + "Could not open Git cache " + "repository!", + /*fatal=*/true); + return; + } + // setup wrapped logger + auto wrapped_logger = std::make_shared< + AsyncMapConsumerLogger>( + [&logger, tree = *root_tree_id]( + auto const& msg, bool fatal) { + (*logger)( + fmt::format( + "While verifying presence " + "of tree {}:\n{}", + tree, + msg), + fatal); + }); + auto tree_present = + just_git_repo->CheckTreeExists( + *root_tree_id, wrapped_logger); + if (not tree_present) { + return; + } + if (*tree_present) { + JustMRProgress::Instance() + .TaskTracker() + .Stop(origin); + // write to id file and process subdir + // tree + WriteIdFileAndSetWSRoot( + *root_tree_id, + just_git_cas, + archive_tree_id_file, + content, + subdir, + pragma_special, + absent, + fetch_absent, + resolve_symlinks_map, + ts, + setter, + logger); + // done + return; + } + // try to get root tree from remote + // execution endpoint + auto root_digest = ArtifactDigest{ + *root_tree_id, 0, /*is_tree=*/true}; + if (remote_api != nullptr and + local_api != nullptr and + remote_api->RetrieveToCas( + {Artifact::ObjectInfo{ + .digest = root_digest, + .type = ObjectType::Tree}}, + local_api)) { + JustMRProgress::Instance() + .TaskTracker() + .Stop(origin); + // Move tree from CAS to local git + // storage + auto tmp_dir = + StorageUtils::CreateTypedTmpDir( + "fetch-absent-root"); + if (not tmp_dir) { + (*logger)( + fmt::format( + "Failed to create tmp " + "directory after fetching " + "root tree {} for absent " + "archive {}", + *root_tree_id, + content), + true); + return; + } + if (not local_api->RetrieveToPaths( + {Artifact::ObjectInfo{ + .digest = root_digest, + .type = ObjectType::Tree}}, + {tmp_dir->GetPath()})) { + (*logger)( + fmt::format("Failed to copy " + "fetched root tree " + "{} to {}", + *root_tree_id, + tmp_dir->GetPath() + .string()), + true); + return; + } + CommitInfo c_info{tmp_dir->GetPath(), + "tree", + *root_tree_id}; + import_to_git_map + ->ConsumeAfterKeysReady( + ts, + {std::move(c_info)}, + [tmp_dir, // keep tmp_dir alive + root_tree_id, + content, + subdir, + pragma_special, + absent, + fetch_absent, + just_git_cas, + archive_tree_id_file, + resolve_symlinks_map, + ts, + setter, + logger](auto const& values) { + if (not values[0]->second) { + (*logger)( + "Importing to git " + "failed", + /*fatal=*/true); + return; + } + // write to id file and + // process subdir tree + WriteIdFileAndSetWSRoot( + *root_tree_id, + just_git_cas, + archive_tree_id_file, + content, + subdir, + pragma_special, + absent, + fetch_absent, + resolve_symlinks_map, + ts, + setter, + logger); + }, + [logger, tmp_dir, root_tree_id]( + auto const& msg, + bool fatal) { + (*logger)( + fmt::format( + "While moving root " + "tree {} from {} " + "to local git:\n{}", + *root_tree_id, + tmp_dir->GetPath() + .string(), + msg), + fatal); + }); + // done + return; + } + // just serve should have made the tree + // available in the remote CAS, so log this + // attempt and revert to network fetch + (*logger)( + fmt::format("Tree {} marked as served, " + "but not found on remote", + *root_tree_id), + /*fatal=*/false); + // revert to network fetch and import_to_git + // before any network fetching, check that + // mandatory fields are provided + if (fetch_url.empty()) { + (*logger)( + "Failed to provide archive fetch " + "url!", + /*fatal=*/true); + return; + } + // now do the actual fetch + auto data = + NetworkFetch(fetch_url, ca_info); + if (data == std::nullopt) { + (*logger)(fmt::format( + "Failed to fetch a file " + "with id {} from {}", + content, + fetch_url), + /*fatal=*/true); + return; + } + // check content wrt checksums + if (sha256) { + auto actual_sha256 = GetContentHash< + Hasher::HashType::SHA256>(*data); + if (actual_sha256 != sha256.value()) { + (*logger)( + fmt::format( + "SHA256 mismatch for {}: " + "expected {}, got {}", + fetch_url, + sha256.value(), + actual_sha256), + /*fatal=*/true); + return; + } + } + if (sha512) { + auto actual_sha512 = GetContentHash< + Hasher::HashType::SHA512>(*data); + if (actual_sha512 != sha512.value()) { + (*logger)( + fmt::format( + "SHA512 mismatch for {}: " + "expected {}, got {}", + fetch_url, + sha512.value(), + actual_sha512), + /*fatal=*/true); + return; + } + } + // add the fetched data to CAS + auto path = StorageUtils::AddToCAS(*data); + // check one last time if content is in CAS + // now + if (not path) { + (*logger)(fmt::format( + "Failed to fetch a file " + "with id {} from {}", + content, + fetch_url), + /*fatal=*/true); + return; + } + JustMRProgress::Instance() + .TaskTracker() + .Stop(origin); + ExtractAndImportToGit(*path, + archive_tree_id_file, + repo_type, + content, + subdir, + pragma_special, + absent, + fetch_absent, + import_to_git_map, + resolve_symlinks_map, + ts, + setter, + logger); + }, + [logger, + target_path = StorageConfig::GitRoot()]( + auto const& msg, bool fatal) { + (*logger)(fmt::format( + "While running critical Git " + "op ENSURE_INIT for " + "target {}:\n{}", + target_path.string(), + msg), + fatal); + }); + // done + return; + } + // give warning + (*logger)(fmt::format("Root tree for content {} could " + "not be served", + key.archive.content), + /*fatal=*/false); + } + // if not fetching absent, request the resolved subdir tree + // directly + else { + if (auto tree_id = serve_api->RetrieveTreeFromArchive( + key.archive.content, + key.repo_type, + key.subdir, + key.pragma_special, + /*sync_tree = */ false)) { + // set the workspace root as absent + JustMRProgress::Instance().TaskTracker().Stop( + key.archive.origin); + (*setter)(std::pair( + nlohmann::json::array( + {FileRoot::kGitTreeMarker, *tree_id}), + /*is_cache_hit = */ false)); + return; + } + // give warning + (*logger)(fmt::format("Tree at subdir {} for archive " + "{} could not be served", + key.subdir, + key.archive.content), + /*fatal=*/false); + } + } + else { + if (not fetch_absent) { + // give warning + (*logger)(fmt::format("Missing serve endpoint for " + "content {} marked absent " + "requires slower network fetch.", + key.archive.content), + /*fatal=*/false); + } + } + // revert to network fetch and import_to_git + // before any network fetching, check that mandatory fields are + // provided + if (key.archive.fetch_url.empty()) { + (*logger)("Failed to provide archive fetch url!", + /*fatal=*/true); + return; + } + // now do the actual fetch + auto data = NetworkFetch(key.archive.fetch_url, ca_info); + if (data == std::nullopt) { + (*logger)( + fmt::format("Failed to fetch a file with id {} from {}", + key.archive.content, + key.archive.fetch_url), + /*fatal=*/true); + return; + } + // check content wrt checksums + if (key.archive.sha256) { + auto actual_sha256 = + GetContentHash<Hasher::HashType::SHA256>(*data); + if (actual_sha256 != key.archive.sha256.value()) { + (*logger)(fmt::format("SHA256 mismatch for {}: " + "expected {}, got {}", + key.archive.fetch_url, + key.archive.sha256.value(), + actual_sha256), + /*fatal=*/true); + return; + } + } + if (key.archive.sha512) { + auto actual_sha512 = + GetContentHash<Hasher::HashType::SHA512>(*data); + if (actual_sha512 != key.archive.sha512.value()) { + (*logger)(fmt::format("SHA512 mismatch for {}: " + "expected {}, got {}", + key.archive.fetch_url, + key.archive.sha512.value(), + actual_sha512), + /*fatal=*/true); + return; + } + } + // add the fetched data to CAS + auto path = StorageUtils::AddToCAS(*data); + // check one last time if content is in CAS now + if (not path) { + (*logger)( + fmt::format("Failed to fetch a file with id {} from {}", + key.archive.content, + key.archive.fetch_url), + /*fatal=*/true); + return; + } + JustMRProgress::Instance().TaskTracker().Stop( + key.archive.origin); + ExtractAndImportToGit(*path, + archive_tree_id_file, + key.repo_type, + key.archive.content, + key.subdir, + key.pragma_special, + key.absent, + fetch_absent, + import_to_git_map, + resolve_symlinks_map, + ts, + setter, + logger); + // done + return; + } + // if not marked absent, do regular fetch to CAS and import_to_git content_cas_map->ConsumeAfterKeysReady( ts, {key.archive}, @@ -272,121 +927,24 @@ auto CreateContentGitMap( setter, logger]([[maybe_unused]] auto const& values) { // content is in CAS - // extract archive - auto tmp_dir = StorageUtils::CreateTypedTmpDir(repo_type); - if (not tmp_dir) { - (*logger)(fmt::format("Failed to create tmp path for " - "{} target {}", - repo_type, - content_id), - /*fatal=*/true); - return; - } auto const& cas = Storage::Instance().CAS(); - // content is in CAS if here, so no need to check nullopt auto content_cas_path = cas.BlobPath(ArtifactDigest(content_id, 0, false), /*is_executable=*/false) .value(); - auto res = ExtractArchive( - content_cas_path, repo_type, tmp_dir->GetPath()); - if (res != std::nullopt) { - (*logger)(fmt::format("Failed to extract archive {} " - "from CAS with error: {}", - content_cas_path.string(), - *res), - /*fatal=*/true); - return; - } - // import to git - CommitInfo c_info{ - tmp_dir->GetPath(), repo_type, content_id}; - import_to_git_map->ConsumeAfterKeysReady( - ts, - {std::move(c_info)}, - [tmp_dir, // keep tmp_dir alive - archive_tree_id_file, - content_id, - subdir, - pragma_special, - absent, - fetch_absent, - resolve_symlinks_map, - ts, - setter, - logger](auto const& values) { - // check for errors - if (not values[0]->second) { - (*logger)("Importing to git failed", - /*fatal=*/true); - return; - } - // only tree id is needed - std::string archive_tree_id = values[0]->first; - // write to tree id file - if (not StorageUtils::WriteTreeIDFile( - archive_tree_id_file, archive_tree_id)) { - (*logger)( - fmt::format("Failed to write tree id " - "to file {}", - archive_tree_id_file.string()), - /*fatal=*/true); - return; - } - // we look for subtree in Git cache - auto just_git_cas = - GitCAS::Open(StorageConfig::GitRoot()); - if (not just_git_cas) { - (*logger)( - "Could not open Git cache object database!", - /*fatal=*/true); - return; - } - auto just_git_repo = - GitRepoRemote::Open(just_git_cas); - if (not just_git_repo) { - (*logger)( - "Could not open Git cache repository!", - /*fatal=*/true); - return; - } - // setup wrapped logger - auto wrapped_logger = - std::make_shared<AsyncMapConsumerLogger>( - [&logger](auto const& msg, bool fatal) { - (*logger)( - fmt::format("While getting subtree " - "from tree:\n{}", - msg), - fatal); - }); - // get subtree id - auto subtree_hash = - just_git_repo->GetSubtreeFromTree( - archive_tree_id, subdir, wrapped_logger); - if (not subtree_hash) { - return; - } - // resolve tree and set workspace root - ResolveContentTree(content_id, - *subtree_hash, - false, /*is_cache_hit*/ - pragma_special, - absent, - fetch_absent, - resolve_symlinks_map, - ts, - setter, - logger); - }, - [logger, target_path = tmp_dir->GetPath()]( - auto const& msg, bool fatal) { - (*logger)(fmt::format("While importing target {} " - "to Git:\n{}", - target_path.string(), - msg), - fatal); - }); + ExtractAndImportToGit(content_cas_path, + archive_tree_id_file, + repo_type, + content_id, + subdir, + pragma_special, + absent, + fetch_absent, + import_to_git_map, + resolve_symlinks_map, + ts, + setter, + logger); }, [logger, content = key.archive.content](auto const& msg, bool fatal) { diff --git a/src/other_tools/root_maps/content_git_map.hpp b/src/other_tools/root_maps/content_git_map.hpp index c5b02454..e0a564f5 100644 --- a/src/other_tools/root_maps/content_git_map.hpp +++ b/src/other_tools/root_maps/content_git_map.hpp @@ -17,7 +17,10 @@ #include <utility> +#include "src/buildtool/common/user_structs.hpp" +#include "src/buildtool/execution_api/common/execution_api.hpp" #include "src/buildtool/file_system/symlinks_map/resolve_symlinks_map.hpp" +#include "src/buildtool/serve_api/remote/serve_api.hpp" #include "src/other_tools/ops_maps/content_cas_map.hpp" #include "src/other_tools/ops_maps/import_to_git_map.hpp" @@ -29,8 +32,13 @@ using ContentGitMap = [[nodiscard]] auto CreateContentGitMap( gsl::not_null<ContentCASMap*> const& content_cas_map, gsl::not_null<ImportToGitMap*> const& import_to_git_map, + LocalPathsPtr const& just_mr_paths, + CAInfoPtr const& ca_info, gsl::not_null<ResolveSymlinksMap*> const& resolve_symlinks_map, gsl::not_null<CriticalGitOpMap*> const& critical_git_op_map, + ServeApi* serve_api, + IExecutionApi* local_api, + IExecutionApi* remote_api, bool fetch_absent, std::size_t jobs) -> ContentGitMap; |