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).
Additionally, the following metadata will be copied from the top-level parser to the sub-parser:
- sharg::parser::info::version
- sharg::parser::info::author
- sharg::parser::info::email
- sharg::parser::info::date
- sharg::parser::info::url
- sharg::parser::info::short_copyright
- sharg::parser::info::long_copyright
- sharg::parser::info::citation
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:158
void add_positional_option(option_type &value, config< validator_type > const &config)
Adds a positional option to the sharg::parser.
Definition parser.hpp:329
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:418
parser & get_sub_parser()
Returns a reference to the sub-parser instance if subcommand parsing was enabled.
Definition parser.hpp:452
@ 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.