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,6 +2,7 @@ | ||
| 2 | 2 | ||
| 3 | * Make unlimited positionals vs. unlimited options more intuitive [#102] | 3 | * Make unlimited positionals vs. unlimited options more intuitive [#102] |
| 4 | * Add missing getters `get_options` and `get_description` to App [#105] | 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 | [#102]: https://github.com/CLIUtils/CLI11/issues/102 | 7 | [#102]: https://github.com/CLIUtils/CLI11/issues/102 |
| 7 | [#105]: https://github.com/CLIUtils/CLI11/issues/105 | 8 | [#105]: https://github.com/CLIUtils/CLI11/issues/105 |
include/CLI/App.hpp
| @@ -64,8 +64,8 @@ class App { | @@ -64,8 +64,8 @@ class App { | ||
| 64 | /// @name Basics | 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 | /// Description of the current program/subcommand | 70 | /// Description of the current program/subcommand |
| 71 | std::string description_; | 71 | std::string description_; |
| @@ -193,7 +193,8 @@ class App { | @@ -193,7 +193,8 @@ class App { | ||
| 193 | ///@{ | 193 | ///@{ |
| 194 | 194 | ||
| 195 | /// Create a new program. Pass in the same arguments as main(), along with a help string. | 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 | set_help_flag("-h,--help", "Print this help message and exit"); | 198 | set_help_flag("-h,--help", "Print this help message and exit"); |
| 198 | } | 199 | } |
| 199 | 200 | ||
| @@ -211,6 +212,12 @@ class App { | @@ -211,6 +212,12 @@ class App { | ||
| 211 | return this; | 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 | /// Remove the error when extras are left over on the command line. | 221 | /// Remove the error when extras are left over on the command line. |
| 215 | App *allow_extras(bool allow = true) { | 222 | App *allow_extras(bool allow = true) { |
| 216 | allow_extras_ = allow; | 223 | allow_extras_ = allow; |
| @@ -723,7 +730,10 @@ class App { | @@ -723,7 +730,10 @@ class App { | ||
| 723 | /// Parses the command line - throws errors | 730 | /// Parses the command line - throws errors |
| 724 | /// This must be called after the options are in but before the rest of the program. | 731 | /// This must be called after the options are in but before the rest of the program. |
| 725 | void parse(int argc, char **argv) { | 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 | std::vector<std::string> args; | 737 | std::vector<std::string> args; |
| 728 | for(int i = argc - 1; i > 0; i--) | 738 | for(int i = argc - 1; i > 0; i--) |
| 729 | args.emplace_back(argv[i]); | 739 | args.emplace_back(argv[i]); |
| @@ -890,7 +900,7 @@ class App { | @@ -890,7 +900,7 @@ class App { | ||
| 890 | 900 | ||
| 891 | std::stringstream out; | 901 | std::stringstream out; |
| 892 | out << description_ << std::endl; | 902 | out << description_ << std::endl; |
| 893 | - out << "Usage: " << prev; | 903 | + out << "Usage:" << (prev.empty() ? "" : " ") << prev; |
| 894 | 904 | ||
| 895 | // Check for options_ | 905 | // Check for options_ |
| 896 | bool npos = false; | 906 | bool npos = false; |
| @@ -1030,6 +1040,7 @@ class App { | @@ -1030,6 +1040,7 @@ class App { | ||
| 1030 | 1040 | ||
| 1031 | /// Get a pointer to the config option. (const) | 1041 | /// Get a pointer to the config option. (const) |
| 1032 | const Option *get_config_ptr() const { return config_ptr_; } | 1042 | const Option *get_config_ptr() const { return config_ptr_; } |
| 1043 | + | ||
| 1033 | /// Get the name of the current app | 1044 | /// Get the name of the current app |
| 1034 | std::string get_name() const { return name_; } | 1045 | std::string get_name() const { return name_; } |
| 1035 | 1046 |
tests/HelpTest.cpp
| @@ -36,7 +36,7 @@ TEST(THelp, Footer) { | @@ -36,7 +36,7 @@ TEST(THelp, Footer) { | ||
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | TEST(THelp, OptionalPositional) { | 38 | TEST(THelp, OptionalPositional) { |
| 39 | - CLI::App app{"My prog"}; | 39 | + CLI::App app{"My prog", "program"}; |
| 40 | 40 | ||
| 41 | std::string x; | 41 | std::string x; |
| 42 | app.add_option("something", x, "My option here"); | 42 | app.add_option("something", x, "My option here"); |
| @@ -71,7 +71,7 @@ TEST(THelp, Hidden) { | @@ -71,7 +71,7 @@ TEST(THelp, Hidden) { | ||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | TEST(THelp, OptionalPositionalAndOptions) { | 73 | TEST(THelp, OptionalPositionalAndOptions) { |
| 74 | - CLI::App app{"My prog"}; | 74 | + CLI::App app{"My prog", "AnotherProgram"}; |
| 75 | app.add_flag("-q,--quick"); | 75 | app.add_flag("-q,--quick"); |
| 76 | 76 | ||
| 77 | std::string x; | 77 | std::string x; |
| @@ -82,7 +82,7 @@ TEST(THelp, OptionalPositionalAndOptions) { | @@ -82,7 +82,7 @@ TEST(THelp, OptionalPositionalAndOptions) { | ||
| 82 | EXPECT_THAT(help, HasSubstr("My prog")); | 82 | EXPECT_THAT(help, HasSubstr("My prog")); |
| 83 | EXPECT_THAT(help, HasSubstr("-h,--help")); | 83 | EXPECT_THAT(help, HasSubstr("-h,--help")); |
| 84 | EXPECT_THAT(help, HasSubstr("Options:")); | 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 | TEST(THelp, RequiredPositionalAndOptions) { | 88 | TEST(THelp, RequiredPositionalAndOptions) { |
| @@ -98,7 +98,7 @@ TEST(THelp, RequiredPositionalAndOptions) { | @@ -98,7 +98,7 @@ TEST(THelp, RequiredPositionalAndOptions) { | ||
| 98 | EXPECT_THAT(help, HasSubstr("-h,--help")); | 98 | EXPECT_THAT(help, HasSubstr("-h,--help")); |
| 99 | EXPECT_THAT(help, HasSubstr("Options:")); | 99 | EXPECT_THAT(help, HasSubstr("Options:")); |
| 100 | EXPECT_THAT(help, HasSubstr("Positionals:")); | 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 | TEST(THelp, MultiOpts) { | 104 | TEST(THelp, MultiOpts) { |
| @@ -111,7 +111,7 @@ TEST(THelp, MultiOpts) { | @@ -111,7 +111,7 @@ TEST(THelp, MultiOpts) { | ||
| 111 | 111 | ||
| 112 | EXPECT_THAT(help, HasSubstr("My prog")); | 112 | EXPECT_THAT(help, HasSubstr("My prog")); |
| 113 | EXPECT_THAT(help, Not(HasSubstr("Positionals:"))); | 113 | EXPECT_THAT(help, Not(HasSubstr("Positionals:"))); |
| 114 | - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS]")); | 114 | + EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS]")); |
| 115 | EXPECT_THAT(help, HasSubstr("INT x 2")); | 115 | EXPECT_THAT(help, HasSubstr("INT x 2")); |
| 116 | EXPECT_THAT(help, HasSubstr("INT ...")); | 116 | EXPECT_THAT(help, HasSubstr("INT ...")); |
| 117 | } | 117 | } |
| @@ -128,6 +128,7 @@ TEST(THelp, VectorOpts) { | @@ -128,6 +128,7 @@ TEST(THelp, VectorOpts) { | ||
| 128 | 128 | ||
| 129 | TEST(THelp, MultiPosOpts) { | 129 | TEST(THelp, MultiPosOpts) { |
| 130 | CLI::App app{"My prog"}; | 130 | CLI::App app{"My prog"}; |
| 131 | + app.set_name("program"); | ||
| 131 | std::vector<int> x, y; | 132 | std::vector<int> x, y; |
| 132 | app.add_option("quick", x, "Disc")->expected(2); | 133 | app.add_option("quick", x, "Disc")->expected(2); |
| 133 | app.add_option("vals", y, "Other"); | 134 | app.add_option("vals", y, "Other"); |
| @@ -243,12 +244,12 @@ TEST(THelp, Subcom) { | @@ -243,12 +244,12 @@ TEST(THelp, Subcom) { | ||
| 243 | app.add_subcommand("sub2"); | 244 | app.add_subcommand("sub2"); |
| 244 | 245 | ||
| 245 | std::string help = app.help(); | 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 | app.require_subcommand(); | 249 | app.require_subcommand(); |
| 249 | 250 | ||
| 250 | help = app.help(); | 251 | help = app.help(); |
| 251 | - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] SUBCOMMAND")); | 252 | + EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS] SUBCOMMAND")); |
| 252 | 253 | ||
| 253 | help = sub1->help(); | 254 | help = sub1->help(); |
| 254 | EXPECT_THAT(help, HasSubstr("Usage: sub1")); | 255 | EXPECT_THAT(help, HasSubstr("Usage: sub1")); |
| @@ -263,6 +264,17 @@ TEST(THelp, Subcom) { | @@ -263,6 +264,17 @@ TEST(THelp, Subcom) { | ||
| 263 | EXPECT_THAT(help, HasSubstr("Usage: ./myprogram sub2")); | 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 | TEST(THelp, IntDefaults) { | 278 | TEST(THelp, IntDefaults) { |
| 267 | CLI::App app{"My prog"}; | 279 | CLI::App app{"My prog"}; |
| 268 | 280 |