1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-05-02 21:53:51 +00:00

Config count anomaly (#1003)

Correct an anomaly when using config file processing with a default. In
this case the count always shows 1 even if the default file were not
actually used. This caused some issues in some applications and was a
change from previous versions.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Philip Top 2024-02-07 15:31:01 -08:00 committed by GitHub
parent fd483ea006
commit cf6092bd88
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 5 deletions

View File

@ -1231,7 +1231,7 @@ class App {
void _process_config_file(); void _process_config_file();
/// Read and process a particular configuration file /// Read and process a particular configuration file
void _process_config_file(const std::string &config_file, bool throw_error); bool _process_config_file(const std::string &config_file, bool throw_error);
/// Get envname options if not yet passed. Runs on *all* subcommands. /// Get envname options if not yet passed. Runs on *all* subcommands.
void _process_env(); void _process_env();

View File

@ -1065,18 +1065,23 @@ CLI11_NODISCARD CLI11_INLINE detail::Classifier App::_recognize(const std::strin
return detail::Classifier::NONE; return detail::Classifier::NONE;
} }
CLI11_INLINE void App::_process_config_file(const std::string &config_file, bool throw_error) { CLI11_INLINE bool App::_process_config_file(const std::string &config_file, bool throw_error) {
auto path_result = detail::check_path(config_file.c_str()); auto path_result = detail::check_path(config_file.c_str());
if(path_result == detail::path_type::file) { if(path_result == detail::path_type::file) {
try { try {
std::vector<ConfigItem> values = config_formatter_->from_file(config_file); std::vector<ConfigItem> values = config_formatter_->from_file(config_file);
_parse_config(values); _parse_config(values);
return true;
} catch(const FileError &) { } catch(const FileError &) {
if(throw_error) if(throw_error) {
throw; throw;
} }
return false;
}
} else if(throw_error) { } else if(throw_error) {
throw FileError::Missing(config_file); throw FileError::Missing(config_file);
} else {
return false;
} }
} }
@ -1093,6 +1098,7 @@ CLI11_INLINE void App::_process_config_file() {
config_ptr_->run_callback(); config_ptr_->run_callback();
auto config_files = config_ptr_->as<std::vector<std::string>>(); auto config_files = config_ptr_->as<std::vector<std::string>>();
bool files_used{file_given};
if(config_files.empty() || config_files.front().empty()) { if(config_files.empty() || config_files.front().empty()) {
if(config_required) { if(config_required) {
throw FileError("config file is required but none was given"); throw FileError("config file is required but none was given");
@ -1100,7 +1106,17 @@ CLI11_INLINE void App::_process_config_file() {
return; return;
} }
for(const auto &config_file : config_files) { for(const auto &config_file : config_files) {
_process_config_file(config_file, config_required || file_given); if(_process_config_file(config_file, config_required || file_given)) {
files_used = true;
}
}
if(!files_used) {
// this is done so the count shows as 0 if no callbacks were processed
config_ptr_->clear();
bool force = config_ptr_->force_callback_;
config_ptr_->force_callback_ = false;
config_ptr_->run_callback();
config_ptr_->force_callback_ = force;
} }
} }
} }

View File

@ -1049,6 +1049,16 @@ TEST_CASE_METHOD(TApp, "IniRequiredNotFound", "[config]") {
CHECK_THROWS_AS(run(), CLI::FileError); CHECK_THROWS_AS(run(), CLI::FileError);
} }
TEST_CASE_METHOD(TApp, "IniDefaultNotExist", "[config]") {
std::string noini = "TestIniNotExist.ini";
auto *cfg = app.set_config("--config", noini);
CHECK_NOTHROW(run());
CHECK(cfg->count() == 0);
}
TEST_CASE_METHOD(TApp, "IniNotRequiredPassedNotFound", "[config]") { TEST_CASE_METHOD(TApp, "IniNotRequiredPassedNotFound", "[config]") {
std::string noini = "TestIniNotExist.ini"; std::string noini = "TestIniNotExist.ini";
@ -1084,7 +1094,7 @@ TEST_CASE_METHOD(TApp, "IniRequired", "[config]") {
TempFile tmpini{"TestIniTmp.ini"}; TempFile tmpini{"TestIniTmp.ini"};
app.set_config("--config", tmpini, "", true); auto *cfg = app.set_config("--config", tmpini, "", true);
{ {
std::ofstream out{tmpini}; std::ofstream out{tmpini};
@ -1109,6 +1119,7 @@ TEST_CASE_METHOD(TApp, "IniRequired", "[config]") {
args = {"--one=1", "--two=2"}; args = {"--one=1", "--two=2"};
CHECK_NOTHROW(run()); CHECK_NOTHROW(run());
CHECK(cfg->count() == 1);
CHECK(1 == one); CHECK(1 == one);
CHECK(2 == two); CHECK(2 == two);
CHECK(3 == three); CHECK(3 == three);