1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-05-03 14:03:52 +00:00

Finishing addition of ->configurable()

This commit is contained in:
Henry Fredrick Schreiner 2017-11-28 15:50:45 -05:00 committed by Henry Schreiner
parent c1fb53f00d
commit 4dac11c025
5 changed files with 75 additions and 33 deletions

View File

@ -86,30 +86,32 @@ class IncorrectConstruction : public ConstructionError {
CLI11_ERROR_DEF(ConstructionError, IncorrectConstruction) CLI11_ERROR_DEF(ConstructionError, IncorrectConstruction)
CLI11_ERROR_SIMPLE(IncorrectConstruction) CLI11_ERROR_SIMPLE(IncorrectConstruction)
static IncorrectConstruction PositionalFlag(std::string name) { static IncorrectConstruction PositionalFlag(std::string name) {
return IncorrectConstruction(name + ": Flags cannot be positional");} return IncorrectConstruction(name + ": Flags cannot be positional");
}
static IncorrectConstruction Set0Opt(std::string name) { static IncorrectConstruction Set0Opt(std::string name) {
return IncorrectConstruction(name + ": Cannot set 0 expected, use a flag instead");} return IncorrectConstruction(name + ": Cannot set 0 expected, use a flag instead");
}
static IncorrectConstruction ChangeNotVector(std::string name) { static IncorrectConstruction ChangeNotVector(std::string name) {
return IncorrectConstruction(name + ": You can only change the expected arguments for vectors");} return IncorrectConstruction(name + ": You can only change the expected arguments for vectors");
}
static IncorrectConstruction AfterMultiOpt(std::string name) { static IncorrectConstruction AfterMultiOpt(std::string name) {
return IncorrectConstruction(name + ": You can't change expected arguments after you've changed the multi option policy!");} return IncorrectConstruction(
name + ": You can't change expected arguments after you've changed the multi option policy!");
}
static IncorrectConstruction MissingOption(std::string name) { static IncorrectConstruction MissingOption(std::string name) {
return IncorrectConstruction("Option " + name + " is not defined");} return IncorrectConstruction("Option " + name + " is not defined");
}
static IncorrectConstruction MultiOptionPolicy(std::string name) { static IncorrectConstruction MultiOptionPolicy(std::string name) {
return IncorrectConstruction(name + ": multi_option_policy only works for flags and single value options");} return IncorrectConstruction(name + ": multi_option_policy only works for flags and single value options");
}
}; };
/// Thrown on construction of a bad name /// Thrown on construction of a bad name
class BadNameString : public ConstructionError { class BadNameString : public ConstructionError {
CLI11_ERROR_DEF(ConstructionError, BadNameString) CLI11_ERROR_DEF(ConstructionError, BadNameString)
CLI11_ERROR_SIMPLE(BadNameString) CLI11_ERROR_SIMPLE(BadNameString)
static BadNameString OneCharName(std::string name) { static BadNameString OneCharName(std::string name) { return BadNameString("Invalid one char name: " + name); }
return BadNameString("Invalid one char name: " + name); static BadNameString BadLongName(std::string name) { return BadNameString("Bad long name: " + name); }
}
static BadNameString BadLongName(std::string name) {
return BadNameString("Bad long name: " + name);
}
static BadNameString DashesOnly(std::string name) { static BadNameString DashesOnly(std::string name) {
return BadNameString("Must have a name, not just dashes: " + name); return BadNameString("Must have a name, not just dashes: " + name);
} }
@ -162,7 +164,7 @@ class RuntimeError : public ParseError {
class FileError : public ParseError { class FileError : public ParseError {
CLI11_ERROR_DEF(ParseError, FileError) CLI11_ERROR_DEF(ParseError, FileError)
CLI11_ERROR_SIMPLE(FileError) CLI11_ERROR_SIMPLE(FileError)
static FileError Missing(std::string name) {return FileError(name + " was not readable (missing?)");} static FileError Missing(std::string name) { return FileError(name + " was not readable (missing?)"); }
}; };
/// Thrown when conversion call back fails, such as when an int fails to coerce to a string /// Thrown when conversion call back fails, such as when an int fails to coerce to a string
@ -174,9 +176,11 @@ class ConversionError : public ParseError {
ConversionError(std::string name, std::vector<std::string> results) ConversionError(std::string name, std::vector<std::string> results)
: ConversionError("Could not convert: " + name + " = " + detail::join(results)) {} : ConversionError("Could not convert: " + name + " = " + detail::join(results)) {}
static ConversionError TooManyInputsFlag(std::string name) { static ConversionError TooManyInputsFlag(std::string name) {
return ConversionError(name + ": too many inputs for a flag");} return ConversionError(name + ": too many inputs for a flag");
}
static ConversionError TrueFalse(std::string name) { static ConversionError TrueFalse(std::string name) {
return ConversionError(name + ": Should be true/false or a number");} return ConversionError(name + ": Should be true/false or a number");
}
}; };
/// Thrown when validation of results fails /// Thrown when validation of results fails
@ -189,15 +193,14 @@ class ValidationError : public ParseError {
/// Thrown when a required option is missing /// Thrown when a required option is missing
class RequiredError : public ParseError { class RequiredError : public ParseError {
CLI11_ERROR_DEF(ParseError, RequiredError) CLI11_ERROR_DEF(ParseError, RequiredError)
RequiredError(std::string name) : RequiredError(name + " is required") {} RequiredError(std::string name) : RequiredError(name + " is required", ExitCodes::RequiredError) {}
static RequiredError Subcommand(size_t min_subcom) { static RequiredError Subcommand(size_t min_subcom) {
if(min_subcom == 1) if(min_subcom == 1)
return RequiredError("A subcommand"); return RequiredError("A subcommand");
else else
return RequiredError("Requires at least " + std::to_string(min_subcom) + " subcommands", ExitCodes::RequiredError); return RequiredError("Requires at least " + std::to_string(min_subcom) + " subcommands",
ExitCodes::RequiredError);
} }
}; };
/// Thrown when the wrong number of arguments has been received /// Thrown when the wrong number of arguments has been received
@ -212,11 +215,11 @@ class ArgumentMismatch : public ParseError {
ExitCodes::ArgumentMismatch) {} ExitCodes::ArgumentMismatch) {}
static ArgumentMismatch AtLeast(std::string name, int num) { static ArgumentMismatch AtLeast(std::string name, int num) {
return ArgumentMismatch(name + ": At least " + std::to_string(num) + " required");} return ArgumentMismatch(name + ": At least " + std::to_string(num) + " required");
}
static ArgumentMismatch TypedAtLeast(std::string name, int num, std::string type) { static ArgumentMismatch TypedAtLeast(std::string name, int num, std::string type) {
return ArgumentMismatch(name + ": " + std::to_string(num) + " required " + type + " missing");} return ArgumentMismatch(name + ": " + std::to_string(num) + " required " + type + " missing");
}
}; };
/// Thrown when a requires option is missing /// Thrown when a requires option is missing
@ -247,9 +250,10 @@ class ExtrasError : public ParseError {
class INIError : public ParseError { class INIError : public ParseError {
CLI11_ERROR_DEF(ParseError, INIError) CLI11_ERROR_DEF(ParseError, INIError)
CLI11_ERROR_SIMPLE(INIError) CLI11_ERROR_SIMPLE(INIError)
static INIError Extras(std::string item) {return INIError("INI was not able to parse " + item);} static INIError Extras(std::string item) { return INIError("INI was not able to parse " + item); }
static INIError NotConfigurable(std::string item) {return INIError(item + ": This option is not allowed in a configuration file");} static INIError NotConfigurable(std::string item) {
return INIError(item + ": This option is not allowed in a configuration file");
}
}; };
/// Thrown when validation fails before parsing /// Thrown when validation fails before parsing

View File

@ -47,11 +47,11 @@ template <typename CRTP> class OptionBase {
/// Policy for multiple arguments when `expected_ == 1` (can be set on bool flags, too) /// Policy for multiple arguments when `expected_ == 1` (can be set on bool flags, too)
MultiOptionPolicy multi_option_policy_{MultiOptionPolicy::Throw}; MultiOptionPolicy multi_option_policy_{MultiOptionPolicy::Throw};
template <typename T> void copy_to(T *other) const { template <typename T> void copy_to(T *other) const {
other->group(group_); other->group(group_);
other->required(required_); other->required(required_);
other->ignore_case(ignore_case_); other->ignore_case(ignore_case_);
other->configurable(configurable_);
other->multi_option_policy(multi_option_policy_); other->multi_option_policy(multi_option_policy_);
} }

View File

@ -303,12 +303,14 @@ TEST_F(TApp, OptionFromDefaultsSubcommands) {
EXPECT_FALSE(app.option_defaults()->get_required()); EXPECT_FALSE(app.option_defaults()->get_required());
EXPECT_EQ(app.option_defaults()->get_multi_option_policy(), CLI::MultiOptionPolicy::Throw); EXPECT_EQ(app.option_defaults()->get_multi_option_policy(), CLI::MultiOptionPolicy::Throw);
EXPECT_FALSE(app.option_defaults()->get_ignore_case()); EXPECT_FALSE(app.option_defaults()->get_ignore_case());
EXPECT_TRUE(app.option_defaults()->get_configurable());
EXPECT_EQ(app.option_defaults()->get_group(), "Options"); EXPECT_EQ(app.option_defaults()->get_group(), "Options");
app.option_defaults() app.option_defaults()
->required() ->required()
->multi_option_policy(CLI::MultiOptionPolicy::TakeLast) ->multi_option_policy(CLI::MultiOptionPolicy::TakeLast)
->ignore_case() ->ignore_case()
->configurable(false)
->group("Something"); ->group("Something");
auto app2 = app.add_subcommand("app2"); auto app2 = app.add_subcommand("app2");
@ -316,6 +318,7 @@ TEST_F(TApp, OptionFromDefaultsSubcommands) {
EXPECT_TRUE(app2->option_defaults()->get_required()); EXPECT_TRUE(app2->option_defaults()->get_required());
EXPECT_EQ(app2->option_defaults()->get_multi_option_policy(), CLI::MultiOptionPolicy::TakeLast); EXPECT_EQ(app2->option_defaults()->get_multi_option_policy(), CLI::MultiOptionPolicy::TakeLast);
EXPECT_TRUE(app2->option_defaults()->get_ignore_case()); EXPECT_TRUE(app2->option_defaults()->get_ignore_case());
EXPECT_FALSE(app2->option_defaults()->get_configurable());
EXPECT_EQ(app2->option_defaults()->get_group(), "Something"); EXPECT_EQ(app2->option_defaults()->get_group(), "Something");
} }

View File

@ -379,6 +379,41 @@ TEST_F(TApp, IniFailure) {
EXPECT_THROW(run(), CLI::INIError); EXPECT_THROW(run(), CLI::INIError);
} }
TEST_F(TApp, IniConfigurable) {
TempFile tmpini{"TestIniTmp.ini"};
app.add_config("--config", tmpini);
bool value;
app.add_flag("--val", value)->configurable(true);
{
std::ofstream out{tmpini};
out << "[default]" << std::endl;
out << "val=1" << std::endl;
}
EXPECT_NO_THROW(run());
EXPECT_TRUE(value);
}
TEST_F(TApp, IniNotConfigurable) {
TempFile tmpini{"TestIniTmp.ini"};
app.add_config("--config", tmpini);
bool value;
app.add_flag("--val", value)->configurable(false);
{
std::ofstream out{tmpini};
out << "[default]" << std::endl;
out << "val=1" << std::endl;
}
EXPECT_THROW(run(), CLI::INIError);
}
TEST_F(TApp, IniSubFailure) { TEST_F(TApp, IniSubFailure) {
TempFile tmpini{"TestIniTmp.ini"}; TempFile tmpini{"TestIniTmp.ini"};