LCOV - code coverage report
Current view: top level - src/esys/repo/cli - cmd_cli.cpp (source / functions) Hit Total Coverage
Test: esysrepo_coverage.info Lines: 101 161 62.7 %
Date: 2026-08-01 10:43:40 Functions: 24 42 57.1 %

          Line data    Source code
       1             : /*!
       2             :  * \file esys/repo/cli/cmd_cli.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/cli/cmd.h"
      20             : #include "esys/repo/cli/appbase.h"
      21             : 
      22             : #include <boost/program_options/parsers.hpp>
      23             : #include <boost/tokenizer.hpp>
      24             : 
      25             : #include <cassert>
      26             : 
      27             : namespace esys::repo::cli
      28             : {
      29             : 
      30         171 : Cmd::Cmd(AppBase *app, const std::string &name, const std::string &description)
      31             :     : esys::log::User()
      32         171 :     , m_name(name)
      33         171 :     , m_description(description)
      34         342 :     , m_app(app)
      35             : {
      36         171 :     m_positional.add("command", 1).add("subargs", -1);
      37             : 
      38         171 :     if (app != nullptr) app->register_cmd(this);
      39         171 : }
      40             : 
      41         434 : Cmd::~Cmd() = default;
      42             : 
      43           0 : void Cmd::set_name(const std::string &name)
      44             : {
      45           0 :     m_name = name;
      46           0 : }
      47             : 
      48         348 : const std::string &Cmd::get_name() const
      49             : {
      50         348 :     return m_name;
      51             : }
      52             : 
      53           0 : void Cmd::set_description(const std::string &description)
      54             : {
      55           0 :     m_description = description;
      56           0 : }
      57             : 
      58          31 : const std::string &Cmd::get_description() const
      59             : {
      60          31 :     return m_description;
      61             : }
      62             : 
      63           0 : void Cmd::set_app(AppBase *app)
      64             : {
      65           0 :     m_app = app;
      66           0 : }
      67             : 
      68           0 : AppBase *Cmd::get_app()
      69             : {
      70           0 :     return m_app;
      71             : }
      72             : 
      73          27 : std::shared_ptr<po::options_description> Cmd::get_common_desc()
      74             : {
      75          27 :     if (m_common_desc != nullptr) return m_common_desc;
      76             : 
      77          27 :     m_common_desc = std::make_shared<po::options_description>("Common options");
      78             :     // clang-format off
      79          27 :     m_common_desc->add_options()
      80          27 :         ("help,h", "Produce help message")
      81          27 :         ("command", po::value<std::string>()->required(), "Command to execute")
      82          27 :         ("subargs", po::value<std::vector<std::string>>(), "Arguments for command")
      83          27 :         ("time", po::value<bool>()->default_value(false)->implicit_value(true), "Display timestamp")
      84          27 :         ("delta-time", po::value<bool>()->default_value(false)->implicit_value(true), "Display delta timestamp")
      85          27 :         ("public", po::value<bool>()->default_value(false)->implicit_value(true), "Only use https when possible")
      86          27 :         ("log", po::value<std::vector<std::string>>(), "Log execution to a file")
      87          27 :         ("verbose", po::value<int>()->default_value(0)->implicit_value(1), "Set verbose level")
      88          27 :         ("debug", po::value<bool>()->default_value(false)->implicit_value(true), "Set debug mode")
      89          27 :         ("workspace,w", po::value<std::string>(), "the path to the workspade to use")
      90          27 :         ("folder,f", po::value<std::string>(), "the folder to work with")
      91          27 :         ("trace", "enable execution trace to a file and to the console")
      92          27 :         ("trace-file", "enable execution trace to a file")
      93          27 :         ("trace-cons", "enable execution trace to the console")
      94             :         ;
      95             :     // clang-format on
      96          27 :     return m_common_desc;
      97             : }
      98             : 
      99          21 : std::shared_ptr<po::options_description> Cmd::get_desc()
     100             : {
     101          21 :     return m_desc;
     102             : }
     103             : 
     104           0 : void Cmd::set_desc_all(std::shared_ptr<po::options_description> desc_all)
     105             : {
     106           0 :     m_desc_all = desc_all;
     107           0 : }
     108             : 
     109          50 : std::shared_ptr<po::options_description> Cmd::get_desc_all()
     110             : {
     111          50 :     if (m_desc_all != nullptr) return m_desc_all;
     112             : 
     113          27 :     m_desc_all = std::make_shared<po::options_description>();
     114          27 :     auto desc = get_desc();
     115          27 :     if (desc != nullptr) m_desc_all->add(*desc);
     116             : 
     117          27 :     m_desc_all->add(*get_common_desc());
     118             : 
     119          54 :     return m_desc_all;
     120          50 : }
     121             : 
     122          34 : void Cmd::set_args(const std::vector<std::string> &args)
     123             : {
     124          34 :     m_args = args;
     125          34 : }
     126             : 
     127          50 : std::vector<std::string> &Cmd::get_args()
     128             : {
     129          50 :     return m_args;
     130             : }
     131             : 
     132           0 : const std::vector<std::string> &Cmd::get_args() const
     133             : {
     134           0 :     return m_args;
     135             : }
     136             : 
     137          50 : int Cmd::parse(bool strict)
     138             : {
     139          50 :     bool parse_error = false;
     140             : 
     141          50 :     m_to_parse_further.clear();
     142          50 :     m_vm.clear();
     143             : 
     144          50 :     try
     145             :     {
     146          50 :         if (strict == false)
     147             :         {
     148           0 :             po::parsed_options parsed = po::command_line_parser(get_args())
     149           0 :                                             .options(*get_desc_all())
     150           0 :                                             .positional(m_positional)
     151           0 :                                             .allow_unregistered()
     152           0 :                                             .run();
     153           0 :             m_to_parse_further = po::collect_unrecognized(parsed.options, po::include_positional);
     154           0 :             po::store(parsed, m_vm);
     155           0 :         }
     156             :         else
     157             :         {
     158          50 :             po::parsed_options parsed =
     159         100 :                 po::command_line_parser(get_args()).options(*get_desc_all()).positional(m_positional).run();
     160          50 :             m_to_parse_further = po::collect_unrecognized(parsed.options, po::include_positional);
     161          50 :             po::store(parsed, m_vm);
     162          50 :         }
     163          50 :         po::notify(m_vm);
     164             :     }
     165           2 :     catch (po::error &e)
     166             :     {
     167           2 :         parse_error = true;
     168           2 :         error(e.what());
     169           0 :     }
     170             : 
     171           2 :     if (parse_error) return -1;
     172             :     return 0;
     173             : }
     174             : 
     175          48 : int Cmd::configure_cmd(exe::Cmd &cmd)
     176             : {
     177          48 :     cmd.set_workspace_path(get_workspace());
     178          48 :     cmd.set_folder(get_folder());
     179          48 :     cmd.set_debug(get_debug());
     180          48 :     cmd.set_sub_args(get_sub_args());
     181          48 :     cmd.set_time(get_time());
     182          48 :     cmd.set_delta_time(get_delta_time());
     183             :     // \TODO add all missing data
     184          48 :     return 0;
     185             : }
     186             : 
     187           0 : int Cmd::print_doc(std::ostream &os)
     188             : {
     189           0 :     return -1;
     190             : }
     191             : 
     192           0 : int Cmd::print_help(std::ostream &os)
     193             : {
     194           0 :     std::ostringstream oss;
     195             : 
     196           0 :     oss << "Usage: esysrepo " << get_name() << " [" << get_name() << "_options] [common_options]" << std::endl;
     197             : 
     198           0 :     auto desc_all = get_desc_all();
     199           0 :     if (desc_all == nullptr) return -1;
     200           0 :     oss << *desc_all;
     201           0 :     os << oss.str();
     202           0 :     return 0;
     203           0 : }
     204             : 
     205          16 : void Cmd::set_console_os(std::ostream *console_os)
     206             : {
     207          16 :     m_console_os = console_os;
     208          16 : }
     209             : 
     210          16 : std::ostream *Cmd::get_console_os()
     211             : {
     212          16 :     return m_console_os;
     213             : }
     214             : 
     215           0 : bool Cmd::is_help()
     216             : {
     217           0 :     return is_present("help");
     218             : }
     219             : 
     220           0 : std::string Cmd::get_command()
     221             : {
     222           0 :     return get_string("command");
     223             : }
     224             : 
     225          48 : bool Cmd::get_time()
     226             : {
     227          48 :     return get_bool("time");
     228             : }
     229             : 
     230          48 : bool Cmd::get_delta_time()
     231             : {
     232          48 :     return get_bool("delta-time");
     233             : }
     234             : 
     235           0 : bool Cmd::get_public()
     236             : {
     237           0 :     return get_bool("public");
     238             : }
     239             : 
     240           0 : int Cmd::get_verbose()
     241             : {
     242           0 :     return get_int("verbose", 0);
     243             : }
     244             : 
     245          48 : bool Cmd::get_debug()
     246             : {
     247          48 :     return get_bool("debug");
     248             : }
     249             : 
     250          48 : std::string Cmd::get_workspace()
     251             : {
     252          96 :     return get_string("workspace");
     253             : }
     254             : 
     255          48 : std::string Cmd::get_folder()
     256             : {
     257          96 :     return get_string("folder");
     258             : }
     259             : 
     260          54 : std::vector<std::string> Cmd::get_sub_args()
     261             : {
     262         110 :     if (m_vm.count("subargs") == 0) return std::vector<std::string>();
     263             : 
     264           6 :     return m_vm["subargs"].as<std::vector<std::string>>();
     265             : }
     266             : 
     267           0 : std::shared_ptr<UserFolder> Cmd::get_user_folder() const
     268             : {
     269           0 :     return m_user_folder;
     270             : }
     271             : 
     272          17 : void Cmd::set_user_folder(std::shared_ptr<UserFolder> user_folder)
     273             : {
     274          17 :     m_user_folder = user_folder;
     275          17 : }
     276             : 
     277          21 : void Cmd::set_desc(std::shared_ptr<po::options_description> desc)
     278             : {
     279          21 :     m_desc = desc;
     280          21 : }
     281             : 
     282          96 : std::string Cmd::get_string(const std::string &name)
     283             : {
     284          96 :     if (m_vm.count(name)) return m_vm[name].as<std::string>();
     285          72 :     return "";
     286             : }
     287             : 
     288           0 : bool Cmd::is_present(const std::string &name)
     289             : {
     290           0 :     return m_vm.count(name) > 0;
     291             : }
     292             : 
     293         144 : bool Cmd::get_bool(const std::string &name)
     294             : {
     295         144 :     if (m_vm.count(name)) return m_vm[name].as<bool>();
     296             :     return false;
     297             : }
     298             : 
     299           0 : int Cmd::get_int(const std::string &name, int dflt)
     300             : {
     301           0 :     if (m_vm.count(name)) return m_vm[name].as<int>();
     302             :     return dflt;
     303             : }
     304             : 
     305         328 : po::variables_map &Cmd::get_vm()
     306             : {
     307         328 :     return m_vm;
     308             : }
     309             : 
     310           0 : const po::variables_map &Cmd::get_vm() const
     311             : {
     312           0 :     return m_vm;
     313             : }
     314             : 
     315           0 : int Cmd::groups_str_to_groups(const std::string &groups_str, std::vector<std::string> &groups)
     316             : {
     317           0 :     typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
     318           0 :     boost::char_separator<char> sep(", ");
     319           0 :     tokenizer tokens(groups_str, sep);
     320             : 
     321           0 :     groups.clear();
     322             : 
     323           0 :     for (tokenizer::iterator it = tokens.begin(); it != tokens.end(); ++it) groups.push_back(*it);
     324             : 
     325           0 :     return 0;
     326           0 : }
     327             : 
     328             : } // namespace esys::repo::cli

Generated by: LCOV version 1.14