This HowTo shows you how to write a parser with subcommands like git push
using Sharg.
Motivation
A common use case for command line tools, e.g. git
, is to have multiple subcommands, e.g. git fetch
or git push
. Each subcommand has its own set of options and its own help page. This HowTo explains how this can be done with the sharg::parser and serves as a copy'n'paste source. If you are new to Sharg, we recommend to do the basic parser tutorial before you read further.
A subcommand parser
In order to keep parsing with subcommands straightforward and simple, the sharg::parser provides an advanced interface that internally takes care of the correct input parsing.
You simply need to specify the names of the subcommands when constructing your top-level parser:
- Attention
- You can still add flags to your top-level parser if needed but no (positional) options. This avoids ambiguous parsing (e.g. subcommand fasta given file extension fasta
./myfasta_parser --filext fasta fasta ...
).
After calling sharg::parser::parse() on your top-level parser, you can then access the sub-parser via the function sharg::parser::get_sub_parser():
The sub-parser's sharg::parser::info::app_name will be set to the user chosen sub command. For example, if the user calls
then the sub-parser will be named mygit-push
and will be instantiated with all arguments followed by the keyword push
which in this case triggers printing the help page (-h
).
That's it. Here is a full example of a subcommand parser you can try and adjust to your needs:
struct pull_arguments
{
bool progress{false};
};
{
pull_arguments args{};
try
{
}
{
return -1;
}
std::cerr <<
"Git pull with repository " << args.repository <<
" and branch " << args.branch <<
'\n';
return 0;
}
struct push_arguments
{
bool push_all{false};
};
{
push_arguments args{};
try
{
}
{
return -1;
}
std::cerr <<
"Git push with repository " << args.repository <<
" and branches ";
for (auto && branch : args.branches)
std::cerr << branch <<
' ';
return 0;
}
int main(int argc, char const ** argv)
{
bool flag{false};
top_level_parser.add_flag(flag,
sharg::config{.
short_id =
'f', .long_id =
"flag", .description =
"some flag"});
try
{
top_level_parser.parse();
}
{
return -1;
}
return run_git_pull(sub_parser);
return run_git_push(sub_parser);
else
return 0;
}
Meta-header for the Parser module .
Parser exception that is thrown whenever there is an error while parsing the command line arguments.
Definition exceptions.hpp:40
The Sharg command line parser.
Definition parser.hpp:154
void add_positional_option(option_type &value, config< validator_type > const &config)
Adds a positional option to the sharg::parser.
Definition parser.hpp:325
parser_meta_data info
Aggregates all parser related meta data (see sharg::parser_meta_data struct).
Definition parser.hpp:713
void parse()
Initiates the actual command line parsing.
Definition parser.hpp:414
parser & get_sub_parser()
Returns a reference to the sub-parser instance if subcommand parsing was enabled.
Definition parser.hpp:448
@ on
Automatic update notifications should be enabled.
Option struct that is passed to the sharg::parser::add_option() function.
Definition config.hpp:43
char short_id
The short identifier for the option (e.g. 'a', making the option callable via -a).
Definition config.hpp:53
Recursive subcommands
If you want to have subcommands with subcommands, you can add subcommands to the sub-parser with sharg::parser::add_subcommands():
{
git_parser.add_subcommands({"remote"});
git_parser.parse();
{
auto & pull_parser = sub_parser;
pull_parser.parse();
}
{
auto & push_parser = sub_parser;
push_parser.parse();
}
{
auto & remote_parser = sub_parser;
remote_parser.parse();
{
auto & set_url_parser = recursive_sub_parser;
set_url_parser.add_positional_option(repository,
sharg::config{});
set_url_parser.parse();
}
{
auto & show_parser = recursive_sub_parser;
}
}
}
int main(int argc, char ** argv)
{
try
{
run({argv, argv + argc});
}
{
}
return 0;
}
void add_subcommands(std::vector< std::string > const &subcommands)
Adds subcommands to the parser.
Definition parser.hpp:652
@ off
Automatic update notifications should be disabled.