mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-05-03 14:03:52 +00:00
Adding string based method for requires/excludes
This commit is contained in:
parent
0ccd814ac9
commit
3f4c165ea9
@ -1,5 +1,6 @@
|
||||
## Version 0.6
|
||||
|
||||
* Added string versions of `->requires()` and `->excludes()` for consistency.
|
||||
* Renamed protected members for internal consistency, grouped docs.
|
||||
* Added the ability to add a number to `.require_subcommand()`.
|
||||
|
||||
|
@ -41,8 +41,7 @@ This library was built to supply the Application object for the GooFit CUDA/OMP
|
||||
* Collect user feedback
|
||||
* Ini configuration support is basic (long options only, no vector support), is more needed?
|
||||
* Evaluate compatibility with [ROOT](https://root.cern.ch)'s TApplication object.
|
||||
* Expand `required`/`exluded` to take strings
|
||||
* Document adding callback (maybe add C++14 only switch method?)
|
||||
* Document adding callback (maybe add C++14 only `add_switch` method?)
|
||||
* Test "adding to cmake" method
|
||||
|
||||
See the [changelog](./CHANGELOG.md) or [GitHub releases](https://github.com/henryiii/CLI11/releases) for details.
|
||||
|
@ -440,7 +440,8 @@ public:
|
||||
/// @name Extras for subclassing
|
||||
///@{
|
||||
|
||||
/// This allows subclasses to inject code before callbacks but after parse
|
||||
/// 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() {}
|
||||
|
||||
|
@ -185,9 +185,19 @@ public:
|
||||
return this;
|
||||
}
|
||||
|
||||
/// Any number supported
|
||||
template<typename... ARG>
|
||||
Option* requires(Option* opt, Option* opt1, ARG... args) {
|
||||
/// Can find a string if needed
|
||||
template<typename T=App>
|
||||
Option* requires(std::string opt_name) {
|
||||
for(const Option_p& opt : dynamic_cast<T*>(parent_)->options_)
|
||||
if(opt.get() != this && opt->check_name(opt_name))
|
||||
return requires(opt.get());
|
||||
throw IncorrectConstruction("Option " + opt_name + " is not defined");
|
||||
|
||||
}
|
||||
|
||||
/// Any number supported, any mix of string and Opt
|
||||
template<typename A, typename B, typename... ARG>
|
||||
Option* requires(A opt, B opt1, ARG... args) {
|
||||
requires(opt);
|
||||
return requires(opt1, args...);
|
||||
}
|
||||
@ -200,9 +210,18 @@ public:
|
||||
return this;
|
||||
}
|
||||
|
||||
/// Any number supported
|
||||
template<typename... ARG>
|
||||
Option* excludes(Option* opt, Option* opt1, ARG... args) {
|
||||
/// Can find a string if needed
|
||||
template<typename T=App>
|
||||
Option* excludes(std::string opt_name) {
|
||||
for(const Option_p& opt : dynamic_cast<T*>(parent_)->options_)
|
||||
if(opt.get() != this && opt->check_name(opt_name))
|
||||
return excludes(opt.get());
|
||||
throw IncorrectConstruction("Option " + opt_name + " is not defined");
|
||||
|
||||
}
|
||||
/// Any number supported, any mix of string and Opt
|
||||
template<typename A, typename B, typename... ARG>
|
||||
Option* excludes(A opt, B opt1, ARG... args) {
|
||||
excludes(opt);
|
||||
return excludes(opt1, args...);
|
||||
}
|
||||
|
@ -458,6 +458,30 @@ TEST_F(TApp, ExcludesFlags) {
|
||||
EXPECT_THROW(run(), CLI::ExcludesError);
|
||||
}
|
||||
|
||||
TEST_F(TApp, ExcludesMixedFlags) {
|
||||
CLI::Option* opt1 = app.add_flag("--opt1");
|
||||
app.add_flag("--opt2");
|
||||
CLI::Option* opt3 = app.add_flag("--opt3");
|
||||
app.add_flag("--no")->excludes(opt1, "--opt2", opt3);
|
||||
|
||||
EXPECT_NO_THROW(run());
|
||||
|
||||
app.reset();
|
||||
args = {"--no"};
|
||||
EXPECT_NO_THROW(run());
|
||||
|
||||
app.reset();
|
||||
args = {"--opt2"};
|
||||
EXPECT_NO_THROW(run());
|
||||
|
||||
app.reset();
|
||||
args = {"--no", "--opt1"};
|
||||
EXPECT_THROW(run(), CLI::ExcludesError);
|
||||
|
||||
app.reset();
|
||||
args = {"--no", "--opt2"};
|
||||
EXPECT_THROW(run(), CLI::ExcludesError);
|
||||
}
|
||||
|
||||
TEST_F(TApp, RequiresMultiFlags) {
|
||||
CLI::Option* opt1 = app.add_flag("--opt1");
|
||||
@ -492,6 +516,39 @@ TEST_F(TApp, RequiresMultiFlags) {
|
||||
EXPECT_NO_THROW(run());
|
||||
}
|
||||
|
||||
TEST_F(TApp, RequiresMixedFlags) {
|
||||
CLI::Option* opt1 = app.add_flag("--opt1");
|
||||
CLI::Option* opt2 = app.add_flag("--opt2");
|
||||
CLI::Option* opt3 = app.add_flag("--opt3");
|
||||
app.add_flag("--optall")->requires(opt1, "--opt2", "--opt3");
|
||||
|
||||
EXPECT_NO_THROW(run());
|
||||
|
||||
app.reset();
|
||||
args = {"--opt1"};
|
||||
EXPECT_NO_THROW(run());
|
||||
|
||||
app.reset();
|
||||
args = {"--opt2"};
|
||||
EXPECT_NO_THROW(run());
|
||||
|
||||
app.reset();
|
||||
args = {"--optall"};
|
||||
EXPECT_THROW(run(), CLI::RequiresError);
|
||||
|
||||
app.reset();
|
||||
args = {"--optall", "--opt1"};
|
||||
EXPECT_THROW(run(), CLI::RequiresError);
|
||||
|
||||
app.reset();
|
||||
args = {"--optall", "--opt2", "--opt1"};
|
||||
EXPECT_THROW(run(), CLI::RequiresError);
|
||||
|
||||
app.reset();
|
||||
args = {"--optall", "--opt1", "--opt2", "--opt3"};
|
||||
EXPECT_NO_THROW(run());
|
||||
}
|
||||
|
||||
TEST_F(TApp, RequiresChainedFlags) {
|
||||
CLI::Option* opt1 = app.add_flag("--opt1");
|
||||
CLI::Option* opt2 = app.add_flag("--opt2")->requires(opt1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user