35 }
catch (
const std::exception&) {
43 :
std::runtime_error(msg), status_(status) {
45 CHECK(
status_ != 0 || msg.empty());
57 : programName_(
std::
move(programName)),
58 programHeading_(
std::
move(programHeading)),
59 programHelpFooter_(
std::
move(programHelpFooter)),
61 initFunction_(
std::
move(initFunction)),
62 globalOptions_(
"Global options") {
66 "Display help (globally or for a given command)",
67 "Displays help (globally or for a given command).",
69 const po::variables_map& vm,
const std::vector<std::string>& args) {
77 "Display version information",
78 "Displays version information.",
79 [
this](
const po::variables_map&,
const std::vector<std::string>&) {
86 "Display help (globally or for a given command)")(
101 po::options_description(
folly::sformat(
"Options for `{}'", name))};
104 CHECK(p.second) <<
"Command already exists";
106 return p.first->second.options;
111 <<
"Alias old name does not exist";
113 <<
"Alias new name already exists";
118 const po::variables_map& ,
119 const std::vector<std::string>& args)
const {
123 "%s\nUsage: %s [global_options...] <command> [command_options...] " 124 "[command_args...]\n\n",
128 printf(
"\nAvailable commands:\n");
132 maxLen =
std::max(maxLen, p.first.size());
135 maxLen =
std::max(maxLen, p.first.size());
138 for (
auto& p : commands_) {
143 p.second.shortHelp.c_str());
146 if (!aliases_.empty()) {
147 printf(
"\nAvailable aliases:\n");
148 for (
auto& p : aliases_) {
160 if (p.first != args.front()) {
162 "`%s' is an alias for `%s'; showing help for `%s'\n",
163 args.front().c_str(),
167 auto&
info = p.second;
170 "Usage: %s [global_options...] %s%s%s%s\n\n",
173 info.options.options().empty() ?
"" :
" [command_options...]",
174 info.argStr.empty() ?
"" :
" ",
175 info.argStr.c_str());
177 printf(
"%s\n", info.fullHelp.c_str());
181 if (!info.options.options().empty()) {
183 std::cout << info.options;
206 ->
const std::pair<const std::string, CommandInfo>& {
212 "Command '{}' not found. Run '{} {}' for help.",
224 return run(std::vector<std::string>(argv + 1, argv + argc));
234 fprintf(stderr,
"%s\n", ex.what());
242 "{}. Run '{} help' for {}.\n",
251 if (ferror(stdout)) {
252 fprintf(stderr,
"error on standard output\n");
254 }
else if (fflush(stdout)) {
257 "standard output flush failed: %s\n",
271 bool not_clean =
false;
272 std::vector<std::string> cleanArgs;
273 std::vector<std::string> endArgs;
275 for (
auto& na : args) {
278 }
else if (not_clean) {
279 endArgs.push_back(na);
281 cleanArgs.push_back(na);
286 po::variables_map vm;
287 po::store(parsed.options, vm);
289 std::vector<std::string> helpArgs;
290 if (parsed.command) {
291 helpArgs.push_back(*parsed.command);
302 if (!parsed.command) {
306 "Command not specified. Run '{} {}' for help.",
313 auto&
info = p.second;
316 po::command_line_parser(parsed.rest).options(
info.options).run();
318 po::store(cmdOptions, vm);
322 po::collect_unrecognized(cmdOptions.options, po::include_positional);
324 cmdArgs.insert(cmdArgs.end(), endArgs.begin(), endArgs.end());
330 info.command(vm, cmdArgs);
std::function< void(const std::string &command, const boost::program_options::variables_map &options, const std::vector< std::string > &args)> InitFunction
NestedCommandLineApp(std::string programName=std::string(), std::string version=std::string(), std::string programHeading=std::string(), std::string programHelpFooter=std::string(), InitFunction initFunction=InitFunction())
std::map< std::string, std::string > aliases_
std::string sformat(StringPiece fmt, Args &&...args)
void addAlias(std::string newName, std::string oldName)
void displayHelp(const boost::program_options::variables_map &options, const std::vector< std::string > &args) const
NestedCommandLineParseResult parseNestedCommandLine(int argc, const char *const argv[], const po::options_description &desc)
constexpr detail::Map< Move > move
std::string programHelpFooter_
const std::pair< const std::string, CommandInfo > & findCommand(const std::string &name) const
InitFunction initFunction_
—— Concurrent Priority Queue Implementation ——
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
boost::program_options::options_description & addCommand(std::string name, std::string argStr, std::string shortHelp, std::string fullHelp, Command command)
boost::program_options::options_description globalOptions_
static constexpr StringPiece const kVersionCommand
bool isBuiltinCommand(const std::string &name) const
std::function< void(const boost::program_options::variables_map &options, const std::vector< std::string > &)> Command
void doRun(const std::vector< std::string > &args)
std::string programHeading_
fbstring errnoStr(int err)
void displayVersion() const
std::map< std::string, CommandInfo > commands_
const std::string & resolveAlias(const std::string &name) const
int run(int argc, const char *const argv[])
std::set< folly::StringPiece > builtinCommands_
static constexpr StringPiece const kHelpCommand
ProgramExit(int status, const std::string &msg=std::string())