mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-04-30 12:43:52 +00:00
Group merge (#1039)
This PR adds a mechanism to hide groups but have their options visible as part of the parent. This works for option group names starting with a '+' for example ``` CLI::App app; bool flag = false; std::optional<bool> optional_flag = std::nullopt; app.add_option("--tester"); auto *m1=app.add_option_group("+tester"); m1->add_option("--flag", flag, "description"); m1->add_option("--optional_flag", optional_flag, "description"); CLI11_PARSE(app,argc, argv); ``` will produce help as ```txt Options: -h,--help Print this help message and exit --tester --flag BOOLEAN description --optional_flag BOOLEAN description ``` instead of ``` Options: -h,--help Print this help message and exit --tester [Option Group: tester] Options: --flag BOOLEAN description --optional_flag BOOLEAN description ``` Fixes issue #1034 and a few other past issues or questions --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
ccd68011a4
commit
08d840bfbe
@ -1,5 +1,10 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
- add mechanism to allow option groups to be hidden and all options be
|
||||||
|
considered part of the parent for help display
|
||||||
|
|
||||||
## Version 2.4: Unicode and TOML support
|
## Version 2.4: Unicode and TOML support
|
||||||
|
|
||||||
This version adds Unicode support, support for TOML standard including multiline
|
This version adds Unicode support, support for TOML standard including multiline
|
||||||
|
12
README.md
12
README.md
@ -1205,7 +1205,17 @@ auto hidden_group=app.add_option_group("");
|
|||||||
```
|
```
|
||||||
|
|
||||||
will create a group such that no options in that group are displayed in the help
|
will create a group such that no options in that group are displayed in the help
|
||||||
string.
|
string. For the purposes of help display, if the option group name starts with a
|
||||||
|
'+' it is treated as if it were not in a group for help and get_options. For
|
||||||
|
example:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
auto added_group=app.add_option_group("+sub");
|
||||||
|
```
|
||||||
|
|
||||||
|
In this case the help output will not reference the option group and options
|
||||||
|
inside of it will be treated for most purposes as if they were part of the
|
||||||
|
parent.
|
||||||
|
|
||||||
### Configuration file
|
### Configuration file
|
||||||
|
|
||||||
|
@ -1340,6 +1340,11 @@ class Option_group : public App {
|
|||||||
: App(std::move(group_description), "", parent) {
|
: App(std::move(group_description), "", parent) {
|
||||||
group(group_name);
|
group(group_name);
|
||||||
// option groups should have automatic fallthrough
|
// option groups should have automatic fallthrough
|
||||||
|
if(group_name.empty() || group_name.front() == '+') {
|
||||||
|
// help will not be used by default in these contexts
|
||||||
|
set_help_flag("");
|
||||||
|
set_help_all_flag("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
using App::add_option;
|
using App::add_option;
|
||||||
/// Add an existing option to the Option_group
|
/// Add an existing option to the Option_group
|
||||||
|
@ -784,7 +784,14 @@ CLI11_INLINE std::vector<const Option *> App::get_options(const std::function<bo
|
|||||||
[&filter](const Option *opt) { return !filter(opt); }),
|
[&filter](const Option *opt) { return !filter(opt); }),
|
||||||
std::end(options));
|
std::end(options));
|
||||||
}
|
}
|
||||||
|
for(const auto &subcp : subcommands_) {
|
||||||
|
// also check down into nameless subcommands
|
||||||
|
const App *subc = subcp.get();
|
||||||
|
if(subc->get_name().empty() && !subc->get_group().empty() && subc->get_group().front() == '+') {
|
||||||
|
std::vector<const Option *> subcopts = subc->get_options(filter);
|
||||||
|
options.insert(options.end(), subcopts.begin(), subcopts.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,7 +805,13 @@ CLI11_INLINE std::vector<Option *> App::get_options(const std::function<bool(Opt
|
|||||||
std::remove_if(std::begin(options), std::end(options), [&filter](Option *opt) { return !filter(opt); }),
|
std::remove_if(std::begin(options), std::end(options), [&filter](Option *opt) { return !filter(opt); }),
|
||||||
std::end(options));
|
std::end(options));
|
||||||
}
|
}
|
||||||
|
for(auto &subc : subcommands_) {
|
||||||
|
// also check down into nameless subcommands
|
||||||
|
if(subc->get_name().empty() && !subc->get_group().empty() && subc->get_group().front() == '+') {
|
||||||
|
auto subcopts = subc->get_options(filter);
|
||||||
|
options.insert(options.end(), subcopts.begin(), subcopts.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,10 +180,10 @@ CLI11_INLINE std::string Formatter::make_subcommands(const App *app, AppFormatMo
|
|||||||
std::vector<std::string> subcmd_groups_seen;
|
std::vector<std::string> subcmd_groups_seen;
|
||||||
for(const App *com : subcommands) {
|
for(const App *com : subcommands) {
|
||||||
if(com->get_name().empty()) {
|
if(com->get_name().empty()) {
|
||||||
if(!com->get_group().empty()) {
|
if(com->get_group().empty() || com->get_group().front() == '+') {
|
||||||
out << make_expanded(com);
|
continue;
|
||||||
}
|
}
|
||||||
continue;
|
out << make_expanded(com);
|
||||||
}
|
}
|
||||||
std::string group_key = com->get_group();
|
std::string group_key = com->get_group();
|
||||||
if(!group_key.empty() &&
|
if(!group_key.empty() &&
|
||||||
|
@ -221,6 +221,32 @@ TEST_CASE_METHOD(TApp, "BasicOptionGroupMin", "[optiongroup]") {
|
|||||||
CHECK(std::string::npos != exactloc);
|
CHECK(std::string::npos != exactloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(TApp, "integratedOptionGroup", "[optiongroup]") {
|
||||||
|
auto *ogroup = app.add_option_group("+clusters");
|
||||||
|
int res{0};
|
||||||
|
ogroup->add_option("--test1", res);
|
||||||
|
ogroup->add_option("--test2", res);
|
||||||
|
ogroup->add_option("--test3", res);
|
||||||
|
int val2{0};
|
||||||
|
app.add_option("--option", val2);
|
||||||
|
ogroup->require_option();
|
||||||
|
|
||||||
|
args = {"--option", "9"};
|
||||||
|
CHECK_THROWS_AS(run(), CLI::RequiredError);
|
||||||
|
|
||||||
|
args = {"--test1", "5", "--test2", "4", "--test3=5"};
|
||||||
|
CHECK_NOTHROW(run());
|
||||||
|
|
||||||
|
auto options = app.get_options();
|
||||||
|
CHECK(options.size() == 5);
|
||||||
|
const CLI::App *capp = &app;
|
||||||
|
auto coptions = capp->get_options();
|
||||||
|
CHECK(coptions.size() == 5);
|
||||||
|
std::string help = app.help();
|
||||||
|
auto exactloc = help.find("clusters");
|
||||||
|
CHECK(std::string::npos == exactloc);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(TApp, "BasicOptionGroupExact2", "[optiongroup]") {
|
TEST_CASE_METHOD(TApp, "BasicOptionGroupExact2", "[optiongroup]") {
|
||||||
auto *ogroup = app.add_option_group("clusters");
|
auto *ogroup = app.add_option_group("clusters");
|
||||||
int res{0};
|
int res{0};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user