argparse
Subcommands
Many programs split up their functionality into a number of sub-commands, for example, the git
program can invoke sub-commands like git checkout
, git add
, and git commit
. Splitting up functionality this way can be a particularly good idea when a program performs several different functions which require different kinds of command-line arguments. ArgumentParser
now supports the creation of such sub-commands with add_subparser()
.
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("git");
// git add subparser
argparse::ArgumentParser add_command("add");
add_command.add_argument("files")
.help("Files to add content from. Fileglobs (e.g. *.c) can be given to add all matching files.")
.remaining();
// git commit subparser
argparse::ArgumentParser commit_command("commit");
commit_command.add_argument("-a", "--all")
.help("Tell the command to automatically stage files that have been modified and deleted.")
.default_value(false)
.implicit_value(true);
commit_command.add_argument("-m", "--message")
.help("Use the given <msg> as the commit message.");
// git cat-file subparser
argparse::ArgumentParser catfile_command("cat-file");
catfile_command.add_argument("-t")
.help("Instead of the content, show the object type identified by <object>.");
catfile_command.add_argument("-p")
.help("Pretty-print the contents of <object> based on its type.");
// git submodule subparser
argparse::ArgumentParser submodule_command("submodule");
argparse::ArgumentParser submodule_update_command("update");
submodule_update_command.add_argument("--init")
.default_value(false)
.implicit_value(true);
submodule_update_command.add_argument("--recursive")
.default_value(false)
.implicit_value(true);
submodule_command.add_subparser(submodule_update_command);
// Add the subcommands to the parent parser
program.add_subparser(add_command);
program.add_subparser(commit_command);
program.add_subparser(catfile_command);
program.add_subparser(submodule_command);
// Parse args
try {
program.parse_args(argc, argv);
}
catch (const std::runtime_error& err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
// Use arguments
}
foo@bar:/home/dev/$ ./git --help
Usage: git [options] <command> [<args>]
Optional arguments:
-h --help shows help message and exits [default: false]
-v --version prints version information and exits [default: false]
Subcommands:
add Add file contents to the index
cat-file Provide content or type and size information for repository objects
commit Record changes to the repository
submodule Initialize, update or inspect submodules
foo@bar:/home/dev/$ ./git add --help
Usage: git add [options] files
Add file contents to the index
Positional arguments:
files Files to add content from. Fileglobs (e.g. *.c) can be given to add all matching files.
Optional arguments:
-h --help shows help message and exits [default: false]
-v --version prints version information and exits [default: false]
foo@bar:/home/dev/$ ./git submodule --help
Usage: git submodule [options] <command> [<args>]
Initialize, update or inspect submodules
Optional arguments:
-h --help shows help message and exits [default: false]
-v --version prints version information and exits [default: false]
Subcommands:
update Update the registered submodules to match what the superproject expects
When a help message is requested from a subparser, only the help for that particular parser will be printed. The help message will not include parent parser or sibling parser messages.
Additionally, every parser has a .is_subcommand_used("<command_name>")
member function to check if a subcommand was used.
You can find relevant unit tests here.