diff --git a/libs/rtefsutils/include/RteFsUtils.h b/libs/rtefsutils/include/RteFsUtils.h index ae031ce7b..3d31a01d7 100644 --- a/libs/rtefsutils/include/RteFsUtils.h +++ b/libs/rtefsutils/include/RteFsUtils.h @@ -392,6 +392,14 @@ class RteFsUtils */ static const std::string& FileCategoryFromExtension(const std::string& file); + /** + * @brief find file using regular expression (non recursively) + * @param search path + * @param regular expression + * @param path to the file found + * @return true if file is found successfully, false otherwise + */ + static bool FindFileWithPattern(const std::string& searchPath, const std::string& pattern, std::string& file); }; #endif // RteFsUtils_H diff --git a/libs/rtefsutils/src/RteFsUtils.cpp b/libs/rtefsutils/src/RteFsUtils.cpp index 853262d1d..c25127877 100644 --- a/libs/rtefsutils/src/RteFsUtils.cpp +++ b/libs/rtefsutils/src/RteFsUtils.cpp @@ -867,4 +867,28 @@ const string& RteFsUtils::FileCategoryFromExtension(const string& file) { return OTHER; } +bool RteFsUtils::FindFileWithPattern(const std::string& searchDir, + const std::string& pattern, std::string& file) +{ + try { + std::regex fileRegex(pattern); + + // Iterate through the directory (not recursively) + for (const auto& entry : fs::directory_iterator(searchDir)) { + // Check only regular files + if (entry.is_regular_file()) { + const std::string fileName = entry.path().filename().string(); + if (std::regex_match(fileName, fileRegex)) { + file = fileName; + return true; // Return on match found + } + } + } + } + catch (const std::exception& e) { + std::cout << "error: " << e.what() << std::endl; + } + return false; // No matching file found +} + // End of RteFsUtils.cpp diff --git a/libs/rtefsutils/test/src/RteFsUtilsTest.cpp b/libs/rtefsutils/test/src/RteFsUtilsTest.cpp index fa021b5aa..7673e7add 100644 --- a/libs/rtefsutils/test/src/RteFsUtilsTest.cpp +++ b/libs/rtefsutils/test/src/RteFsUtilsTest.cpp @@ -1202,4 +1202,35 @@ TEST_F(RteFsUtilsTest, GetAbsPathFromLocalUrl) { EXPECT_EQ(absoluteFilename, RteFsUtils::GetAbsPathFromLocalUrl(testUrlOmittedHost)); } +TEST_F(RteFsUtilsTest, FindFileWithPattern) { + const string& testdir = dirnameBase + "/FindFileWithPattern"; + const string& fileName = "manifest_1.2.3.yml"; + const string& filePath = testdir + "/" + fileName; + RteFsUtils::CreateDirectories(testdir); + RteFsUtils::CreateTextFile(filePath, ""); + string discoveredFile; + EXPECT_EQ(true, RteFsUtils::FindFileWithPattern( + testdir, "manifest_(\\d+\\.\\d+\\.\\d+)(.*).yml", discoveredFile)); + EXPECT_EQ(fileName, discoveredFile); + RteFsUtils::RemoveDir(testdir); +} + +TEST_F(RteFsUtilsTest, FindFileWithPattern_NoMatch) { + const string& testdir = dirnameBase + "/FindFileWithPattern"; + RteFsUtils::CreateDirectories(testdir); + string discoveredFile; + + EXPECT_EQ(false, RteFsUtils::FindFileWithPattern(testdir, "manifest_(\\d+\\.\\d+\\.\\d+)(.*).yml", discoveredFile)); + RteFsUtils::RemoveDir(testdir); + EXPECT_TRUE(discoveredFile.empty()); +} + +TEST_F(RteFsUtilsTest, FindFileWithPattern_InvalidSearchPath) { + const string& testdir = dirnameBase + "/FindFileWithPattern"; + string discoveredFile; + + EXPECT_EQ(false, RteFsUtils::FindFileWithPattern(testdir, "manifest_(\\d+\\.\\d+\\.\\d+)(.*).yml", discoveredFile)); + RteFsUtils::RemoveDir(testdir); + EXPECT_TRUE(discoveredFile.empty()); +} // end of RteFsUtilsTest.cpp diff --git a/tools/projmgr/include/ProjMgr.h b/tools/projmgr/include/ProjMgr.h index 427480758..259602b3c 100644 --- a/tools/projmgr/include/ProjMgr.h +++ b/tools/projmgr/include/ProjMgr.h @@ -110,6 +110,11 @@ class ProjMgr { */ bool GetCdefaultFile(); + /** + * @brief get cmsis-toolbox version from manifest file + * @return version as string + */ + std::string GetToolboxVersion(const std::string& manifestFilePath); protected: ProjMgrParser m_parser; ProjMgrExtGenerator m_extGenerator; diff --git a/tools/projmgr/src/ProjMgr.cpp b/tools/projmgr/src/ProjMgr.cpp index 756543aba..f27888baf 100644 --- a/tools/projmgr/src/ProjMgr.cpp +++ b/tools/projmgr/src/ProjMgr.cpp @@ -1059,7 +1059,12 @@ bool ProjMgr::ValidateCreatedFor(const string& createdFor) { }); if (toolName == "cmsis-toolbox") { const string version = string(sm[2]) + '.' + string(sm[3]) + '.' + string(sm[4]); - const string currentVersion = string(VERSION_STRING) + ':' + string(VERSION_STRING); + string cmsisToolboxDir = ProjMgrKernel::Get()->GetCmsisToolboxDir(); + string currentVersion = GetToolboxVersion(cmsisToolboxDir); + if (currentVersion.empty()) { + return true; + } + currentVersion += (":" + currentVersion); if (VersionCmp::RangeCompare(version, currentVersion) <= 0) { return true; } else { @@ -1072,3 +1077,20 @@ bool ProjMgr::ValidateCreatedFor(const string& createdFor) { } return true; } + +string ProjMgr::GetToolboxVersion(const string& toolboxDir) { + // Find file non recursively under given search directory + string manifestFilePattern = "manifest_(\\d+\\.\\d+\\.\\d+)(.*).yml"; + string manifestFile; + + if (!RteFsUtils::FindFileWithPattern(toolboxDir, manifestFilePattern, manifestFile)) { + ProjMgrLogger::Get().Warn("manifest file does not exist", "", toolboxDir); + return ""; + } + + // Extract the version from filename and match it against the expected pattern + static const regex regEx = regex(manifestFilePattern); + smatch matchResult; + regex_match(manifestFile, matchResult, regEx); + return matchResult[1].str(); +} diff --git a/tools/projmgr/test/src/ProjMgrTestEnv.cpp b/tools/projmgr/test/src/ProjMgrTestEnv.cpp index fd5f31727..725b45456 100644 --- a/tools/projmgr/test/src/ProjMgrTestEnv.cpp +++ b/tools/projmgr/test/src/ProjMgrTestEnv.cpp @@ -102,6 +102,12 @@ void ProjMgrTestEnv::SetUp() { RteFsUtils::RemoveDir(bin_folder); } RteFsUtils::CreateDirectories(bin_folder); + // add dummy manifest file + string manifestFile = string(PROJMGRUNITTESTS_BIN_PATH) + "/../manifest_0.0.0.yml"; + if (RteFsUtils::Exists(manifestFile)) { + RteFsUtils::RemoveFile(manifestFile); + } + RteFsUtils::CreateTextFile(manifestFile, RteUtils::EMPTY_STRING); // copy local pack string srcPackPath, destPackPath; diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 0c2d52e3e..510b4d2d4 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -6503,3 +6503,25 @@ TEST_F(ProjMgrUnitTests, ReportPacksUnused) { EXPECT_EQ(1, cbuild2["build-idx"]["cbuilds"][0]["packs-unused"].size()); EXPECT_EQ("ARM::RteTestGenerator@0.1.0", cbuild2["build-idx"]["cbuilds"][0]["packs-unused"][0]["pack"].as()); } + +TEST_F(ProjMgrUnitTests, GetToolboxVersion) { + const string& testdir = testoutput_folder + "/toolbox_version"; + string fileName = "manifest_1.test2.3.yml"; + string filePath = testdir + "/" + fileName; + RteFsUtils::CreateDirectories(testdir); + RteFsUtils::CreateTextFile(filePath, ""); + + StdStreamRedirect streamRedirect; + EXPECT_EQ("", GetToolboxVersion(testdir)); + auto errStr = streamRedirect.GetErrorString(); + EXPECT_TRUE(errStr.find("manifest file does not exist") != string::npos); + + streamRedirect.ClearStringStreams(); + fileName = "manifest_1.2.3.yml"; + filePath = testdir + "/" + fileName; + RteFsUtils::CreateDirectories(testdir); + RteFsUtils::CreateTextFile(filePath, ""); + EXPECT_EQ("1.2.3", GetToolboxVersion(testdir)); + + RteFsUtils::RemoveDir(testdir); +}