From c63288a91cb79c19a4f28cbeb0ae4f57fa96e2ad Mon Sep 17 00:00:00 2001 From: Henry Fredrick Schreiner Date: Wed, 11 Apr 2018 13:00:14 +0200 Subject: [PATCH] Adding set_name and support for names to app --- CHANGELOG.md | 1 + include/CLI/App.hpp | 21 ++++++++++++++++----- tests/HelpTest.cpp | 26 +++++++++++++++++++------- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6df6c71e..9b08573f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * Make unlimited positionals vs. unlimited options more intuitive [#102] * Add missing getters `get_options` and `get_description` to App [#105] +* The app name now can be set, and will override the auto name if present [#105] [#102]: https://github.com/CLIUtils/CLI11/issues/102 [#105]: https://github.com/CLIUtils/CLI11/issues/105 diff --git a/include/CLI/App.hpp b/include/CLI/App.hpp index 2d2c8f42..4319c25c 100644 --- a/include/CLI/App.hpp +++ b/include/CLI/App.hpp @@ -64,8 +64,8 @@ class App { /// @name Basics ///@{ - /// Subcommand name or program name (from parser) - std::string name_{"program"}; + /// Subcommand name or program name (from parser if name is empty) + std::string name_; /// Description of the current program/subcommand std::string description_; @@ -193,7 +193,8 @@ class App { ///@{ /// Create a new program. Pass in the same arguments as main(), along with a help string. - App(std::string description_ = "") : App(description_, nullptr) { + App(std::string description_ = "", std::string name = "") : App(description_, nullptr) { + name_ = name; set_help_flag("-h,--help", "Print this help message and exit"); } @@ -211,6 +212,12 @@ class App { return this; } + /// Set a name for the app (empty will use parser to set the name) + App *set_name(std::string name = "") { + name_ = name; + return this; + } + /// Remove the error when extras are left over on the command line. App *allow_extras(bool allow = true) { allow_extras_ = allow; @@ -723,7 +730,10 @@ class App { /// Parses the command line - throws errors /// This must be called after the options are in but before the rest of the program. void parse(int argc, char **argv) { - name_ = argv[0]; + // If the name is not set, read from command line + if(name_.empty()) + name_ = argv[0]; + std::vector args; for(int i = argc - 1; i > 0; i--) args.emplace_back(argv[i]); @@ -890,7 +900,7 @@ class App { std::stringstream out; out << description_ << std::endl; - out << "Usage: " << prev; + out << "Usage:" << (prev.empty() ? "" : " ") << prev; // Check for options_ bool npos = false; @@ -1030,6 +1040,7 @@ class App { /// Get a pointer to the config option. (const) const Option *get_config_ptr() const { return config_ptr_; } + /// Get the name of the current app std::string get_name() const { return name_; } diff --git a/tests/HelpTest.cpp b/tests/HelpTest.cpp index 4402a202..5b6c9a4a 100644 --- a/tests/HelpTest.cpp +++ b/tests/HelpTest.cpp @@ -36,7 +36,7 @@ TEST(THelp, Footer) { } TEST(THelp, OptionalPositional) { - CLI::App app{"My prog"}; + CLI::App app{"My prog", "program"}; std::string x; app.add_option("something", x, "My option here"); @@ -71,7 +71,7 @@ TEST(THelp, Hidden) { } TEST(THelp, OptionalPositionalAndOptions) { - CLI::App app{"My prog"}; + CLI::App app{"My prog", "AnotherProgram"}; app.add_flag("-q,--quick"); std::string x; @@ -82,7 +82,7 @@ TEST(THelp, OptionalPositionalAndOptions) { EXPECT_THAT(help, HasSubstr("My prog")); EXPECT_THAT(help, HasSubstr("-h,--help")); EXPECT_THAT(help, HasSubstr("Options:")); - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] [something]")); + EXPECT_THAT(help, HasSubstr("Usage: AnotherProgram [OPTIONS] [something]")); } TEST(THelp, RequiredPositionalAndOptions) { @@ -98,7 +98,7 @@ TEST(THelp, RequiredPositionalAndOptions) { EXPECT_THAT(help, HasSubstr("-h,--help")); EXPECT_THAT(help, HasSubstr("Options:")); EXPECT_THAT(help, HasSubstr("Positionals:")); - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] something")); + EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS] something")); } TEST(THelp, MultiOpts) { @@ -111,7 +111,7 @@ TEST(THelp, MultiOpts) { EXPECT_THAT(help, HasSubstr("My prog")); EXPECT_THAT(help, Not(HasSubstr("Positionals:"))); - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS]")); + EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS]")); EXPECT_THAT(help, HasSubstr("INT x 2")); EXPECT_THAT(help, HasSubstr("INT ...")); } @@ -128,6 +128,7 @@ TEST(THelp, VectorOpts) { TEST(THelp, MultiPosOpts) { CLI::App app{"My prog"}; + app.set_name("program"); std::vector x, y; app.add_option("quick", x, "Disc")->expected(2); app.add_option("vals", y, "Other"); @@ -243,12 +244,12 @@ TEST(THelp, Subcom) { app.add_subcommand("sub2"); std::string help = app.help(); - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] [SUBCOMMAND]")); + EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS] [SUBCOMMAND]")); app.require_subcommand(); help = app.help(); - EXPECT_THAT(help, HasSubstr("Usage: program [OPTIONS] SUBCOMMAND")); + EXPECT_THAT(help, HasSubstr("Usage: [OPTIONS] SUBCOMMAND")); help = sub1->help(); EXPECT_THAT(help, HasSubstr("Usage: sub1")); @@ -263,6 +264,17 @@ TEST(THelp, Subcom) { EXPECT_THAT(help, HasSubstr("Usage: ./myprogram sub2")); } +TEST(THelp, MasterName) { + CLI::App app{"My prog", "MyRealName"}; + + char x[] = "./myprogram"; + + std::vector args = {x}; + app.parse((int)args.size(), args.data()); + + EXPECT_THAT(app.help(), HasSubstr("Usage: MyRealName")); +} + TEST(THelp, IntDefaults) { CLI::App app{"My prog"};