Commit b59a16ccf23ebbbdfe752e9ba75e3973049da855
1 parent
e63898df
Adding hidden options
Showing
4 changed files
with
32 additions
and
2 deletions
CHANGELOG.md
| 1 | ## Version 0.5 (in progress) | 1 | ## Version 0.5 (in progress) |
| 2 | 2 | ||
| 3 | +* Allow `Hidden` options. | ||
| 3 | * Throw `OptionAlreadyAdded` errors for matching subcommands or options, with ignore-case included, tests | 4 | * Throw `OptionAlreadyAdded` errors for matching subcommands or options, with ignore-case included, tests |
| 4 | * `->ignore_case()` added to subcommands, options, and `add_set_ignore_case`. Subcommands inherit setting from parent App on creation. | 5 | * `->ignore_case()` added to subcommands, options, and `add_set_ignore_case`. Subcommands inherit setting from parent App on creation. |
| 5 | * Subcommands now can be "chained", that is, left over arguments can now include subcommands that then get parsed. Subcommands are now a list (`get_subcommands`). Added `got_subcommand(App_or_name)` to check for subcommands. | 6 | * Subcommands now can be "chained", that is, left over arguments can now include subcommands that then get parsed. Subcommands are now a list (`get_subcommands`). Added `got_subcommand(App_or_name)` to check for subcommands. |
README.md
| @@ -128,7 +128,7 @@ The add commands return a pointer to an internally stored `Option`. If you set t | @@ -128,7 +128,7 @@ The add commands return a pointer to an internally stored `Option`. If you set t | ||
| 128 | * `->requires(opt)`: This option requires another option to also be present, opt is an `Option` pointer. | 128 | * `->requires(opt)`: This option requires another option to also be present, opt is an `Option` pointer. |
| 129 | * `->excludes(opt)`: This option cannot be given with `opt` present, opt is an `Option` pointer. | 129 | * `->excludes(opt)`: This option cannot be given with `opt` present, opt is an `Option` pointer. |
| 130 | * `->envname(name)`: Gets the value from the environment if present and not passed on the command line. | 130 | * `->envname(name)`: Gets the value from the environment if present and not passed on the command line. |
| 131 | -* `->group(name)`: The help group to put the option in. No effect for positional options. Defaults to `"Options"`. | 131 | +* `->group(name)`: The help group to put the option in. No effect for positional options. Defaults to `"Options"`. `"Hidden"` will not show up in the help print. |
| 132 | * `->ignore_case()`: Ignore the case on the command line (also works on subcommands, does not affect arguments). | 132 | * `->ignore_case()`: Ignore the case on the command line (also works on subcommands, does not affect arguments). |
| 133 | * `->check(CLI::ExistingFile)`: Requires that the file exists if given. | 133 | * `->check(CLI::ExistingFile)`: Requires that the file exists if given. |
| 134 | * `->check(CLI::ExistingDirectory)`: Requires that the directory exists. | 134 | * `->check(CLI::ExistingDirectory)`: Requires that the directory exists. |
include/CLI/App.hpp
| @@ -467,6 +467,9 @@ public: | @@ -467,6 +467,9 @@ public: | ||
| 467 | bool pos=false; | 467 | bool pos=false; |
| 468 | for(const Option_p &opt : options) | 468 | for(const Option_p &opt : options) |
| 469 | if(opt->get_positional()) { | 469 | if(opt->get_positional()) { |
| 470 | + // A hidden positional should still show up in the usage statement | ||
| 471 | + //if(detail::to_lower(opt->get_group()) == "hidden") | ||
| 472 | + // continue; | ||
| 470 | out << " " << opt->help_positional(); | 473 | out << " " << opt->help_positional(); |
| 471 | if(opt->has_description()) | 474 | if(opt->has_description()) |
| 472 | pos=true; | 475 | pos=true; |
| @@ -484,9 +487,12 @@ public: | @@ -484,9 +487,12 @@ public: | ||
| 484 | // Positional descriptions | 487 | // Positional descriptions |
| 485 | if(pos) { | 488 | if(pos) { |
| 486 | out << "Positionals:" << std::endl; | 489 | out << "Positionals:" << std::endl; |
| 487 | - for(const Option_p &opt : options) | 490 | + for(const Option_p &opt : options) { |
| 491 | + if(detail::to_lower(opt->get_group()) == "hidden") | ||
| 492 | + continue; | ||
| 488 | if(opt->get_positional() && opt->has_description()) | 493 | if(opt->get_positional() && opt->has_description()) |
| 489 | detail::format_help(out, opt->help_pname(), opt->get_description(), wid); | 494 | detail::format_help(out, opt->help_pname(), opt->get_description(), wid); |
| 495 | + } | ||
| 490 | out << std::endl; | 496 | out << std::endl; |
| 491 | 497 | ||
| 492 | } | 498 | } |
| @@ -495,6 +501,8 @@ public: | @@ -495,6 +501,8 @@ public: | ||
| 495 | // Options | 501 | // Options |
| 496 | if(npos) { | 502 | if(npos) { |
| 497 | for (const std::string& group : groups) { | 503 | for (const std::string& group : groups) { |
| 504 | + if(detail::to_lower(group) == "hidden") | ||
| 505 | + continue; | ||
| 498 | out << group << ":" << std::endl; | 506 | out << group << ":" << std::endl; |
| 499 | for(const Option_p &opt : options) { | 507 | for(const Option_p &opt : options) { |
| 500 | if(opt->nonpositional() && opt->get_group() == group) | 508 | if(opt->nonpositional() && opt->get_group() == group) |
tests/HelpTest.cpp
| @@ -9,6 +9,7 @@ | @@ -9,6 +9,7 @@ | ||
| 9 | #include <fstream> | 9 | #include <fstream> |
| 10 | 10 | ||
| 11 | using ::testing::HasSubstr; | 11 | using ::testing::HasSubstr; |
| 12 | +using ::testing::Not; | ||
| 12 | 13 | ||
| 13 | TEST(THelp, Basic) { | 14 | TEST(THelp, Basic) { |
| 14 | CLI::App app{"My prog"}; | 15 | CLI::App app{"My prog"}; |
| @@ -37,8 +38,28 @@ TEST(THelp, OptionalPositional) { | @@ -37,8 +38,28 @@ TEST(THelp, OptionalPositional) { | ||
| 37 | EXPECT_THAT(help, HasSubstr("something TEXT")); | 38 | EXPECT_THAT(help, HasSubstr("something TEXT")); |
| 38 | EXPECT_THAT(help, HasSubstr("My option here")); | 39 | EXPECT_THAT(help, HasSubstr("My option here")); |
| 39 | EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] [something]")); | 40 | EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] [something]")); |
| 41 | +} | ||
| 42 | + | ||
| 43 | +TEST(THelp, Hidden) { | ||
| 44 | + CLI::App app{"My prog"}; | ||
| 45 | + | ||
| 46 | + std::string x; | ||
| 47 | + app.add_option("something", x, "My option here") | ||
| 48 | + ->group("Hidden"); | ||
| 49 | + std::string y; | ||
| 50 | + app.add_option("--another", y) | ||
| 51 | + ->group("Hidden"); | ||
| 40 | 52 | ||
| 53 | + std::string help = app.help(); | ||
| 54 | + | ||
| 55 | + EXPECT_THAT(help, HasSubstr("My prog")); | ||
| 56 | + EXPECT_THAT(help, HasSubstr("-h,--help")); | ||
| 57 | + EXPECT_THAT(help, HasSubstr("Options:")); | ||
| 58 | + EXPECT_THAT(help, HasSubstr("[something]")); | ||
| 59 | + EXPECT_THAT(help, Not(HasSubstr("something "))); | ||
| 60 | + EXPECT_THAT(help, Not(HasSubstr("another"))); | ||
| 41 | } | 61 | } |
| 62 | + | ||
| 42 | TEST(THelp, OptionalPositionalAndOptions) { | 63 | TEST(THelp, OptionalPositionalAndOptions) { |
| 43 | CLI::App app{"My prog"}; | 64 | CLI::App app{"My prog"}; |
| 44 | app.add_flag("-q,--quick"); | 65 | app.add_flag("-q,--quick"); |