Commit 15bb724e06af9f4699a657643720d9ed80bb6972
Committed by
GitHub
1 parent
ee2b7250
fix: make the IncorrectConstruction errors on bad subcommand name more comprehensible. (#602)
Showing
2 changed files
with
37 additions
and
2 deletions
include/CLI/App.hpp
| ... | ... | @@ -368,7 +368,20 @@ class App { |
| 368 | 368 | /// Set an alias for the app |
| 369 | 369 | App *alias(std::string app_name) { |
| 370 | 370 | if(!detail::valid_name_string(app_name)) { |
| 371 | - throw(IncorrectConstruction("alias is not a valid name string")); | |
| 371 | + if(app_name.empty()) { | |
| 372 | + throw IncorrectConstruction("Empty aliases are not allowed"); | |
| 373 | + } | |
| 374 | + if(!detail::valid_first_char(app_name[0])) { | |
| 375 | + throw IncorrectConstruction( | |
| 376 | + "Alias starts with invalid character, allowed characters are [a-zA-z0-9]+'_','?','@' "); | |
| 377 | + } | |
| 378 | + for(auto c : app_name) { | |
| 379 | + if(!detail::valid_later_char(c)) { | |
| 380 | + throw IncorrectConstruction(std::string("Alias contains invalid character ('") + c + | |
| 381 | + "'), allowed characters are " | |
| 382 | + "[a-zA-z0-9]+'_','?','@','.','-' "); | |
| 383 | + } | |
| 384 | + } | |
| 372 | 385 | } |
| 373 | 386 | |
| 374 | 387 | if(parent_ != nullptr) { |
| ... | ... | @@ -963,7 +976,17 @@ class App { |
| 963 | 976 | /// Add a subcommand. Inherits INHERITABLE and OptionDefaults, and help flag |
| 964 | 977 | App *add_subcommand(std::string subcommand_name = "", std::string subcommand_description = "") { |
| 965 | 978 | if(!subcommand_name.empty() && !detail::valid_name_string(subcommand_name)) { |
| 966 | - throw IncorrectConstruction("subcommand name is not valid"); | |
| 979 | + if(!detail::valid_first_char(subcommand_name[0])) { | |
| 980 | + throw IncorrectConstruction( | |
| 981 | + "Subcommand name starts with invalid character, allowed characters are [a-zA-z0-9]+'_','?','@' "); | |
| 982 | + } | |
| 983 | + for(auto c : subcommand_name) { | |
| 984 | + if(!detail::valid_later_char(c)) { | |
| 985 | + throw IncorrectConstruction(std::string("Subcommand name contains invalid character ('") + c + | |
| 986 | + "'), allowed characters are " | |
| 987 | + "[a-zA-z0-9]+'_','?','@','.','-' "); | |
| 988 | + } | |
| 989 | + } | |
| 967 | 990 | } |
| 968 | 991 | CLI::App_p subcom = std::shared_ptr<App>(new App(std::move(subcommand_description), subcommand_name, this)); |
| 969 | 992 | return add_subcommand(std::move(subcom)); | ... | ... |
tests/SubcommandTest.cpp
| ... | ... | @@ -811,6 +811,18 @@ TEST_CASE_METHOD(TApp, "RequiredPosInSubcommand", "[subcom]") { |
| 811 | 811 | CHECK_THROWS_AS(run(), CLI::RequiredError); |
| 812 | 812 | } |
| 813 | 813 | |
| 814 | +TEST_CASE_METHOD(TApp, "invalidSubcommandName", "[subcom]") { | |
| 815 | + | |
| 816 | + bool gotError{false}; | |
| 817 | + try { | |
| 818 | + app.add_subcommand("foo/foo", "Foo a bar"); | |
| 819 | + } catch(const CLI::IncorrectConstruction &e) { | |
| 820 | + gotError = true; | |
| 821 | + CHECK_THAT(e.what(), Contains("/")); | |
| 822 | + } | |
| 823 | + CHECK(gotError); | |
| 824 | +} | |
| 825 | + | |
| 814 | 826 | struct SubcommandProgram : public TApp { |
| 815 | 827 | |
| 816 | 828 | CLI::App *start{nullptr}; | ... | ... |