LCOV - code coverage report
Current view: top level - src/esys/repo/exe - cmdstatus.cpp (source / functions) Hit Total Coverage
Test: esysrepo_coverage.info Lines: 104 147 70.7 %
Date: 2026-08-01 10:43:40 Functions: 11 15 73.3 %

          Line data    Source code
       1             : /*!
       2             :  * \file esys/repo/exe/cmdstatus.cpp
       3             :  * \brief
       4             :  *
       5             :  * \cond
       6             :  * __legal_b__
       7             :  *
       8             :  * Copyright (c) 2020-2021 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/cmdstatus.h"
      20             : #include "esys/repo/manifest/repository.h"
      21             : #include "esys/repo/githelper.h"
      22             : 
      23             : #include <termcolor/termcolor.hpp>
      24             : 
      25             : #include <boost/filesystem.hpp>
      26             : 
      27             : #include <sstream>
      28             : #include <iomanip>
      29             : 
      30             : namespace esys::repo::exe
      31             : {
      32             : 
      33          18 : CmdStatus::CmdStatus()
      34          36 :     : Cmd("Status")
      35             : {
      36          18 : }
      37             : 
      38          21 : CmdStatus::~CmdStatus() = default;
      39             : 
      40           0 : void CmdStatus::set_quiet(bool quiet)
      41             : {
      42           0 :     m_quiet = quiet;
      43           0 : }
      44             : 
      45           3 : bool CmdStatus::get_quiet() const
      46             : {
      47           3 :     return m_quiet;
      48             : }
      49             : 
      50           3 : Result CmdStatus::impl_run()
      51             : {
      52           3 :     if (get_quiet()) warn("The option --quiet is not implemented yet");
      53             : 
      54           3 :     Result result = process_sub_args_to_find_parent_path();
      55           3 :     if (result.error())
      56             :     {
      57           0 :         std::string err_str = "No ESysRepo folder found";
      58           0 :         error(err_str);
      59           0 :         return ESYSREPO_RESULT(result, ResultCode::CMD_NO_ESYSREPO_FOLDER_FOUND, err_str);
      60           0 :     }
      61             : 
      62           3 :     result = open_esysrepo_folder();
      63           3 :     if (result.error()) return ESYSREPO_RESULT(result);
      64             : 
      65           3 :     result = load_manifest();
      66           3 :     if (result.error()) return ESYSREPO_RESULT(result);
      67             : 
      68           3 :     result = process_sub_args_as_git_repo_paths();
      69           3 :     if (result.error()) return ESYSREPO_RESULT(result);
      70             : 
      71           3 :     std::map<std::string, int> map_input_repo_paths;
      72             : 
      73           3 :     if (get_input_git_repo_paths().size() != 0)
      74             :     {
      75           0 :         for (auto &path : get_input_git_repo_paths())
      76             :         {
      77           0 :             auto repo = get_manifest()->find_repo_by_path(path);
      78           0 :             if (repo != nullptr) map_input_repo_paths[path] = 1;
      79           0 :         }
      80             :     }
      81             : 
      82           3 :     Result rresult;
      83             : 
      84          12 :     for (auto location : get_manifest()->get_locations())
      85             :     {
      86          36 :         for (auto repo : location->get_repos())
      87             :         {
      88          30 :             if (map_input_repo_paths.size() != 0)
      89             :             {
      90           0 :                 if (map_input_repo_paths.find(repo->get_path()) == map_input_repo_paths.end()) continue;
      91             :             }
      92          60 :             result = open_repo(repo);
      93          30 :             if (result.error())
      94             :             {
      95           0 :                 rresult.add(ESYSREPO_RESULT(result));
      96           0 :                 continue;
      97             :             }
      98          90 :             print_repo(repo);
      99          30 :         }
     100           6 :     }
     101             : 
     102           6 :     return ESYSREPO_RESULT(rresult);
     103           6 : }
     104             : 
     105          30 : Result CmdStatus::open_repo(std::shared_ptr<manifest::Repository> repo)
     106             : {
     107          30 :     auto git_helper = new_git_helper();
     108          30 :     git_helper->set_auto_close();
     109             : 
     110          30 :     boost::filesystem::path rel_repo_path;
     111          30 :     boost::filesystem::path repo_path = get_config_folder()->get_workspace_path();
     112          30 :     repo_path /= repo->get_path();
     113          90 :     repo_path = boost::filesystem::absolute(repo_path).lexically_normal().make_preferred();
     114          60 :     rel_repo_path = boost::filesystem::relative(repo_path);
     115             : 
     116          30 :     m_rel_repo_path = rel_repo_path.string();
     117          30 :     m_repo_path = repo_path.string();
     118             : 
     119          30 :     Result result = git_helper->open(repo_path.string(), log::Level::DEBUG);
     120          30 :     if (result.error()) return ESYSREPO_RESULT(result);
     121             : 
     122          30 :     m_repo_status = std::make_shared<git::RepoStatus>();
     123             : 
     124          30 :     result = git_helper->get_status(*m_repo_status, log::Level::DEBUG);
     125          30 :     if (result.error()) return ESYSREPO_RESULT(result);
     126             : 
     127          30 :     m_repo_status->sort_file_status();
     128             : 
     129          30 :     m_branches.clear();
     130             : 
     131          30 :     result = git_helper->get_branches(m_branches, git::BranchType::LOCAL, log::Level::DEBUG);
     132          30 :     if (result.error()) return ESYSREPO_RESULT(result);
     133             : 
     134          30 :     m_branches.sort();
     135             : 
     136          30 :     return ESYSREPO_RESULT(git_helper->close(log::Level::DEBUG));
     137          60 : }
     138             : 
     139          30 : void CmdStatus::print_repo(std::shared_ptr<manifest::Repository> repo)
     140             : {
     141          30 :     std::ostringstream oss;
     142          30 :     std::string first_part;
     143          30 :     std::string cur_branch;
     144             : 
     145          30 :     oss << termcolor::colorize;
     146             : 
     147          30 :     if (m_branches.size() != 0)
     148             :     {
     149          30 :         if (m_branches.get()[0]->get_is_head()) cur_branch = m_branches.get()[0]->get_name();
     150             :     }
     151             : 
     152          30 :     if (m_repo_status->get_file_status().size() == 0)
     153             :     {
     154          81 :         std::string rev = get_manifest()->get_repo_revision(repo);
     155             : 
     156          27 :         auto index = rev.find("refs/heads/");
     157          27 :         if (index != rev.npos) rev = rev.substr(index + std::strlen("refs/heads/"));
     158             : 
     159          27 :         if (rev == cur_branch) return;
     160          27 :     }
     161             : 
     162           3 :     first_part = "Repository : " + repo->get_path();
     163           3 :     oss << std::setw(get_start_print_branch()) << std::setfill(' ') << std::left << first_part;
     164             : 
     165           3 :     if (!cur_branch.empty()) oss << cur_branch;
     166             : 
     167           7 :     for (auto file_status : m_repo_status->get_file_status())
     168             :     {
     169           4 :         oss << std::endl;
     170          12 :         print(oss, file_status);
     171           4 :     }
     172             : 
     173           6 :     info(oss.str());
     174          30 : }
     175             : 
     176           4 : void CmdStatus::print(std::ostream &os, std::shared_ptr<git::FileStatus> file_status)
     177             : {
     178          12 :     os << get_file_status_header(file_status);
     179           4 :     os << "  ";
     180           4 :     if (get_show_file_permission())
     181             :     {
     182           4 :         bool executable = false;
     183           8 :         if (file_status->get_index_to_work_dir() != nullptr)
     184           4 :             executable = (file_status->get_index_to_work_dir()->get_diff_delta().get_old_file().get_mode()
     185             :                           == git::FileMode::BLOB_EXECUTABLE);
     186           4 :         if (executable)
     187           0 :             os << termcolor::red << "x  ";
     188             :         else
     189           4 :             os << "-  ";
     190             :     }
     191             :     else
     192           0 :         os << "   ";
     193             : 
     194           4 :     os << file_status->get_old_name() << termcolor::reset;
     195           4 : }
     196             : 
     197           4 : std::string CmdStatus::get_file_status_header(std::shared_ptr<git::FileStatus> file_status)
     198             : {
     199           4 :     std::string result = "--";
     200           4 :     std::shared_ptr<git::Status> status;
     201             : 
     202           8 :     for (auto status : file_status->get_status())
     203             :     {
     204           4 :         switch (status->get_type())
     205             :         {
     206           0 :             case git::StatusType::CURRENT: result = "--"; break;
     207           0 :             case git::StatusType::INDEX:
     208           0 :                 switch (status->get_sub_type())
     209             :                 {
     210           0 :                     case git::StatusSubType::DELETED: result[0] = 'D'; break;
     211           0 :                     case git::StatusSubType::MODIFIED: result[0] = 'M'; break;
     212           0 :                     case git::StatusSubType::NEW: result[0] = 'A'; break;
     213           0 :                     case git::StatusSubType::RENAMED: result[0] = 'R'; break;
     214           0 :                     case git::StatusSubType::TYPECHANGE: result[0] = 'T'; break;
     215             :                     default:;
     216             :                 }
     217             :                 break;
     218           4 :             case git::StatusType::WORKING_DIR:
     219           4 :                 switch (status->get_sub_type())
     220             :                 {
     221           0 :                     case git::StatusSubType::MODIFIED: result[1] = 'm'; break;
     222           0 :                     case git::StatusSubType::DELETED: result[1] = 'd'; break;
     223             :                     default:;
     224             :                 }
     225             :                 break;
     226           0 :             case git::StatusType::CONFLICTED: result[0] = 'U'; break;
     227           4 :             default:;
     228             :         }
     229           4 :     }
     230             : 
     231           4 :     return result;
     232           4 : }
     233           0 : void CmdStatus::set_start_print_branch(std::size_t start_print_branch)
     234             : {
     235           0 :     m_start_print_branch = start_print_branch;
     236           0 : }
     237             : 
     238           3 : std::size_t CmdStatus::get_start_print_branch() const
     239             : {
     240           3 :     return m_start_print_branch;
     241             : }
     242             : 
     243           0 : void CmdStatus::set_show_file_permission(bool show_file_permission)
     244             : {
     245           0 :     m_show_file_permission = show_file_permission;
     246           0 : }
     247             : 
     248           4 : bool CmdStatus::get_show_file_permission() const
     249             : {
     250           4 :     return m_show_file_permission;
     251             : }
     252             : 
     253           3 : Result CmdStatus::process_sub_args_to_find_parent_path()
     254             : {
     255           3 :     if (!get_workspace_path().empty()) return ESYSREPO_RESULT(ResultCode::OK);
     256             : 
     257           2 :     if ((get_sub_args().size() == 0) || (!get_folder().empty()) || (!get_workspace_path().empty()))
     258           2 :         return ESYSREPO_RESULT(default_handling_folder_workspace());
     259             : 
     260           0 :     std::string parent_path;
     261             : 
     262           0 :     for (auto &path : get_sub_args())
     263             :     {
     264             :         // if (!boost::filesystem::exists(path)) continue;
     265           0 :         parent_path = Cmd::find_workspace_path(path);
     266           0 :         if (!parent_path.empty())
     267             :         {
     268           0 :             set_workspace_path(parent_path);
     269           0 :             return ESYSREPO_RESULT(ResultCode::OK);
     270             :         }
     271             :     }
     272             : 
     273           0 :     parent_path = Cmd::find_workspace_path();
     274           0 :     if (parent_path.empty()) return ESYSREPO_RESULT(ResultCode::CMD_WORKSPACE_PATH_IS_EMPTY);
     275             : 
     276           0 :     set_workspace_path(parent_path);
     277           0 :     return ESYSREPO_RESULT(ResultCode::OK);
     278           3 : }
     279             : 
     280             : } // namespace esys::repo::exe

Generated by: LCOV version 1.14