From fdbd5f1d79c7c20d19753559f413c705907407f6 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Sat, 23 Sep 2023 12:01:44 -0700 Subject: [PATCH] style: pre-commit.ci fixes add automatic validation to environmental variables --- README.md | 3 ++- book/chapters/options.md | 2 +- include/CLI/impl/App_inl.hpp | 6 +++++- tests/HelpTest.cpp | 18 ++++++++++++++++++ tests/SubcommandTest.cpp | 2 +- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5550f92b4..3127be8a3 100644 --- a/README.md +++ b/README.md @@ -417,7 +417,8 @@ Before parsing, you can set the following options: option. Options can be removed from the excludes list with `->remove_excludes(opt)` - `->envname(name)`: Gets the value from the environment if present and not - passed on the command line. + passed on the command line. 🚧 The value must also pass any validators to be + used. - `->group(name)`: The help group to put the option in. No effect for positional options. Defaults to `"Options"`. Options given an empty string will not show up in the help print (hidden). diff --git a/book/chapters/options.md b/book/chapters/options.md index f3cf25326..bc32cea7b 100644 --- a/book/chapters/options.md +++ b/book/chapters/options.md @@ -214,7 +214,7 @@ that to add option modifiers. A full listing of the option modifiers: | `->type_size(Nmin,Nmax)` | specify that each block of values would consist of between Nmin and Nmax elements | | `->needs(opt)` | This option requires another option to also be present, opt is an `Option` pointer or a string with the name of the option. Can be removed with `->remove_needs(opt)` | | `->excludes(opt)` | This option cannot be given with `opt` present, opt is an `Option` pointer or a string with the name of the option. Can be removed with `->remove_excludes(opt)` | -| `->envname(name)` | Gets the value from the environment if present and not passed on the command line. | +| `->envname(name)` | Gets the value from the environment if present and not passed on the command line and passes any validators. | | `->group(name)` | The help group to put the option in. No effect for positional options. Defaults to `"Options"`. Options given an empty string for the group name will not show up in the help print. | | `->description(string)` | Set/change the description | | `->ignore_case()` | Ignore the case on the command line (also works on subcommands, does not affect arguments). | diff --git a/include/CLI/impl/App_inl.hpp b/include/CLI/impl/App_inl.hpp index c5f79ca58..0fed48b0f 100644 --- a/include/CLI/impl/App_inl.hpp +++ b/include/CLI/impl/App_inl.hpp @@ -1080,7 +1080,11 @@ CLI11_INLINE void App::_process_env() { if(opt->count() == 0 && !opt->envname_.empty()) { std::string ename_string = detail::get_environment_value(opt->envname_); if(!ename_string.empty()) { - opt->add_result(ename_string); + std::string result = ename_string; + result = opt->_validate(result, 0); + if(result.empty()) { + opt->add_result(ename_string); + } } } } diff --git a/tests/HelpTest.cpp b/tests/HelpTest.cpp index c4403f754..4af0a3b8e 100644 --- a/tests/HelpTest.cpp +++ b/tests/HelpTest.cpp @@ -10,6 +10,8 @@ #include "CLI/CLI.hpp" #endif +#include "app_helper.hpp" + #include "catch.hpp" #include @@ -718,6 +720,22 @@ TEST_CASE("THelp: CustomHelp", "[help]") { } } +TEST_CASE("THelp: HelpSubcommandPriority", "[help]") { + CLI::App app{"My prog"}; + + app.set_help_flag("-h", "display help and exit"); + + auto *sub1 = app.add_subcommand("sub1"); + std::string someFile = ""; + + put_env("SOME_FILE", "NOT_A_FILE"); + sub1->add_option("-f,--file", someFile)->envname("SOME_FILE")->required()->expected(1)->check(CLI::ExistingFile); + + std::string input{"sub1 -h"}; + CHECK_THROWS_AS(app.parse(input), CLI::CallForHelp); + unset_env("SOME_FILE"); +} + TEST_CASE("THelp: NextLineShouldBeAlignmentInMultilineDescription", "[help]") { CLI::App app; int i{0}; diff --git a/tests/SubcommandTest.cpp b/tests/SubcommandTest.cpp index bdcd4bf8d..7c3f3e21a 100644 --- a/tests/SubcommandTest.cpp +++ b/tests/SubcommandTest.cpp @@ -2138,6 +2138,6 @@ TEST_CASE_METHOD(TApp, "subcommandEnvironmentName", "[subcom]") { CHECK_NOTHROW(run()); args = {"sub1", "-v", "111"}; - CHECK_THROWS_AS(run(), CLI::ValidationError); + CHECK_THROWS_AS(run(), CLI::RequiredError); unset_env("SOME_FILE"); }