1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-04-30 04:33:53 +00:00

Help priority adjustment (#1106)

Move the help generation priority higher so it triggers before config
file processing.

Fixes #1099

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Philip Top 2024-12-26 06:13:36 -08:00 committed by GitHub
parent ef50bb35c3
commit ecdcf633a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 62 additions and 15 deletions

View File

@ -28,10 +28,11 @@ jobs:
- name: Get LCov - name: Get LCov
run: | run: |
wget https://github.com/linux-test-project/lcov/releases/download/v1.16/lcov-1.16.tar.gz sudo apt-get install ca-certificates lcov
tar -xzf lcov-1.16.tar.gz #wget https://github.com/linux-test-project/lcov/releases/download/v1.16/lcov-1.16.tar.gz
cd lcov-1.16 #tar -xzf lcov-1.16.tar.gz
sudo make install #cd lcov-1.16
#sudo make install
- name: Configure - name: Configure
run: | run: |
@ -50,8 +51,8 @@ jobs:
- name: Prepare coverage - name: Prepare coverage
run: | run: |
lcov --directory . --capture --output-file coverage.info lcov --ignore-errors gcov,mismatch --directory . --capture --output-file coverage.info
lcov --remove coverage.info '*/tests/*' '*/examples/*' '/usr/*' '*/book/*' '*/fuzz/*' --output-file coverage.info lcov --remove coverage.info '*/tests/*' '/usr/*' --output-file coverage.info
lcov --list coverage.info lcov --list coverage.info
working-directory: build working-directory: build

View File

@ -270,6 +270,8 @@ function(setup_target_for_coverage_lcov)
${Coverage_LCOV_ARGS} ${Coverage_LCOV_ARGS}
--gcov-tool --gcov-tool
${GCOV_PATH} ${GCOV_PATH}
--ignore-errors
mismatch
-directory -directory
. .
-b -b
@ -281,6 +283,8 @@ function(setup_target_for_coverage_lcov)
${Coverage_LCOV_ARGS} ${Coverage_LCOV_ARGS}
--gcov-tool --gcov-tool
${GCOV_PATH} ${GCOV_PATH}
--ignore-errors
mismatch
-c -c
-i -i
-d -d
@ -302,6 +306,8 @@ function(setup_target_for_coverage_lcov)
-b -b
${BASEDIR} ${BASEDIR}
--capture --capture
--ignore-errors
mismatch,gcov
--output-file --output-file
${Coverage_NAME}.capture) ${Coverage_NAME}.capture)
# add baseline counters # add baseline counters
@ -314,6 +320,8 @@ function(setup_target_for_coverage_lcov)
${Coverage_NAME}.base ${Coverage_NAME}.base
-a -a
${Coverage_NAME}.capture ${Coverage_NAME}.capture
--ignore-errors
mismatch,gcov
--output-file --output-file
${Coverage_NAME}.total) ${Coverage_NAME}.total)
# filter collected data to final coverage report # filter collected data to final coverage report
@ -322,14 +330,23 @@ function(setup_target_for_coverage_lcov)
${Coverage_LCOV_ARGS} ${Coverage_LCOV_ARGS}
--gcov-tool --gcov-tool
${GCOV_PATH} ${GCOV_PATH}
--ignore-errors
mismatch,mismatch,gcov
--remove --remove
${Coverage_NAME}.total ${Coverage_NAME}.total
${LCOV_EXCLUDES} ${LCOV_EXCLUDES}
--output-file --output-file
${Coverage_NAME}.info) ${Coverage_NAME}.info)
# Generate HTML output # Generate HTML output
set(LCOV_GEN_HTML_CMD ${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} -o set(LCOV_GEN_HTML_CMD
${Coverage_NAME} ${Coverage_NAME}.info) ${GENHTML_PATH}
${GENHTML_EXTRA_ARGS}
--ignore-errors
mismatch,mismatch
${Coverage_GENHTML_ARGS}
-o
${Coverage_NAME}
${Coverage_NAME}.info)
if(${Coverage_SONARQUBE}) if(${Coverage_SONARQUBE})
# Generate SonarQube output # Generate SonarQube output
set(GCOVR_XML_CMD set(GCOVR_XML_CMD
@ -347,7 +364,7 @@ function(setup_target_for_coverage_lcov)
COMMENT "SonarQube code coverage info report saved in ${Coverage_NAME}_sonarqube.xml.") COMMENT "SonarQube code coverage info report saved in ${Coverage_NAME}_sonarqube.xml.")
endif() endif()
if(CODE_COVERAGE_VERBOSE) if(CODE_COVERAGE_VERBOSE OR 1)
message(STATUS "Executed command report") message(STATUS "Executed command report")
message(STATUS "Command to clean up lcov: ") message(STATUS "Command to clean up lcov: ")
string(REPLACE ";" " " LCOV_CLEAN_CMD_SPACED "${LCOV_CLEAN_CMD}") string(REPLACE ";" " " LCOV_CLEAN_CMD_SPACED "${LCOV_CLEAN_CMD}")

View File

@ -1385,7 +1385,7 @@ bool lexical_assign(const std::string &input, AssignTo &output) {
} }
return lexical_cast(input, output); return lexical_cast(input, output);
} } // LCOV_EXCL_LINE
/// Assign a value through lexical cast operations /// Assign a value through lexical cast operations
template <typename AssignTo, template <typename AssignTo,

View File

@ -1367,6 +1367,9 @@ CLI11_INLINE void App::_process_requirements() {
} }
CLI11_INLINE void App::_process() { CLI11_INLINE void App::_process() {
// help takes precedence over other potential errors and config and environment shouldn't be processed if help
// throws
_process_help_flags();
try { try {
// the config file might generate a FileError but that should not be processed until later in the process // the config file might generate a FileError but that should not be processed until later in the process
// to allow for help, version and other errors to generate first. // to allow for help, version and other errors to generate first.
@ -1375,15 +1378,13 @@ CLI11_INLINE void App::_process() {
// process env shouldn't throw but no reason to process it if config generated an error // process env shouldn't throw but no reason to process it if config generated an error
_process_env(); _process_env();
} catch(const CLI::FileError &) { } catch(const CLI::FileError &) {
// callbacks and help_flags can generate exceptions which should take priority // callbacks can generate exceptions which should take priority
// over the config file error if one exists. // over the config file error if one exists.
_process_callbacks(); _process_callbacks();
_process_help_flags();
throw; throw;
} }
_process_callbacks(); _process_callbacks();
_process_help_flags();
_process_requirements(); _process_requirements();
} }

View File

@ -2097,6 +2097,34 @@ TEST_CASE_METHOD(TApp, "IniSubcommandConfigurableInQuotesAliasWithEquals", "[con
CHECK(app.got_subcommand(subcom)); CHECK(app.got_subcommand(subcom));
} }
TEST_CASE_METHOD(TApp, "IniSubcommandConfigurableHelp", "[config]") {
TempFile tmpini{"TestIniTmp.ini"};
app.set_config("--config", tmpini);
{
std::ofstream out{tmpini};
out << "[default]" << '\n';
out << "val=1" << '\n';
out << "[subcom]" << '\n';
out << "val=2" << '\n';
}
int one{0}, two{0};
app.add_option("--val", one);
app.add_option("--helptest", two);
auto *subcom = app.add_subcommand("subcom");
subcom->configurable();
subcom->add_option("--val", two);
args = {"--help"};
CHECK_THROWS_AS(run(), CLI::CallForHelp);
auto helpres = app.help();
CHECK_THAT(helpres, Contains("--helptest"));
}
TEST_CASE_METHOD(TApp, "IniSubcommandConfigurableInQuotesAliasWithComment", "[config]") { TEST_CASE_METHOD(TApp, "IniSubcommandConfigurableInQuotesAliasWithComment", "[config]") {
TempFile tmpini{"TestIniTmp.ini"}; TempFile tmpini{"TestIniTmp.ini"};

View File

@ -301,7 +301,7 @@ TEST_CASE("StringTools: binaryEscapeConversion2", "[helpers]") {
CHECK(rstring == testString); CHECK(rstring == testString);
} }
TEST_CASE("StringTools: binaryEscapseConversion_withX", "[helpers]") { TEST_CASE("StringTools: binaryEscapeConversion_withX", "[helpers]") {
std::string testString("hippy\\x35mm\\XF3_helpX26fox19"); std::string testString("hippy\\x35mm\\XF3_helpX26fox19");
testString.push_back(0); testString.push_back(0);
testString.push_back(0); testString.push_back(0);
@ -317,7 +317,7 @@ TEST_CASE("StringTools: binaryEscapseConversion_withX", "[helpers]") {
CHECK(rstring == testString); CHECK(rstring == testString);
} }
TEST_CASE("StringTools: binaryEscapseConversion_withBrackets", "[helpers]") { TEST_CASE("StringTools: binaryEscapeConversion_withBrackets", "[helpers]") {
std::string vstr = R"raw('B"([\xb0\x0a\xb0/\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0])"')raw"; std::string vstr = R"raw('B"([\xb0\x0a\xb0/\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0\xb0])"')raw";
std::string testString("["); std::string testString("[");