diff --git a/CHANGELOG.md b/CHANGELOG.md index 20fc8d60..5672d3c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Version 0.5 (in progress) + +* Added `require_subcommand` to `App`, to simplify forcing subcommands. Do not "chain" with `add_subcommand`, since that is the subcommand, not the master `App`. Untested. + ## Version 0.4 * Updates to help print diff --git a/include/CLI/App.hpp b/include/CLI/App.hpp index a4f7e5f2..9feae078 100644 --- a/include/CLI/App.hpp +++ b/include/CLI/App.hpp @@ -47,6 +47,7 @@ protected: std::vector subcommands; bool parsed {false}; App* subcommand {nullptr}; + bool required_subcommand = false; std::string progname {"program"}; Option* help_flag {nullptr}; @@ -55,7 +56,7 @@ protected: std::string ini_file; bool ini_required {false}; Option* ini_setting {nullptr}; - + public: /// Create a new program. Pass in the same arguments as main(), along with a help string. @@ -117,7 +118,6 @@ public: return subcommands.back().get(); } - /// Add an option, will automatically understand the type for common types. /** To use, create a variable with the expected type, and pass it in after the name. * After start is called, you can use count to see if the value was passed, and @@ -332,6 +332,7 @@ public: } /// This allows subclasses to inject code before callbacks but after parse + /// This does not run if any errors or help is thrown. virtual void pre_callback() {} /// Parses the command line - throws errors @@ -411,8 +412,12 @@ public: pos=true; } - if(subcommands.size() > 0) - out << " [SUBCOMMANDS]"; + if(subcommands.size() > 0) { + if(required_subcommand) + out << " SUBCOMMAND"; + else + out << " [SUBCOMMAND]"; + } out << std::endl << std::endl; @@ -459,6 +464,10 @@ public: return name; } + /// Require a subcommand to be given (does not affect help call) + void require_subcommand(bool value = true) { + required_subcommand = value; + } protected: @@ -579,6 +588,9 @@ protected: throw ExcludesError(opt->get_name(), opt_ex->get_name()); } + if(required_subcommand && subcommand == nullptr) + throw RequiredError("Subcommand required"); + if(positionals.size()>0) throw PositionalError("[" + detail::join(positionals) + "]");