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
|
## Version 0.6
|
||||||
|
|
||||||
|
* Added string versions of `->requires()` and `->excludes()` for consistency.
|
||||||
* Renamed protected members for internal consistency, grouped docs.
|
* Renamed protected members for internal consistency, grouped docs.
|
||||||
* Added the ability to add a number to `.require_subcommand()`.
|
* 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
|
* Collect user feedback
|
||||||
* Ini configuration support is basic (long options only, no vector support), is more needed?
|
* 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.
|
* 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 `add_switch` method?)
|
||||||
* Document adding callback (maybe add C++14 only switch method?)
|
|
||||||
* Test "adding to cmake" method
|
* Test "adding to cmake" method
|
||||||
|
|
||||||
See the [changelog](./CHANGELOG.md) or [GitHub releases](https://github.com/henryiii/CLI11/releases) for details.
|
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
|
/// @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.
|
/// This does not run if any errors or help is thrown.
|
||||||
virtual void pre_callback() {}
|
virtual void pre_callback() {}
|
||||||
|
|
||||||
|
@ -185,9 +185,19 @@ public:
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Any number supported
|
/// Can find a string if needed
|
||||||
template<typename... ARG>
|
template<typename T=App>
|
||||||
Option* requires(Option* opt, Option* opt1, ARG... args) {
|
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);
|
requires(opt);
|
||||||
return requires(opt1, args...);
|
return requires(opt1, args...);
|
||||||
}
|
}
|
||||||
@ -200,9 +210,18 @@ public:
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Any number supported
|
/// Can find a string if needed
|
||||||
template<typename... ARG>
|
template<typename T=App>
|
||||||
Option* excludes(Option* opt, Option* opt1, ARG... args) {
|
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);
|
excludes(opt);
|
||||||
return excludes(opt1, args...);
|
return excludes(opt1, args...);
|
||||||
}
|
}
|
||||||
|
@ -458,6 +458,30 @@ TEST_F(TApp, ExcludesFlags) {
|
|||||||
EXPECT_THROW(run(), CLI::ExcludesError);
|
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) {
|
TEST_F(TApp, RequiresMultiFlags) {
|
||||||
CLI::Option* opt1 = app.add_flag("--opt1");
|
CLI::Option* opt1 = app.add_flag("--opt1");
|
||||||
@ -492,6 +516,39 @@ TEST_F(TApp, RequiresMultiFlags) {
|
|||||||
EXPECT_NO_THROW(run());
|
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) {
|
TEST_F(TApp, RequiresChainedFlags) {
|
||||||
CLI::Option* opt1 = app.add_flag("--opt1");
|
CLI::Option* opt1 = app.add_flag("--opt1");
|
||||||
CLI::Option* opt2 = app.add_flag("--opt2")->requires(opt1);
|
CLI::Option* opt2 = app.add_flag("--opt2")->requires(opt1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user