LCOV - code coverage report
Current view: top level - src/esys/repo/manifest - syncrepo_manifest.cpp (source / functions) Hit Total Coverage
Test: esysrepo_coverage.info Lines: 246 372 66.1 %
Date: 2026-08-12 14:26:50 Functions: 36 47 76.6 %

          Line data    Source code
       1             : /*!
       2             :  * \file esys/repo/manifest/syncrepo_manifest.cpp
       3             :  * \brief
       4             :  *
       5             :  * \cond
       6             :  * __legal_b__
       7             :  *
       8             :  * Copyright (c) 2020-2023 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/manifest/syncrepo.h"
      20             : #include "esys/repo/manifest/location.h"
      21             : #include "esys/repo/git/clonerev.h"
      22             : 
      23             : #include "esys/repo/filesystem.h"
      24             : 
      25             : #include <esys/trace/call.h>
      26             : #include <esys/trace/macros.h>
      27             : 
      28             : #include <boost/filesystem.hpp>
      29             : 
      30             : #include <sstream>
      31             : #include <string>
      32             : 
      33             : namespace esys::repo::manifest
      34             : {
      35             : 
      36         122 : SyncRepo::SyncRepo()
      37         122 :     : log::User()
      38             : {
      39         122 : }
      40             : 
      41         244 : SyncRepo::~SyncRepo() = default;
      42             : 
      43         120 : int SyncRepo::run()
      44             : {
      45         120 :     int result = 0;
      46         120 :     ETRC_CALL_RET_NP(result);
      47             : 
      48         120 :     return ETRC_RET(process_repo());
      49         120 : }
      50             : 
      51         120 : int SyncRepo::process_repo()
      52             : {
      53         120 :     int result = 0;
      54         120 :     ETRC_CALL_RET_NP(result);
      55             : 
      56         120 :     boost::filesystem::path path = get_config_folder()->get_workspace_path();
      57         345 :     if (get_repo()->get_path() != ".") path /= get_repo()->get_path();
      58             : 
      59         120 :     if (!GitBase::is_repo(path.string()))
      60         113 :         result = clone();
      61             :     else
      62           7 :         result = fetch_update();
      63         120 :     if (result != 0) return ETRC_RET(result);
      64         120 :     return ETRC_RET(maybe_update_submodules(path.string()));
      65         120 : }
      66             : 
      67           0 : bool SyncRepo::has_branch(GitHelper &git_helper, const std::string &branch)
      68             : {
      69           0 :     bool result_bool = false;
      70           0 :     ETRC_CALL_RET(result_bool, branch);
      71             : 
      72           0 :     git::Branches branches;
      73           0 :     Result result = git_helper.get_branches(branches, git::BranchType::REMOTE, log::Level::DEBUG);
      74           0 :     if (result.error())
      75             :     {
      76           0 :         git_helper.error("Couldn't get the list of local branches");
      77           0 :         return ETRC_RET(false);
      78             :     }
      79             : 
      80           0 :     branches.sort();
      81             : 
      82           0 :     auto branch_ptr = branches.find(branch);
      83             : 
      84           0 :     if (branch_ptr != nullptr)
      85             :     {
      86           0 :         git_helper.debug(0, "Branch found : " + branch);
      87           0 :         return ETRC_RET(true);
      88             :     }
      89           0 :     git_helper.debug(0, "Branch not found : " + branch);
      90           0 :     return ETRC_RET(false);
      91           0 : }
      92             : 
      93         121 : std::string SyncRepo::get_manifest_repo_revision()
      94             : {
      95         363 :     if (m_manifest != nullptr && get_repo() != nullptr) return m_manifest->get_repo_revision(get_repo());
      96           0 :     if (get_repo() != nullptr) return get_repo()->get_revision();
      97         121 :     return {};
      98             : }
      99             : 
     100          40 : bool SyncRepo::is_pinned()
     101             : {
     102          80 :     if (m_manifest == nullptr || get_repo() == nullptr) return false;
     103          80 :     return m_manifest->has_revision_pin(get_repo()->get_path());
     104             : }
     105             : 
     106          32 : std::string SyncRepo::get_checkout_revision(GitHelper &git_helper)
     107             : {
     108          32 :     std::string result;
     109          32 :     ETRC_CALL_RET_NP(result);
     110             : 
     111             :     // Workspace pins win over sync --branch (ADR-0021)
     112          32 :     if (is_pinned()) return ETRC_RET(get_manifest_repo_revision());
     113             : 
     114          82 :     if (get_branch().empty()) return ETRC_RET(get_manifest_repo_revision());
     115             : 
     116           7 :     Result_t<bool> branch_exists =
     117           7 :         git_helper.has_branch(get_branch(), git::BranchType::REMOTE, esys::log::Level::DEBUG);
     118             : 
     119           7 :     std::ostringstream oss;
     120           7 :     oss << "branch_exists = " << branch_exists;
     121           7 :     debug(0, oss.str());
     122             : 
     123           7 :     if (branch_exists) return ETRC_RET(get_branch());
     124          18 :     return ETRC_RET(get_manifest_repo_revision());
     125          39 : }
     126             : 
     127         120 : std::shared_ptr<GitHelper> SyncRepo::new_git_helper()
     128             : {
     129         240 :     auto git_helper = std::make_shared<GitHelper>(get_git(), get_logger_if(), static_cast<int>(get_repo_idx()));
     130             : 
     131         360 :     get_git()->set_logger_if(git_helper);
     132         120 :     return git_helper;
     133           0 : }
     134             : 
     135         120 : SyncRepo::PhaseCapture::PhaseCapture(SyncRepo &self, GitHelper &helper)
     136         120 :     : m_self(self)
     137         120 :     , m_helper(helper)
     138             : {
     139         120 : }
     140             : 
     141         120 : SyncRepo::PhaseCapture::~PhaseCapture()
     142             : {
     143         120 :     m_self.m_phase_timings = m_helper.get_phase_timings();
     144         120 :     m_helper.log_phase_summary();
     145         120 : }
     146             : 
     147           0 : const GitPhaseTimings &SyncRepo::get_phase_timings() const
     148             : {
     149           0 :     return m_phase_timings;
     150             : }
     151             : 
     152         113 : int SyncRepo::clone()
     153             : {
     154         113 :     int result = 0;
     155         113 :     ETRC_CALL_RET_NP(result);
     156             : 
     157         113 :     std::shared_ptr<GitHelper> git_helper = new_git_helper();
     158         113 :     PhaseCapture phase_capture(*this, *git_helper);
     159         113 :     std::string url = get_repo_url();
     160         113 :     std::string branch_to_checkout;
     161             : 
     162         113 :     boost::filesystem::path path = get_config_folder()->get_workspace_path();
     163         226 :     ETRC_MSG("path : " + get_repo()->get_path());
     164             : 
     165         226 :     if (get_repo()->get_path() != ".")
     166             :     {
     167             :         // A simple clone can be made
     168          99 :         path /= get_repo()->get_path();
     169             : 
     170             :         // Prefer tip-at-clone when SyncRepos enabled checkout_rev (ADR-0030 default).
     171             :         // Raw commit SHAs and empty revs force the legacy path for this repo.
     172          99 :         git::CloneOptions clone_opts = get_clone_options();
     173         198 :         git::CloneRevPlan plan = git::plan_clone_rev(clone_opts.checkout_rev, get_branch(),
     174          99 :                                                      get_branch().empty() ? get_manifest_repo_revision()
     175          99 :                                                                           : std::string());
     176          99 :         std::string clone_rev = plan.clone_rev;
     177          99 :         if (!plan.use_tip) clone_opts.checkout_rev = false;
     178             : 
     179          99 :         Result rresult =
     180          99 :             git_helper->clone_rev(url, clone_rev, path.string(), false, log::Level::INFO, 0, clone_opts);
     181          99 :         if (rresult.error() && clone_opts.checkout_rev && !clone_rev.empty())
     182             :         {
     183             :             // Branch/tag missing on this remote (e.g. sync -b), or odd rev: fall back.
     184          10 :             git_helper->debug(0, "clone with rev '" + clone_rev + "' failed; cloning default");
     185           5 :             clone_rev.clear();
     186           5 :             clone_opts = git::CloneOptions();
     187           5 :             rresult = git_helper->clone_rev(url, "", path.string(), false, log::Level::INFO, 0, clone_opts);
     188             :         }
     189          99 :         if (rresult.error())
     190             :         {
     191           0 :             git_helper->close_on_error(log::Level::DEBUG);
     192           0 :             return ETRC_RET(rresult.get_result_code_int());
     193             :         }
     194             : 
     195          99 :         if (clone_opts.checkout_rev && !clone_rev.empty())
     196             :         {
     197             :             // Already on the requested branch/tag tip from clone.
     198          81 :             rresult = git_helper->close(log::Level::DEBUG);
     199          81 :             return ETRC_RET(rresult.get_result_code_int());
     200             :         }
     201             : 
     202          18 :         if (!get_branch().empty())
     203             :         {
     204           5 :             Result result = git_helper->fetch(get_log_level());
     205           5 :             if (result.error())
     206             :             {
     207           0 :                 git_helper->close_on_error(log::Level::DEBUG);
     208           0 :                 return ETRC_RET(result.get_result_code_int());
     209             :             }
     210           5 :         }
     211             : 
     212          18 :         branch_to_checkout = get_checkout_revision(*git_helper.get());
     213          18 :         git_helper->debug(0, "branch_to_checkout = " + branch_to_checkout);
     214          18 :         if (branch_to_checkout.empty()) return ETRC_RET(0);
     215             : 
     216          18 :         rresult = git_helper->checkout(branch_to_checkout, false, log::Level::INFO);
     217          18 :         if (rresult.error())
     218             :         {
     219           0 :             git_helper->close_on_error(log::Level::DEBUG);
     220           0 :             return ETRC_RET(rresult.get_result_code_int());
     221             :         }
     222          18 :         rresult = git_helper->close(log::Level::DEBUG);
     223          18 :         return ETRC_RET(rresult.get_result_code_int());
     224          99 :     }
     225             : 
     226          14 :     if (get_workspace_root_clone_method() == WorkspaceRootCloneMethod::InitFetch)
     227           1 :         return ETRC_RET(clone_workspace_root_init_fetch(*git_helper.get(), url, path.string()));
     228             : 
     229          13 :     return ETRC_RET(clone_workspace_root_temp_move(*git_helper.get(), url, path.string()));
     230         226 : }
     231             : 
     232          13 : int SyncRepo::clone_workspace_root_temp_move(GitHelper &git_helper, const std::string &url, const std::string &path)
     233             : {
     234          13 :     int result = 0;
     235          13 :     ETRC_CALL_RET(result, url, path);
     236             : 
     237             :     // Folder is not empty (.esysrepo): clone into temp, then move into the workspace
     238          13 :     boost::filesystem::path temp_path = get_config_folder()->get_temp_path();
     239          13 :     std::ostringstream oss;
     240          13 :     oss << "repo_temp" << get_repo_idx();
     241          13 :     temp_path /= oss.str();
     242             : 
     243          13 :     Result rresult = git_helper.clone(url, temp_path.string(), path, true, get_log_level());
     244          13 :     if (rresult.error())
     245             :     {
     246           0 :         git_helper.close_on_error(log::Level::DEBUG);
     247           0 :         return ETRC_RET(rresult.get_result_code_int());
     248             :     }
     249             : 
     250          13 :     rresult = git_helper.open(path, esys::log::INFO);
     251          13 :     if (rresult.error()) return ETRC_RET(rresult.get_result_code_int());
     252             : 
     253          13 :     if (!get_branch().empty())
     254             :     {
     255           2 :         rresult = git_helper.fetch(get_log_level());
     256           2 :         if (rresult.error())
     257             :         {
     258           0 :             git_helper.close_on_error(log::Level::DEBUG);
     259           0 :             return ETRC_RET(rresult.get_result_code_int());
     260             :         }
     261             :     }
     262             : 
     263          13 :     return ETRC_RET(finish_workspace_root_clone(git_helper));
     264          13 : }
     265             : 
     266           1 : int SyncRepo::clone_workspace_root_init_fetch(GitHelper &git_helper, const std::string &url, const std::string &path)
     267             : {
     268           1 :     int result = 0;
     269           1 :     ETRC_CALL_RET(result, url, path);
     270             : 
     271           2 :     git_helper.info("Init+fetch workspace root ...\n    path : " + path + "\n    url  : " + url);
     272             : 
     273           1 :     Result rresult = git_helper.get_git()->init(path);
     274           1 :     if (rresult.error())
     275             :     {
     276           0 :         git_helper.error("Failed to init workspace root", rresult.get_result_code_int());
     277           0 :         git_helper.close_on_error(log::Level::DEBUG);
     278           0 :         return ETRC_RET(rresult.get_result_code_int());
     279             :     }
     280             : 
     281           1 :     rresult = git_helper.get_git()->add_remote("origin", url);
     282           1 :     if (rresult.error())
     283             :     {
     284           0 :         git_helper.error("Failed to add remote origin", rresult.get_result_code_int());
     285           0 :         git_helper.close_on_error(log::Level::DEBUG);
     286           0 :         return ETRC_RET(rresult.get_result_code_int());
     287             :     }
     288             : 
     289           1 :     rresult = git_helper.fetch("origin", get_log_level());
     290           1 :     if (rresult.error())
     291             :     {
     292           0 :         git_helper.close_on_error(log::Level::DEBUG);
     293           0 :         return ETRC_RET(rresult.get_result_code_int());
     294             :     }
     295             : 
     296           1 :     return ETRC_RET(finish_workspace_root_clone(git_helper));
     297           1 : }
     298             : 
     299          14 : int SyncRepo::finish_workspace_root_clone(GitHelper &git_helper)
     300             : {
     301          14 :     int result = 0;
     302          14 :     ETRC_CALL_RET_NP(result);
     303             : 
     304          14 :     std::string branch_to_checkout = resolve_checkout_revision(git_helper);
     305          14 :     git_helper.debug(0, "branch_to_checkout = " + branch_to_checkout);
     306          14 :     if (branch_to_checkout.empty())
     307             :     {
     308           0 :         git_helper.error("No revision to checkout after workspace-root clone");
     309           0 :         git_helper.close_on_error(log::Level::DEBUG);
     310           0 :         return ETRC_RET(-1);
     311             :     }
     312             : 
     313          14 :     Result rresult = git_helper.checkout(branch_to_checkout, get_force(), log::Level::INFO);
     314          14 :     if (rresult.error())
     315             :     {
     316           0 :         git_helper.close_on_error(log::Level::DEBUG);
     317           0 :         return ETRC_RET(rresult.get_result_code_int());
     318             :     }
     319          14 :     rresult = git_helper.close(log::Level::DEBUG);
     320          14 :     return ETRC_RET(rresult.get_result_code_int());
     321          28 : }
     322             : 
     323          14 : std::string SyncRepo::resolve_checkout_revision(GitHelper &git_helper)
     324             : {
     325          14 :     std::string rev = get_checkout_revision(git_helper);
     326             : 
     327          14 :     const std::string heads = "refs/heads/";
     328          14 :     if (rev.compare(0, heads.size(), heads) == 0) rev = rev.substr(heads.size());
     329          28 :     if (!rev.empty()) return rev;
     330             : 
     331             :     // Init-fetch leaves no default checkout (unlike clone). Pick a remote branch.
     332           0 :     git::Branches branches;
     333           0 :     Result rresult = git_helper.get_branches(branches, git::BranchType::REMOTE, log::Level::DEBUG);
     334           0 :     if (rresult.error() || branches.size() == 0) return {};
     335             : 
     336           0 :     auto short_name = [](const std::string &full) -> std::string {
     337           0 :         auto pos = full.rfind('/');
     338           0 :         if (pos == std::string::npos) return full;
     339           0 :         return full.substr(pos + 1);
     340             :     };
     341             : 
     342           0 :     auto find_named = [&](const std::string &want) -> std::string {
     343           0 :         for (const auto &branch : branches.get())
     344             :         {
     345           0 :             if (short_name(branch->get_name()) == want) return want;
     346             :         }
     347           0 :         return {};
     348           0 :     };
     349             : 
     350           0 :     rev = find_named("master");
     351           0 :     if (rev.empty()) rev = find_named("main");
     352           0 :     if (rev.empty()) rev = short_name(branches.get()[0]->get_name());
     353           0 :     return rev;
     354          14 : }
     355             : 
     356           7 : int SyncRepo::fetch_update()
     357             : {
     358           7 :     int result_int = 0;
     359           7 :     ETRC_CALL_RET_NP(result_int);
     360             : 
     361           7 :     std::shared_ptr<GitHelper> git_helper = new_git_helper();
     362           7 :     PhaseCapture phase_capture(*this, *git_helper);
     363           7 :     git_helper->set_display_repo_idx(get_display_repo_idx());
     364             : 
     365           7 :     boost::filesystem::path path = get_config_folder()->get_workspace_path();
     366          20 :     if (get_repo()->get_path() != ".") path /= get_repo()->get_path();
     367             : 
     368           7 :     Result rresult = git_helper->open(path.string(), log::Level::INFO);
     369           7 :     if (rresult.error()) return ETRC_RET(rresult.get_result_code_int());
     370             : 
     371           7 :     bool dirty = false;
     372           7 :     rresult = git_helper->is_dirty(dirty, log::Level::DEBUG);
     373           7 :     if (rresult.error()) return ETRC_RET(rresult.get_result_code_int());
     374             : 
     375           7 :     if (dirty)
     376             :     {
     377           0 :         git_helper->warn("Changes detected in repo, no sync.");
     378           0 :         return ETRC_RET(0);
     379             :     }
     380             : 
     381           7 :     if (is_pinned()) return ETRC_RET(pin_sync(*git_helper.get()));
     382             : 
     383           7 :     if (get_branch().empty())
     384           7 :         return ETRC_RET(normal_sync(*git_helper.get()));
     385             :     else
     386           0 :         return ETRC_RET(branch_sync(*git_helper.get()));
     387          14 : }
     388             : 
     389           0 : int SyncRepo::pin_sync(GitHelper &git_helper)
     390             : {
     391           0 :     int result_int = 0;
     392           0 :     ETRC_CALL_RET_NP(result_int);
     393             : 
     394           0 :     const std::string pin_rev = get_manifest_repo_revision();
     395           0 :     if (pin_rev.empty())
     396             :     {
     397           0 :         git_helper.error("Pinned repository has an empty revision.");
     398           0 :         return ETRC_RET(-1);
     399             :     }
     400             : 
     401           0 :     Result result = git_helper.fetch(log::Level::DEBUG);
     402           0 :     if (result.error())
     403             :     {
     404           0 :         git_helper.error("Fetch failed on the pinned git repo");
     405           0 :         return ETRC_RET(result.get_result_code_int());
     406             :     }
     407             : 
     408           0 :     git_helper.info("Checking out pinned revision " + pin_rev + " ...");
     409           0 :     result = git_helper.checkout(pin_rev, get_force(), log::Level::INFO);
     410           0 :     if (result.error())
     411             :     {
     412           0 :         git_helper.error("Failed to checkout pinned revision " + pin_rev + ".");
     413           0 :         return ETRC_RET(result.get_result_code_int());
     414             :     }
     415           0 :     git_helper.info("Pinned revision checkout completed.");
     416           0 :     return ETRC_RET(0);
     417           0 : }
     418             : 
     419           7 : int SyncRepo::normal_sync(GitHelper &git_helper)
     420             : {
     421           7 :     int result_int = 0;
     422           7 :     ETRC_CALL_RET_NP(result_int);
     423             : 
     424           7 :     bool detached = false;
     425           7 :     Result result = git_helper.is_detached(detached, log::Level::DEBUG);
     426           7 :     if (result.error())
     427             :     {
     428           0 :         git_helper.error("Couldn't detect if the git repo is detached or not.");
     429           0 :         return ETRC_RET(result.get_result_code_int());
     430             :     }
     431             : 
     432           7 :     if (detached)
     433             :     {
     434             :         // Soft skip (same as dirty): detached HEADs are left alone on a normal sync
     435           2 :         git_helper.warn("Sync repo aborted: the git repo is detached.");
     436           2 :         return ETRC_RET(0);
     437             :     }
     438             : 
     439           5 :     result = git_helper.fetch(log::Level::DEBUG);
     440           5 :     if (result.error())
     441             :     {
     442           0 :         git_helper.error("Fetch failed on the git repo");
     443           0 :         return ETRC_RET(result.get_result_code_int());
     444             :     }
     445             : 
     446           5 :     git::Branches branches;
     447           5 :     result = git_helper.get_branches(branches, git::BranchType::LOCAL, log::Level::DEBUG);
     448           5 :     if (result.error())
     449             :     {
     450           0 :         git_helper.error("Couldn't get the list of local branches");
     451           0 :         return ETRC_RET(result.get_result_code_int());
     452             :     }
     453             : 
     454           5 :     branches.sort();
     455             : 
     456          10 :     if (branches.get_head() == nullptr)
     457             :     {
     458           0 :         git_helper.error("Couldn't get the HEAD.");
     459           0 :         return ETRC_RET(-4);
     460             :     }
     461             : 
     462           5 :     std::vector<std::string> refs;
     463           5 :     git::MergeAnalysisResult merge_analysis_result;
     464           5 :     std::vector<git::CommitHash> commits;
     465             : 
     466           5 :     refs.push_back(branches.get_head()->get_remote_branch());
     467             : 
     468           5 :     result = git_helper.merge_analysis(refs, merge_analysis_result, commits, log::Level::DEBUG);
     469           5 :     if (result.error())
     470             :     {
     471           0 :         git_helper.error("Merge analysis failed.");
     472           0 :         return ETRC_RET(-5);
     473             :     }
     474             : 
     475           5 :     if (merge_analysis_result == git::MergeAnalysisResult::UP_TO_DATE)
     476             :     {
     477           4 :         git_helper.info("Git repo up to date.");
     478           4 :         return ETRC_RET(0);
     479             :     }
     480           1 :     if (merge_analysis_result != git::MergeAnalysisResult::FASTFORWARD)
     481             :     {
     482           0 :         git_helper.warn("Sync manifest aborted: can't be fastforwarded.");
     483           0 :         return ETRC_RET(-6);
     484             :     }
     485             : 
     486             :     // For a fastforward, there should be only one commit
     487           1 :     if (commits.size() != 1)
     488             :     {
     489           0 :         git_helper.error("Fast forward failed.");
     490           0 :         return ETRC_RET(-7);
     491             :     }
     492             : 
     493           1 :     git_helper.info("Fast forwarding git repo ...");
     494             : 
     495           1 :     result = git_helper.fastforward(commits[0], log::Level::DEBUG);
     496           1 :     if (result.error())
     497             :     {
     498           0 :         git_helper.error("Fast forward failed.");
     499           0 :         return ETRC_RET(-8);
     500             :     }
     501           1 :     git_helper.info("Fast forward completed.");
     502           1 :     return ETRC_RET(0);
     503           7 : }
     504             : 
     505           0 : int SyncRepo::branch_sync(GitHelper &git_helper)
     506             : {
     507           0 :     int result_int = false;
     508           0 :     ETRC_CALL_RET_NP(result_int);
     509             : 
     510           0 :     if (!has_branch(git_helper, get_branch())) return ETRC_RET(normal_sync(git_helper));
     511             : 
     512           0 :     Result result = git_helper.checkout(get_branch(), get_force(), log::Level::DEBUG);
     513           0 :     if (result.ok())
     514           0 :         info("Checkout branch " + get_branch() + ".");
     515             :     else
     516           0 :         error("Failed to checkout branch " + get_branch() + ".");
     517           0 :     return ETRC_RET(result.get_result_code_int());
     518           0 : }
     519             : 
     520           0 : void SyncRepo::set_log_level(log::Level log_level)
     521             : {
     522           0 :     m_log_level = log_level;
     523           0 : }
     524             : 
     525          21 : log::Level SyncRepo::get_log_level()
     526             : {
     527          21 :     return m_log_level;
     528             : }
     529             : 
     530         120 : void SyncRepo::set_repo_idx(std::size_t repo_idx)
     531             : {
     532         120 :     m_repo_idx = repo_idx;
     533         120 : }
     534             : 
     535           0 : std::size_t SyncRepo::get_repo_idx() const
     536             : {
     537           0 :     return m_repo_idx;
     538             : }
     539             : 
     540         253 : std::size_t &SyncRepo::get_repo_idx()
     541             : {
     542         253 :     return m_repo_idx;
     543             : }
     544             : 
     545         120 : void SyncRepo::set_display_repo_idx(bool display_repo_idx)
     546             : {
     547         120 :     m_display_repo_idx = display_repo_idx;
     548         120 : }
     549             : 
     550           7 : bool SyncRepo::get_display_repo_idx() const
     551             : {
     552           7 :     return m_display_repo_idx;
     553             : }
     554             : 
     555         113 : std::string SyncRepo::get_repo_url()
     556             : {
     557         113 :     assert(get_repo() != nullptr);
     558         113 :     assert(get_repo()->get_location() != nullptr);
     559             : 
     560         113 :     std::string url;
     561         113 :     if (!get_alt_address())
     562         339 :         url = get_repo()->get_location()->get_address();
     563             :     else
     564           0 :         url = get_repo()->get_location()->get_alt_address();
     565             : 
     566         226 :     url += "/" + get_repo()->get_name();
     567             : 
     568         113 :     return url;
     569           0 : }
     570             : 
     571          13 : void SyncRepo::set_branch(const std::string &branch)
     572             : {
     573          13 :     m_branch = branch;
     574          13 : }
     575             : 
     576         276 : const std::string &SyncRepo::get_branch() const
     577             : {
     578         276 :     return m_branch;
     579             : }
     580             : 
     581         120 : void SyncRepo::set_alt_address(bool alt_address)
     582             : {
     583         120 :     m_alt_address = alt_address;
     584         120 : }
     585             : 
     586         113 : bool SyncRepo::get_alt_address() const
     587             : {
     588         113 :     return m_alt_address;
     589             : }
     590             : 
     591         122 : void SyncRepo::set_manifest(std::shared_ptr<Manifest> manifest)
     592             : {
     593         122 :     m_manifest = manifest;
     594         122 : }
     595             : 
     596           0 : std::shared_ptr<Manifest> SyncRepo::get_manifest() const
     597             : {
     598           0 :     return m_manifest;
     599             : }
     600             : 
     601           0 : void SyncRepo::set_force(bool force)
     602             : {
     603           0 :     m_force = force;
     604           0 : }
     605             : 
     606          14 : bool SyncRepo::get_force() const
     607             : {
     608          14 :     return m_force;
     609             : }
     610             : 
     611         120 : void SyncRepo::set_workspace_root_clone_method(WorkspaceRootCloneMethod method)
     612             : {
     613         120 :     m_workspace_root_clone_method = method;
     614         120 : }
     615             : 
     616          14 : WorkspaceRootCloneMethod SyncRepo::get_workspace_root_clone_method() const
     617             : {
     618          14 :     return m_workspace_root_clone_method;
     619             : }
     620             : 
     621         120 : void SyncRepo::set_clone_options(const git::CloneOptions &options)
     622             : {
     623         120 :     m_clone_options = options;
     624         120 : }
     625             : 
     626          99 : const git::CloneOptions &SyncRepo::get_clone_options() const
     627             : {
     628          99 :     return m_clone_options;
     629             : }
     630             : 
     631         120 : void SyncRepo::set_update_submodules(bool update)
     632             : {
     633         120 :     m_update_submodules = update;
     634         120 : }
     635             : 
     636         120 : bool SyncRepo::get_update_submodules() const
     637             : {
     638         120 :     return m_update_submodules;
     639             : }
     640             : 
     641         120 : int SyncRepo::maybe_update_submodules(const std::string &abs_path)
     642             : {
     643         120 :     int result = 0;
     644         120 :     ETRC_CALL_RET(result, abs_path);
     645             : 
     646         120 :     if (!get_update_submodules()) return ETRC_RET(0);
     647             : 
     648           0 :     auto git = get_git();
     649           0 :     if (git == nullptr) return ETRC_RET(-1);
     650             : 
     651           0 :     Result rresult = git->update_submodules(abs_path, true);
     652           0 :     if (rresult.error())
     653             :     {
     654           0 :         error("Failed to update Git submodules for '" + abs_path + "'");
     655           0 :         return ETRC_RET(rresult.get_result_code_int());
     656             :     }
     657           0 :     return ETRC_RET(0);
     658         120 : }
     659             : 
     660             : } // namespace esys::repo::manifest

Generated by: LCOV version 1.14