mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-05-02 13:43:52 +00:00
Finishing addition of ->configurable()
This commit is contained in:
parent
c1fb53f00d
commit
4dac11c025
@ -1209,7 +1209,7 @@ class App {
|
||||
|
||||
if(!op->get_configurable())
|
||||
throw INIError::NotConfigurable(current.fullname);
|
||||
|
||||
|
||||
if(op->results_.empty()) {
|
||||
// Flag parsing
|
||||
if(op->get_expected() == 0) {
|
||||
|
@ -86,30 +86,32 @@ class IncorrectConstruction : public ConstructionError {
|
||||
CLI11_ERROR_DEF(ConstructionError, IncorrectConstruction)
|
||||
CLI11_ERROR_SIMPLE(IncorrectConstruction)
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
return IncorrectConstruction("Option " + name + " is not defined");}
|
||||
return IncorrectConstruction("Option " + name + " is not defined");
|
||||
}
|
||||
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
|
||||
class BadNameString : public ConstructionError {
|
||||
CLI11_ERROR_DEF(ConstructionError, BadNameString)
|
||||
CLI11_ERROR_SIMPLE(BadNameString)
|
||||
static BadNameString OneCharName(std::string name) {
|
||||
return BadNameString("Invalid one char name: " + name);
|
||||
}
|
||||
static BadNameString BadLongName(std::string name) {
|
||||
return BadNameString("Bad long name: " + name);
|
||||
}
|
||||
static BadNameString OneCharName(std::string name) { return BadNameString("Invalid one char name: " + name); }
|
||||
static BadNameString BadLongName(std::string name) { return BadNameString("Bad long name: " + name); }
|
||||
static BadNameString DashesOnly(std::string name) {
|
||||
return BadNameString("Must have a name, not just dashes: " + name);
|
||||
}
|
||||
@ -162,7 +164,7 @@ class RuntimeError : public ParseError {
|
||||
class FileError : public ParseError {
|
||||
CLI11_ERROR_DEF(ParseError, 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
|
||||
@ -174,9 +176,11 @@ class ConversionError : public ParseError {
|
||||
ConversionError(std::string name, std::vector<std::string> results)
|
||||
: ConversionError("Could not convert: " + name + " = " + detail::join(results)) {}
|
||||
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) {
|
||||
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
|
||||
@ -189,15 +193,14 @@ class ValidationError : public ParseError {
|
||||
/// Thrown when a required option is missing
|
||||
class RequiredError : public ParseError {
|
||||
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) {
|
||||
if(min_subcom == 1)
|
||||
return RequiredError("A subcommand");
|
||||
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
|
||||
@ -210,13 +213,13 @@ class ArgumentMismatch : public ParseError {
|
||||
: ("Expected at least " + std::to_string(-expected) + " arguments to " + name +
|
||||
", got " + std::to_string(recieved)),
|
||||
ExitCodes::ArgumentMismatch) {}
|
||||
|
||||
|
||||
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) {
|
||||
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
|
||||
@ -247,9 +250,10 @@ class ExtrasError : public ParseError {
|
||||
class INIError : public ParseError {
|
||||
CLI11_ERROR_DEF(ParseError, INIError)
|
||||
CLI11_ERROR_SIMPLE(INIError)
|
||||
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 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");
|
||||
}
|
||||
};
|
||||
|
||||
/// Thrown when validation fails before parsing
|
||||
|
@ -43,15 +43,15 @@ template <typename CRTP> class OptionBase {
|
||||
|
||||
/// Allow this option to be given in a configuration file
|
||||
bool configurable_{true};
|
||||
|
||||
|
||||
/// Policy for multiple arguments when `expected_ == 1` (can be set on bool flags, too)
|
||||
MultiOptionPolicy multi_option_policy_{MultiOptionPolicy::Throw};
|
||||
|
||||
|
||||
template <typename T> void copy_to(T *other) const {
|
||||
other->group(group_);
|
||||
other->required(required_);
|
||||
other->ignore_case(ignore_case_);
|
||||
other->configurable(configurable_);
|
||||
other->multi_option_policy(multi_option_policy_);
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ template <typename CRTP> class OptionBase {
|
||||
|
||||
/// The status of ignore case
|
||||
bool get_ignore_case() const { return ignore_case_; }
|
||||
|
||||
|
||||
/// The status of configurable
|
||||
bool get_configurable() const { return configurable_; }
|
||||
|
||||
@ -113,7 +113,7 @@ template <typename CRTP> class OptionBase {
|
||||
self->multi_option_policy(MultiOptionPolicy::Join);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
/// Allow in a configuration file
|
||||
CRTP *configurable(bool value = true) {
|
||||
configurable_ = value;
|
||||
|
@ -303,12 +303,14 @@ TEST_F(TApp, OptionFromDefaultsSubcommands) {
|
||||
EXPECT_FALSE(app.option_defaults()->get_required());
|
||||
EXPECT_EQ(app.option_defaults()->get_multi_option_policy(), CLI::MultiOptionPolicy::Throw);
|
||||
EXPECT_FALSE(app.option_defaults()->get_ignore_case());
|
||||
EXPECT_TRUE(app.option_defaults()->get_configurable());
|
||||
EXPECT_EQ(app.option_defaults()->get_group(), "Options");
|
||||
|
||||
app.option_defaults()
|
||||
->required()
|
||||
->multi_option_policy(CLI::MultiOptionPolicy::TakeLast)
|
||||
->ignore_case()
|
||||
->configurable(false)
|
||||
->group("Something");
|
||||
|
||||
auto app2 = app.add_subcommand("app2");
|
||||
@ -316,6 +318,7 @@ TEST_F(TApp, OptionFromDefaultsSubcommands) {
|
||||
EXPECT_TRUE(app2->option_defaults()->get_required());
|
||||
EXPECT_EQ(app2->option_defaults()->get_multi_option_policy(), CLI::MultiOptionPolicy::TakeLast);
|
||||
EXPECT_TRUE(app2->option_defaults()->get_ignore_case());
|
||||
EXPECT_FALSE(app2->option_defaults()->get_configurable());
|
||||
EXPECT_EQ(app2->option_defaults()->get_group(), "Something");
|
||||
}
|
||||
|
||||
|
@ -379,6 +379,41 @@ TEST_F(TApp, IniFailure) {
|
||||
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) {
|
||||
|
||||
TempFile tmpini{"TestIniTmp.ini"};
|
||||
|
Loading…
x
Reference in New Issue
Block a user