LCOV - code coverage report
Current view: top level - src/esys/repo/exe - cmdsync.cpp (source / functions) Hit Total Coverage
Test: esysrepo_coverage.info Lines: 153 339 45.1 %
Date: 2026-11-07 22:18:26 Functions: 21 34 61.8 %

          Line data    Source code
       1             : /*!
       2             :  * \file esys/repo/exe/cmdsync.cpp
       3             :  * \brief
       4             :  *
       5             :  * \cond
       6             :  * __legal_b__
       7             :  *
       8             :  * Copyright (c) 2020-2022 Michel Gillet
       9             :  * Distributed under the MIT License.
      10             :  * (See accompanying file LICENSE.txt or
      11             :  * copy at https://opensource.org/licenses/MIT)
      12             :  *
      13             :  * __legal_e__
      14             :  * \endcond
      15             :  *
      16             :  */
      17             : 
      18             : #include "esys/repo/esysrepo_prec.h"
      19             : #include "esys/repo/exe/cmdsync.h"
      20             : #include "esys/repo/exe/nested.h"
      21             : #include "esys/repo/manifest/capture.h"
      22             : #include "esys/repo/manifest/sync.h"
      23             : #include "esys/repo/manifest/syncrepos.h"
      24             : #include "esys/repo/resultcode.h"
      25             : #include "esys/repo/tui/is_tty.h"
      26             : #include "esys/repo/tui/run_compact_sync_tui.h"
      27             : 
      28             : #include <esys/trace/call.h>
      29             : #include <esys/trace/macros.h>
      30             : 
      31             : #include <boost/filesystem.hpp>
      32             : 
      33             : #include <cstdlib>
      34             : #include <cstring>
      35             : #include <iostream>
      36             : #include <sstream>
      37             : 
      38             : namespace esys::repo::exe
      39             : {
      40             : 
      41             : namespace
      42             : {
      43             : 
      44          26 : bool env_flag_enabled(const char *name)
      45             : {
      46          26 :     const char *value = std::getenv(name);
      47          26 :     if (value == nullptr || value[0] == '\0') return false;
      48           0 :     if (std::strcmp(value, "1") == 0) return true;
      49           0 :     if (std::strcmp(value, "true") == 0) return true;
      50           0 :     if (std::strcmp(value, "TRUE") == 0) return true;
      51           0 :     if (std::strcmp(value, "yes") == 0) return true;
      52           0 :     if (std::strcmp(value, "YES") == 0) return true;
      53           0 :     if (std::strcmp(value, "on") == 0) return true;
      54           0 :     if (std::strcmp(value, "ON") == 0) return true;
      55             :     return false;
      56             : }
      57             : 
      58             : } // namespace
      59             : 
      60          39 : CmdSync::CmdSync()
      61          78 :     : Cmd("Sync")
      62             : {
      63          39 : }
      64             : 
      65          39 : CmdSync::~CmdSync() = default;
      66             : 
      67           1 : void CmdSync::set_force(bool force)
      68             : {
      69           1 :     m_force = force;
      70           1 : }
      71             : 
      72          27 : bool CmdSync::get_force() const
      73             : {
      74          27 :     return m_force;
      75             : }
      76             : 
      77          28 : void CmdSync::set_branch(const std::string &branch)
      78             : {
      79          28 :     m_branch = branch;
      80          28 : }
      81             : 
      82          93 : const std::string &CmdSync::get_branch() const
      83             : {
      84          93 :     return m_branch;
      85             : }
      86             : 
      87           2 : void CmdSync::set_rev_set(const std::string &rev_set)
      88             : {
      89           2 :     m_rev_set = rev_set;
      90           2 : }
      91             : 
      92          54 : const std::string &CmdSync::get_rev_set() const
      93             : {
      94          54 :     return m_rev_set;
      95             : }
      96             : 
      97          26 : Result CmdSync::apply_revision_set_selection()
      98             : {
      99          26 :     Result result;
     100          26 :     ETRC_CALL_RET_NP(result);
     101             : 
     102          52 :     if (get_manifest() == nullptr) return ETRC_RET(ESYSREPO_RESULT(ResultCode::MANIFEST_IS_NULLPTR));
     103             : 
     104          26 :     std::string preferred = get_rev_set();
     105         104 :     if (preferred.empty() && get_config_folder() != nullptr && get_config_folder()->get_config() != nullptr)
     106         104 :         preferred = get_config_folder()->get_config()->get_revision_set();
     107             : 
     108          26 :     result = get_manifest()->select_revision_set(preferred);
     109          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     110             : 
     111          26 :     if (!get_rev_set().empty() && get_config_folder() != nullptr)
     112             :     {
     113           0 :         auto cfg = get_config_folder()->get_or_new_config();
     114           0 :         cfg->set_revision_set(get_rev_set());
     115           0 :         result = get_config_folder()->write_config_file();
     116           0 :         if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     117           0 :     }
     118             : 
     119          52 :     return ETRC_RET(ESYSREPO_RESULT(ResultCode::OK));
     120          26 : }
     121             : 
     122          26 : Result CmdSync::apply_prefer_branch()
     123             : {
     124          26 :     Result result;
     125          26 :     ETRC_CALL_RET_NP(result);
     126             : 
     127          52 :     if (get_config_folder() == nullptr) return ETRC_RET(ESYSREPO_RESULT(ResultCode::OK));
     128             : 
     129          26 :     if (get_branch().empty())
     130             :     {
     131          66 :         if (get_config_folder()->get_config() != nullptr)
     132          66 :             set_branch(get_config_folder()->get_config()->get_prefer_branch());
     133          44 :         return ETRC_RET(ESYSREPO_RESULT(ResultCode::OK));
     134             :     }
     135             : 
     136           4 :     auto cfg = get_config_folder()->get_or_new_config();
     137           4 :     cfg->set_prefer_branch(get_branch());
     138           4 :     result = get_config_folder()->write_config_file();
     139           4 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     140           8 :     return ETRC_RET(ESYSREPO_RESULT(ResultCode::OK));
     141          26 : }
     142             : 
     143          26 : Result CmdSync::apply_revision_pins()
     144             : {
     145          26 :     Result result;
     146          26 :     ETRC_CALL_RET_NP(result);
     147             : 
     148          52 :     if (get_manifest() == nullptr) return ETRC_RET(ESYSREPO_RESULT(ResultCode::MANIFEST_IS_NULLPTR));
     149          52 :     if (get_config_folder() == nullptr) return ETRC_RET(ESYSREPO_RESULT(ResultCode::CONFIG_FOLDER_IS_NULLPTR));
     150             : 
     151             :     // open() already loaded pins; refresh in case they changed mid-session
     152          26 :     result = get_config_folder()->load_pins_file();
     153          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     154             : 
     155          78 :     get_manifest()->set_revision_pins(get_config_folder()->get_or_new_revision_pins());
     156          78 :     return ETRC_RET(ESYSREPO_RESULT(ResultCode::OK));
     157          26 : }
     158             : 
     159           1 : void CmdSync::set_alt_address(bool alt_address)
     160             : {
     161           1 :     m_alt_address = alt_address;
     162           1 : }
     163           1 : bool CmdSync::get_alt_address() const
     164             : {
     165           1 :     return m_alt_address;
     166             : }
     167             : 
     168           0 : void CmdSync::set_multi(bool multi)
     169             : {
     170           0 :     m_multi = multi;
     171           0 : }
     172             : 
     173          26 : bool CmdSync::get_multi() const
     174             : {
     175          26 :     return m_multi;
     176             : }
     177             : 
     178           0 : void CmdSync::set_tui(bool tui)
     179             : {
     180           0 :     m_tui = tui;
     181           0 : }
     182             : 
     183          26 : bool CmdSync::get_tui() const
     184             : {
     185          26 :     return m_tui;
     186             : }
     187             : 
     188           0 : void CmdSync::set_tui_demo(bool tui_demo)
     189             : {
     190           0 :     m_tui_demo = tui_demo;
     191           0 :     if (tui_demo) m_tui = true;
     192           0 : }
     193             : 
     194           0 : bool CmdSync::get_tui_demo() const
     195             : {
     196           0 :     return m_tui_demo;
     197             : }
     198             : 
     199           3 : void CmdSync::set_recurse_submodules(manifest::RecurseSubmodules recurse)
     200             : {
     201           3 :     m_recurse_submodules = recurse;
     202           3 : }
     203             : 
     204          29 : manifest::RecurseSubmodules CmdSync::get_recurse_submodules() const
     205             : {
     206          29 :     return m_recurse_submodules;
     207             : }
     208             : 
     209          26 : Result CmdSync::sync_manifest()
     210             : {
     211          26 :     Result result;
     212          26 :     ETRC_CALL_RET_NP(result);
     213             : 
     214          26 :     manifest::Sync sync;
     215             : 
     216          52 :     if (get_config_folder() == nullptr) return ETRC_RET(ESYSREPO_RESULT(ResultCode::CMD_CONFIG_FOLDER_NULLPTR));
     217             : 
     218          26 :     auto config = get_config_folder()->get_config();
     219          26 :     if (config != nullptr && !config->get_manifest_local().empty())
     220             :     {
     221           1 :         info("Local manifest: skip git update of the manifest.");
     222           2 :         return ETRC_RET(ESYSREPO_RESULT(ResultCode::OK));
     223             :     }
     224             : 
     225          25 :     sync.set_config_folder(get_config_folder());
     226          25 :     sync.set_git(get_git());
     227          25 :     sync.set_logger_if(get_logger_if());
     228          25 :     if (!get_branch().empty()) sync.set_branch(get_branch());
     229             : 
     230          50 :     return ETRC_RET(ESYSREPO_RESULT(sync.run()));
     231          26 : }
     232             : 
     233           0 : Result CmdSync::handle_capture_item(std::shared_ptr<manifest::Capture::Item> item)
     234             : {
     235           0 :     Result result;
     236           0 :     ETRC_CALL_RET(result, item);
     237             : 
     238           0 :     if (get_workspace_path().empty()) return ETRC_RET(ESYSREPO_RESULT(ResultCode::CMD_WORKSPACE_PATH_IS_EMPTY));
     239             : 
     240           0 :     boost::filesystem::path git_path_folder = get_workspace_path();
     241           0 :     git_path_folder /= item->get_path();
     242           0 :     git_path_folder = git_path_folder.lexically_normal().make_preferred();
     243             : 
     244           0 :     auto git_helper = new_git_helper();
     245           0 :     result = git_helper->open(git_path_folder.string(), log::Level::DEBUG);
     246           0 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     247             : 
     248           0 :     GitHelper::AutoClose auto_close(git_helper.get());
     249             : 
     250           0 :     bool dirty = false;
     251           0 :     result = git_helper->is_dirty(dirty, log::Level::DEBUG);
     252           0 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     253             : 
     254             :     // If there is a remote defined, create it and fetch it
     255           0 :     if (!item->get_remote_name().empty())
     256             :     {
     257           0 :         result = git_helper->get_git()->add_remote(item->get_remote_name(), item->get_remote_url());
     258           0 :         if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     259             : 
     260           0 :         result = git_helper->get_git()->fetch(item->get_remote_name());
     261           0 :         if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     262             :     }
     263             : 
     264             :     // Checkout the new revision
     265           0 :     result = git_helper->checkout(item->get_revision(), false, log::Level::DEBUG);
     266           0 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     267             : 
     268           0 :     return ETRC_RET(ESYSREPO_RESULT(ResultCode::OK));
     269           0 : }
     270             : 
     271           0 : Result CmdSync::do_multi()
     272             : {
     273           0 :     Result result;
     274           0 :     ETRC_CALL_RET_NP(result);
     275             : 
     276             :     // First we need to get the working folder
     277           0 :     std::string folder_path;
     278             : 
     279           0 :     if (!get_folder().empty())
     280           0 :         folder_path = get_folder();
     281           0 :     else if (!get_workspace_path().empty())
     282           0 :         folder_path = get_workspace_path();
     283             :     else
     284           0 :         folder_path = boost::filesystem::current_path().string();
     285           0 :     if (folder_path.empty()) return ETRC_RET(ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR));
     286             : 
     287           0 :     auto git_folder_path = find_git_root_path(folder_path);
     288           0 :     auto git_helper = new_git_helper();
     289             : 
     290           0 :     set_git_folder_path(git_folder_path);
     291           0 :     result = git_helper->open(git_folder_path, log::Level::DEBUG);
     292           0 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     293             : 
     294           0 :     GitHelper::AutoClose auto_close(git_helper.get());
     295             : 
     296           0 :     int result_int = git_helper->get_git()->add_notes_ref("esysrepo");
     297           0 :     if (result_int < 0) return ETRC_RET(ESYSREPO_RESULT(ResultCode::GIT_RAW_INT_ERROR, result_int));
     298             : 
     299           0 :     result = git_helper->get_git()->fetch_all_notes();
     300           0 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     301             : 
     302           0 :     git::Commit last_commit;
     303             : 
     304           0 :     result = git_helper->get_git()->get_last_commit(last_commit, true);
     305           0 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     306             : 
     307           0 :     std::vector<std::shared_ptr<git::Note>> notes;
     308           0 :     result_int = last_commit.get_notes("esysrepo", notes);
     309           0 :     if (result_int < 0) return ETRC_RET(ESYSREPO_RESULT(ResultCode::GIT_RAW_INT_ERROR, result_int));
     310             : 
     311           0 :     std::ostringstream oss;
     312             : 
     313           0 :     oss << "Found " << notes.size() << " esysrepo multi note.";
     314             : 
     315           0 :     info(oss.str());
     316             : 
     317           0 :     if (notes.empty()) return ETRC_RET(ESYSREPO_RESULT(ResultCode::OK));
     318           0 :     if (notes.size() != 1) return ETRC_RET(ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR));
     319             : 
     320           0 :     std::string note_text = notes[0]->get_message();
     321           0 :     auto capture = std::make_shared<manifest::Capture>();
     322           0 :     result = load_capture(capture, note_text);
     323           0 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     324             : 
     325           0 :     oss.str("");
     326           0 :     print_capture(oss, capture);
     327           0 :     info(oss.str());
     328             : 
     329           0 :     Result rresult;
     330           0 :     for (auto repo : capture->get_items())
     331             :     {
     332           0 :         result = handle_capture_item(repo);
     333           0 :         if (result.error())
     334             :         {
     335           0 :             std::ostringstream e_oss;
     336             : 
     337           0 :             e_oss << "repo '" << repo->get_path() << "' could set revivions '" << repo->get_revision() << "'";
     338           0 :             error(e_oss.str());
     339           0 :             rresult.add(result);
     340           0 :         }
     341           0 :     }
     342             : 
     343           0 :     return ETRC_RET(ESYSREPO_RESULT(rresult));
     344           0 : }
     345             : 
     346           0 : void CmdSync::set_git_folder_path(const std::string &git_folder_path)
     347             : {
     348           0 :     m_git_folder_path = git_folder_path;
     349           0 : }
     350             : 
     351           0 : const std::string &CmdSync::get_git_folder_path() const
     352             : {
     353           0 :     return m_git_folder_path;
     354             : }
     355             : 
     356          26 : Result CmdSync::apply_sync_folder_filters(manifest::SyncRepos &sync_repos)
     357             : {
     358          26 :     if (get_sub_args().size() != 0)
     359           4 :         sync_repos.set_folders_to_sync(get_sub_args());
     360          22 :     else if (get_groups().size() != 0)
     361             :     {
     362           2 :         std::vector<std::string> repos;
     363             : 
     364           4 :         for (auto &group : get_groups())
     365             :         {
     366           2 :             auto group_ptr = get_manifest()->get_groups().find_group_by_name(group);
     367           2 :             if (group_ptr == nullptr) continue;
     368          14 :             for (auto repo : group_ptr->get_repos()) repos.push_back(repo->get_path());
     369           2 :         }
     370             : 
     371           2 :         sync_repos.set_folders_to_sync(repos);
     372           2 :     }
     373             : 
     374          26 :     if (get_sub_args().empty()) return ESYSREPO_RESULT(ResultCode::OK);
     375           8 :     if (get_manifest() == nullptr) return ESYSREPO_RESULT(ResultCode::MANIFEST_IS_NULLPTR);
     376             : 
     377           4 :     bool any = false;
     378           8 :     for (auto location : get_manifest()->get_locations())
     379             :     {
     380           9 :         for (auto repo : location->get_repos())
     381             :         {
     382          27 :             if (sync_repos.is_repo_to_be_synced(repo))
     383             :             {
     384           4 :                 any = true;
     385           4 :                 break;
     386             :             }
     387           5 :         }
     388           4 :         if (any) break;
     389           0 :     }
     390           4 :     if (any) return ESYSREPO_RESULT(ResultCode::OK);
     391             : 
     392           0 :     std::ostringstream oss;
     393           0 :     oss << "No repository matches";
     394           0 :     for (const auto &arg : get_sub_args()) oss << " '" << arg << "'";
     395           0 :     error(oss.str());
     396           0 :     return ESYSREPO_RESULT(ResultCode::MANIFEST_REPO_UNKNOWN, oss.str());
     397           0 : }
     398             : 
     399          26 : Result CmdSync::impl_run()
     400             : {
     401          26 :     Result result;
     402          26 :     ETRC_CALL_RET_NP(result);
     403             : 
     404          26 :     if (env_flag_enabled("ESYSREPO_TUI_DEMO")) set_tui_demo(true);
     405             : 
     406          26 :     if (get_tui()) return ETRC_RET(ESYSREPO_RESULT(impl_run_tui()));
     407             : 
     408          26 :     if (get_force()) warn("Option --force-sync is not implemented yet");
     409             : 
     410          26 :     result = default_handling_folder_workspace();
     411          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     412             : 
     413          26 :     result = open_esysrepo_folder();
     414          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     415             : 
     416          26 :     result = apply_prefer_branch();
     417          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     418             : 
     419          26 :     result = sync_manifest();
     420          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     421             : 
     422          26 :     result = load_manifest();
     423          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     424             : 
     425          26 :     result = apply_revision_set_selection();
     426          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     427             : 
     428          26 :     result = apply_revision_pins();
     429          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     430             : 
     431          26 :     manifest::SyncRepos sync_repos;
     432             : 
     433          26 :     if (!get_branch().empty()) sync_repos.set_branch(get_branch());
     434             : 
     435          26 :     result = apply_sync_folder_filters(sync_repos);
     436          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     437             : 
     438          26 :     if (get_debug()) sync_repos.set_log_level(log::Level::DEBUG);
     439             : 
     440          26 :     sync_repos.set_job_count(get_job_count());
     441          26 :     sync_repos.set_logger_if(get_logger_if());
     442          26 :     sync_repos.set_config_folder(get_config_folder());
     443          26 :     sync_repos.set_git(get_git());
     444          26 :     sync_repos.set_manifest(get_manifest());
     445          26 :     sync_repos.set_tui(false);
     446          26 :     sync_repos.set_recurse_submodules(get_recurse_submodules());
     447             : 
     448          26 :     get_git()->detect_ssh_agent(true);
     449             : 
     450          26 :     result = sync_repos.run();
     451          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     452             : 
     453          26 :     NestedContext nested_scratch;
     454          26 :     NestedContext *nested_ctx = get_nested_context() != nullptr ? get_nested_context() : &nested_scratch;
     455          26 :     set_nested_context(nested_ctx);
     456          52 :     result = for_each_nested(*this, NestedMissingMode::Fail, *nested_ctx,
     457           0 :                              [this](const std::string &child_abs, std::shared_ptr<manifest::Repository>) {
     458           0 :                                  CmdSync child;
     459           0 :                                  prepare_nested_cmd(*this, child, child_abs);
     460           0 :                                  child.set_force(get_force());
     461           0 :                                  child.set_branch(get_branch());
     462           0 :                                  child.set_rev_set(get_rev_set());
     463           0 :                                  child.set_alt_address(get_alt_address());
     464           0 :                                  child.set_multi(false);
     465           0 :                                  child.set_recurse_submodules(get_recurse_submodules());
     466           0 :                                  return child.run();
     467          26 :                              });
     468          26 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     469             : 
     470          52 :     if (!get_multi()) return ETRC_RET(ESYSREPO_RESULT(ResultCode::OK));
     471           0 :     return ETRC_RET(ESYSREPO_RESULT(do_multi()));
     472          26 : }
     473             : 
     474           0 : Result CmdSync::impl_run_tui()
     475             : {
     476           0 :     Result result;
     477           0 :     ETRC_CALL_RET_NP(result);
     478             : 
     479             : #ifndef ESYSREPO_HAVE_TUI
     480             :     error("--tui requested but esysrepo was built without FTXUI (Conan with_tui / ESYSREPO_WITH_TUI)");
     481             :     return ETRC_RET(ESYSREPO_RESULT(ResultCode::NOT_IMPLEMENTED));
     482             : #else
     483           0 :     if (!tui::is_tty())
     484             :     {
     485           0 :         const char *msg =
     486             :             "--tui requires a real Win32 console (cmd.exe, PowerShell, or Windows "
     487             :             "Terminal). Git Bash/mintty and redirected stdout are not supported.";
     488           0 :         error(msg);
     489           0 :         std::cerr << "ERROR: " << msg << std::endl;
     490           0 :         return ETRC_RET(ESYSREPO_RESULT(ResultCode::GENERIC_ERROR));
     491             :     }
     492             : 
     493           0 :     if (get_force()) warn("Option --force-sync is not implemented yet");
     494             : 
     495           0 :     const std::size_t ui_workers =
     496           0 :         get_job_count() <= 0 ? std::size_t{1} : static_cast<std::size_t>(get_job_count());
     497             : 
     498           0 :     auto work = [this](progress::ProgressSession &session, tui::SyncTuiControl &control) -> Result {
     499           0 :         auto prev_logger = get_logger_if();
     500           0 :         if (control.logger) set_logger_if(control.logger);
     501             : 
     502           0 :         auto restore_logger = [&]() {
     503           0 :             if (prev_logger) set_logger_if(prev_logger);
     504           0 :         };
     505             : 
     506           0 :         if (control.set_phase) control.set_phase("Loading workspace…");
     507             : 
     508           0 :         Result phase = default_handling_folder_workspace();
     509           0 :         if (phase.error())
     510             :         {
     511           0 :             restore_logger();
     512             :             return phase;
     513             :         }
     514             : 
     515           0 :         phase = open_esysrepo_folder();
     516           0 :         if (phase.error())
     517             :         {
     518           0 :             restore_logger();
     519             :             return phase;
     520             :         }
     521             : 
     522           0 :         phase = apply_prefer_branch();
     523           0 :         if (phase.error())
     524             :         {
     525           0 :             restore_logger();
     526             :             return phase;
     527             :         }
     528             : 
     529           0 :         if (control.set_phase) control.set_phase("Loading manifest…");
     530             : 
     531           0 :         phase = sync_manifest();
     532           0 :         if (phase.error())
     533             :         {
     534           0 :             restore_logger();
     535             :             return phase;
     536             :         }
     537             : 
     538           0 :         phase = load_manifest();
     539           0 :         if (phase.error())
     540             :         {
     541           0 :             restore_logger();
     542             :             return phase;
     543             :         }
     544             : 
     545           0 :         phase = apply_revision_set_selection();
     546           0 :         if (phase.error())
     547             :         {
     548           0 :             restore_logger();
     549             :             return phase;
     550             :         }
     551             : 
     552           0 :         phase = apply_revision_pins();
     553           0 :         if (phase.error())
     554             :         {
     555           0 :             restore_logger();
     556             :             return phase;
     557             :         }
     558             : 
     559           0 :         manifest::SyncRepos sync_repos;
     560             : 
     561           0 :         if (!get_branch().empty()) sync_repos.set_branch(get_branch());
     562             : 
     563           0 :         phase = apply_sync_folder_filters(sync_repos);
     564           0 :         if (phase.error())
     565             :         {
     566           0 :             restore_logger();
     567             :             return phase;
     568             :         }
     569             : 
     570           0 :         if (get_debug()) sync_repos.set_log_level(log::Level::DEBUG);
     571             : 
     572           0 :         sync_repos.set_job_count(get_job_count());
     573           0 :         sync_repos.set_logger_if(get_logger_if());
     574           0 :         sync_repos.set_config_folder(get_config_folder());
     575           0 :         sync_repos.set_git(get_git());
     576           0 :         sync_repos.set_manifest(get_manifest());
     577           0 :         sync_repos.set_tui(false);
     578           0 :         sync_repos.set_alt_address(get_alt_address());
     579           0 :         sync_repos.set_recurse_submodules(get_recurse_submodules());
     580             : 
     581           0 :         get_git()->detect_ssh_agent(true);
     582           0 :         if (control.logger) get_git()->set_logger_if(control.logger);
     583             : 
     584           0 :         phase = sync_repos.run_with_session(session, &control);
     585           0 :         restore_logger();
     586             :         return phase;
     587           0 :     };
     588             : 
     589           0 :     tui::SyncTuiOptions tui_options;
     590           0 :     tui_options.demo = get_tui_demo();
     591           0 :     result = tui::run_compact_sync_tui(work, {}, ui_workers, get_logger_if(), tui_options);
     592           0 :     if (result.error()) return ETRC_RET(ESYSREPO_RESULT(result));
     593             : 
     594           0 :     if (!get_multi()) return ETRC_RET(ESYSREPO_RESULT(ResultCode::OK));
     595           0 :     return ETRC_RET(ESYSREPO_RESULT(do_multi()));
     596             : #endif
     597           0 : }
     598             : 
     599             : } // namespace esys::repo::exe

Generated by: LCOV version 1.14