Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
## In progress

* 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


## Version 1.5: Optionals
Expand Down
33 changes: 28 additions & 5 deletions include/CLI/App.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
Expand Down Expand Up @@ -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");
}

Expand All @@ -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;
Expand Down Expand Up @@ -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<std::string> args;
for(int i = argc - 1; i > 0; i--)
args.emplace_back(argv[i]);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -977,6 +987,18 @@ class App {
/// @name Getters
///@{

/// Get the app or subcommand description
std::string get_description() const { return description_; }

/// Get the list of options (user facing function, so returns raw pointers)
std::vector<Option *> get_options() const {
std::vector<Option *> options(options_.size());
std::transform(std::begin(options_), std::end(options_), std::begin(options), [](const Option_p &val) {
return val.get();
});
return options;
}

/// Check the status of ignore_case
bool get_ignore_case() const { return ignore_case_; }

Expand Down Expand Up @@ -1018,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_; }

Expand Down
12 changes: 12 additions & 0 deletions tests/CreationTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,3 +404,15 @@ TEST_F(TApp, SubcommandMinMax) {
EXPECT_EQ(app.get_require_subcommand_min(), (size_t)3);
EXPECT_EQ(app.get_require_subcommand_max(), (size_t)7);
}

TEST_F(TApp, GetOptionList) {
int two;
auto flag = app.add_flag("--one");
auto opt = app.add_option("--two", two);

auto opt_list = app.get_options();

ASSERT_EQ(opt_list.size(), static_cast<size_t>(3));
EXPECT_EQ(opt_list.at(1), flag);
EXPECT_EQ(opt_list.at(2), opt);
}
32 changes: 25 additions & 7 deletions tests/HelpTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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 ..."));
}
Expand All @@ -128,6 +128,7 @@ TEST(THelp, VectorOpts) {

TEST(THelp, MultiPosOpts) {
CLI::App app{"My prog"};
app.set_name("program");
std::vector<int> x, y;
app.add_option("quick", x, "Disc")->expected(2);
app.add_option("vals", y, "Other");
Expand Down Expand Up @@ -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"));
Expand All @@ -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<char *> args = {x};
app.parse((int)args.size(), args.data());

EXPECT_THAT(app.help(), HasSubstr("Usage: MyRealName"));
}

TEST(THelp, IntDefaults) {
CLI::App app{"My prog"};

Expand Down Expand Up @@ -477,3 +489,9 @@ TEST(THelp, CustomDoubleOption) {

EXPECT_THAT(app.help(), Not(HasSubstr("x 2")));
}

TEST(THelp, AccessDescription) {
CLI::App app{"My description goes here"};

EXPECT_EQ(app.get_description(), "My description goes here");
}