From e0a55e4a7dde8074475ee7e3ee897a81102fa75d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 13 Mar 2024 11:19:29 +0100 Subject: [PATCH] Fix #12505 (cli: Add option --check-version to pin cppcheck version) --- cli/cmdlineparser.cpp | 31 ++++++++++++++++++++++--------- releasenotes.txt | 3 ++- test/testcmdlineparser.cpp | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 7f275ab00dfb..8db720aae08f 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -117,6 +117,15 @@ static bool addPathsToSet(const std::string& fileName, std::set& se return true; } +static std::string getVersion(const Settings& settings) { + if (!settings.cppcheckCfgProductName.empty()) + return settings.cppcheckCfgProductName; + const char * const extraVersion = CppCheck::extraVersion(); + if (*extraVersion != '\0') + return std::string("Cppcheck ") + CppCheck::version() + " ("+ extraVersion + ')'; + return std::string("Cppcheck ") + CppCheck::version(); +} + namespace { class XMLErrorMessagesLogger : public ErrorLogger { @@ -356,15 +365,8 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a if (std::strcmp(argv[i], "--version") == 0) { if (!loadCppcheckCfg()) return Result::Fail; - if (!mSettings.cppcheckCfgProductName.empty()) { - mLogger.printRaw(mSettings.cppcheckCfgProductName); - } else { - const char * const extraVersion = CppCheck::extraVersion(); - if (*extraVersion != '\0') - mLogger.printRaw(std::string("Cppcheck ") + CppCheck::version() + " ("+ extraVersion + ')'); - else - mLogger.printRaw(std::string("Cppcheck ") + CppCheck::version()); - } + const std::string version = getVersion(mSettings); + mLogger.printRaw(version); return Result::Exit; } } @@ -488,6 +490,17 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a mSettings.checkLibrary = true; } + else if (std::strncmp(argv[i], "--check-version=", 16) == 0) { + if (!loadCppcheckCfg()) + return Result::Fail; + const std::string actualVersion = getVersion(mSettings); + const std::string wantedVersion = argv[i] + 16; + if (actualVersion != wantedVersion) { + mLogger.printError("--check-version check failed. Aborting."); + return Result::Fail; + } + } + else if (std::strncmp(argv[i], "--checkers-report=", 18) == 0) mSettings.checkersReportFilename = argv[i] + 18; diff --git a/releasenotes.txt b/releasenotes.txt index 65c9e9ef90ac..d4e39c5a810b 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -24,4 +24,5 @@ Other: - Removed deprecated platform type 'Unspecified'. Please use 'unspecified' instead. - Removed deprecated 'Makefile' option 'SRCDIR'. - Added CMake option 'DISALLOW_THREAD_EXECUTOR' to control the inclusion of the executor which performs the analysis within a thread of the main process. -- Removed CMake option 'USE_THREADS' in favor of 'DISALLOW_THREAD_EXECUTOR'. \ No newline at end of file +- Removed CMake option 'USE_THREADS' in favor of 'DISALLOW_THREAD_EXECUTOR'. +- Add option '--check-version', you can use it to pin the cppcheck version in a script. diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 5437ca9f0130..a6619a53eecd 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -119,6 +119,7 @@ class TestCmdlineParser : public TestFixture { TEST_CASE(versionWithCfg); TEST_CASE(versionExclusive); TEST_CASE(versionWithInvalidCfg); + TEST_CASE(checkVersion); TEST_CASE(onefile); TEST_CASE(onepath); TEST_CASE(optionwithoutfile); @@ -466,6 +467,23 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS("cppcheck: error: could not load cppcheck.cfg - not a valid JSON - syntax error at line 2 near: \n", logger->str()); } + void checkVersion() { + REDIRECT; + // get version + const char * const argv1[] = {"cppcheck", "--version"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Exit, parser->parseFromArgs(2, argv1)); + std::string version = logger->str(); + version.erase(version.find('\n')); + const std::string checkCorrectVersion = "--check-version=" + version; + // check version: correct version + const char * const argv2[] = {"cppcheck", checkCorrectVersion.c_str(), "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv2)); + // check version: incorrect version + const char * const argv3[] = {"cppcheck", "--check-version=Cppcheck 2.0", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parser->parseFromArgs(3, argv3)); + ASSERT_EQUALS("cppcheck: error: --check-version check failed. Aborting.\n", logger->str()); + } + void onefile() { REDIRECT; const char * const argv[] = {"cppcheck", "file.cpp"};