Commit c63288a91cb79c19a4f28cbeb0ae4f57fa96e2ad
Committed by
Henry Schreiner
1 parent
8e650c38
Adding set_name and support for names to app
Showing
3 changed files
with
36 additions
and
12 deletions
CHANGELOG.md
| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | * Make unlimited positionals vs. unlimited options more intuitive [#102] |
| 4 | 4 | * Add missing getters `get_options` and `get_description` to App [#105] |
| 5 | +* The app name now can be set, and will override the auto name if present [#105] | |
| 5 | 6 | |
| 6 | 7 | [#102]: https://github.com/CLIUtils/CLI11/issues/102 |
| 7 | 8 | [#105]: https://github.com/CLIUtils/CLI11/issues/105 | ... | ... |
include/CLI/App.hpp
| ... | ... | @@ -64,8 +64,8 @@ class App { |
| 64 | 64 | /// @name Basics |
| 65 | 65 | ///@{ |
| 66 | 66 | |
| 67 | - /// Subcommand name or program name (from parser) | |
| 68 | - std::string name_{"program"}; | |
| 67 | + /// Subcommand name or program name (from parser if name is empty) | |
| 68 | + std::string name_; | |
| 69 | 69 | |
| 70 | 70 | /// Description of the current program/subcommand |
| 71 | 71 | std::string description_; |
| ... | ... | @@ -193,7 +193,8 @@ class App { |
| 193 | 193 | ///@{ |
| 194 | 194 | |
| 195 | 195 | /// Create a new program. Pass in the same arguments as main(), along with a help string. |
| 196 | - App(std::string description_ = "") : App(description_, nullptr) { | |
| 196 | + App(std::string description_ = "", std::string name = "") : App(description_, nullptr) { | |
| 197 | + name_ = name; | |
| 197 | 198 | set_help_flag("-h,--help", "Print this help message and exit"); |
| 198 | 199 | } |
| 199 | 200 | |
| ... | ... | @@ -211,6 +212,12 @@ class App { |
| 211 | 212 | return this; |
| 212 | 213 | } |
| 213 | 214 | |
| 215 | + /// Set a name for the app (empty will use parser to set the name) | |
| 216 | + App *set_name(std::string name = "") { | |
| 217 | + name_ = name; | |
| 218 | + return this; | |
| 219 | + } | |
| 220 | + | |
| 214 | 221 | /// Remove the error when extras are left over on the command line. |
| 215 | 222 | App *allow_extras(bool allow = true) { |
| 216 | 223 | allow_extras_ = allow; |
| ... | ... | @@ -723,7 +730,10 @@ class App { |
| 723 | 730 | /// Parses the command line - throws errors |
| 724 | 731 | /// This must be called after the options are in but before the rest of the program. |
| 725 | 732 | void parse(int argc, char **argv) { |
| 726 | - name_ = argv[0]; | |
| 733 | + // If the name is not set, read from command line | |
| 734 | + if(name_.empty()) | |
| 735 | + name_ = argv[0]; | |
| 736 | + | |
| 727 | 737 | std::vector<std::string> args; |
| 728 | 738 | for(int i = argc - 1; i > 0; i--) |
| 729 | 739 | args.emplace_back(argv[i]); |
| ... | ... | @@ -890,7 +900,7 @@ class App { |
| 890 | 900 | |
| 891 | 901 | std::stringstream out; |
| 892 | 902 | out << description_ << std::endl; |
| 893 | - out << "Usage: " << prev; | |
| 903 | + out << "Usage:" << (prev.empty() ? "" : " ") << prev; | |
| 894 | 904 | |
| 895 | 905 | // Check for options_ |
| 896 | 906 | bool npos = false; |
| ... | ... | @@ -1030,6 +1040,7 @@ class App { |
| 1030 | 1040 | |
| 1031 | 1041 | /// Get a pointer to the config option. (const) |
| 1032 | 1042 | const Option *get_config_ptr() const { return config_ptr_; } |
| 1043 | + | |
| 1033 | 1044 | /// Get the name of the current app |
| 1034 | 1045 | std::string get_name() const { return name_; } |
| 1035 | 1046 | ... | ... |
tests/HelpTest.cpp
| ... | ... | @@ -36,7 +36,7 @@ TEST(THelp, Footer) { |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | 38 | TEST(THelp, OptionalPositional) { |
| 39 | - CLI::App app{"My prog"}; | |
| 39 | + CLI::App app{"My prog", "program"}; | |
| 40 | 40 | |
| 41 | 41 | std::string x; |
| 42 | 42 | app.add_option("something", x, "My option here"); |
| ... | ... | @@ -71,7 +71,7 @@ TEST(THelp, Hidden) { |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | 73 | TEST(THelp, OptionalPositionalAndOptions) { |
| 74 | - CLI::App app{"My prog"}; | |
| 74 | + CLI::App app{"My prog", "AnotherProgram"}; | |
| 75 | 75 | app.add_flag("-q,--quick"); |
| 76 | 76 | |
| 77 | 77 | std::string x; |
| ... | ... | @@ -82,7 +82,7 @@ TEST(THelp, OptionalPositionalAndOptions) { |
| 82 | 82 | EXPECT_THAT(help, HasSubstr("My prog")); |
| 83 | 83 | EXPECT_THAT(help, HasSubstr("-h,--help")); |
| 84 | 84 | EXPECT_THAT(help, HasSubstr("Options:")); |
| 85 | - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] [something]")); | |
| 85 | + EXPECT_THAT(help, HasSubstr("Usage: AnotherProgram [OPTIONS] [something]")); | |
| 86 | 86 | } |
| 87 | 87 | |
| 88 | 88 | TEST(THelp, RequiredPositionalAndOptions) { |
| ... | ... | @@ -98,7 +98,7 @@ TEST(THelp, RequiredPositionalAndOptions) { |
| 98 | 98 | EXPECT_THAT(help, HasSubstr("-h,--help")); |
| 99 | 99 | EXPECT_THAT(help, HasSubstr("Options:")); |
| 100 | 100 | EXPECT_THAT(help, HasSubstr("Positionals:")); |
| 101 | - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] something")); | |
| 101 | + EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS] something")); | |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | TEST(THelp, MultiOpts) { |
| ... | ... | @@ -111,7 +111,7 @@ TEST(THelp, MultiOpts) { |
| 111 | 111 | |
| 112 | 112 | EXPECT_THAT(help, HasSubstr("My prog")); |
| 113 | 113 | EXPECT_THAT(help, Not(HasSubstr("Positionals:"))); |
| 114 | - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS]")); | |
| 114 | + EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS]")); | |
| 115 | 115 | EXPECT_THAT(help, HasSubstr("INT x 2")); |
| 116 | 116 | EXPECT_THAT(help, HasSubstr("INT ...")); |
| 117 | 117 | } |
| ... | ... | @@ -128,6 +128,7 @@ TEST(THelp, VectorOpts) { |
| 128 | 128 | |
| 129 | 129 | TEST(THelp, MultiPosOpts) { |
| 130 | 130 | CLI::App app{"My prog"}; |
| 131 | + app.set_name("program"); | |
| 131 | 132 | std::vector<int> x, y; |
| 132 | 133 | app.add_option("quick", x, "Disc")->expected(2); |
| 133 | 134 | app.add_option("vals", y, "Other"); |
| ... | ... | @@ -243,12 +244,12 @@ TEST(THelp, Subcom) { |
| 243 | 244 | app.add_subcommand("sub2"); |
| 244 | 245 | |
| 245 | 246 | std::string help = app.help(); |
| 246 | - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] [SUBCOMMAND]")); | |
| 247 | + EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS] [SUBCOMMAND]")); | |
| 247 | 248 | |
| 248 | 249 | app.require_subcommand(); |
| 249 | 250 | |
| 250 | 251 | help = app.help(); |
| 251 | - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] SUBCOMMAND")); | |
| 252 | + EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS] SUBCOMMAND")); | |
| 252 | 253 | |
| 253 | 254 | help = sub1->help(); |
| 254 | 255 | EXPECT_THAT(help, HasSubstr("Usage: sub1")); |
| ... | ... | @@ -263,6 +264,17 @@ TEST(THelp, Subcom) { |
| 263 | 264 | EXPECT_THAT(help, HasSubstr("Usage: ./myprogram sub2")); |
| 264 | 265 | } |
| 265 | 266 | |
| 267 | +TEST(THelp, MasterName) { | |
| 268 | + CLI::App app{"My prog", "MyRealName"}; | |
| 269 | + | |
| 270 | + char x[] = "./myprogram"; | |
| 271 | + | |
| 272 | + std::vector<char *> args = {x}; | |
| 273 | + app.parse((int)args.size(), args.data()); | |
| 274 | + | |
| 275 | + EXPECT_THAT(app.help(), HasSubstr("Usage: MyRealName")); | |
| 276 | +} | |
| 277 | + | |
| 266 | 278 | TEST(THelp, IntDefaults) { |
| 267 | 279 | CLI::App app{"My prog"}; |
| 268 | 280 | ... | ... |