From f3df8bcc8a7280c376fc28a6a50445a8e014aa34 Mon Sep 17 00:00:00 2001 From: Jen-Tse Huang Date: Wed, 25 Mar 2026 16:54:13 +0100 Subject: [PATCH 1/6] Add `download-url` into error reporting for external generator failures --- .../0.1.0/ARM.RteTestGenerator.pdsc | 12 +++++++ tools/projmgr/include/ProjMgrExtGenerator.h | 7 ++++ tools/projmgr/src/ProjMgrExtGenerator.cpp | 5 +++ tools/projmgr/src/ProjMgrWorker.cpp | 12 ++++++- .../ExternalGenerator/extgen.csolution.yml | 2 ++ .../ExternalGenerator/global.generator.yml | 4 +++ .../test-url/test-url.cproject.yml | 15 ++++++++ tools/projmgr/test/src/ProjMgrUnitTests.cpp | 35 ++++++++++++++++++- 8 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 tools/projmgr/test/data/ExternalGenerator/test-url/test-url.cproject.yml diff --git a/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc b/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc index b732712bd..d45c8ce2d 100644 --- a/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc +++ b/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc @@ -27,6 +27,8 @@ RteTest ARM M Device Family + + @@ -193,6 +195,16 @@ + + + Component addressing external with exit code 1 + + + + + + + Component with overlaping file lists diff --git a/tools/projmgr/include/ProjMgrExtGenerator.h b/tools/projmgr/include/ProjMgrExtGenerator.h index f60055d2a..50d2bb2da 100644 --- a/tools/projmgr/include/ProjMgrExtGenerator.h +++ b/tools/projmgr/include/ProjMgrExtGenerator.h @@ -73,6 +73,13 @@ class ProjMgrExtGenerator { */ const std::string& GetGlobalGenRunCmd(const std::string& generatorId); + /** + * @brief get URL for generator download + * @param generatorId generator identifier + * @return string with URL for generator download + */ + const std::string& GetGlobalGenUrl(const std::string& generatorId); + /** * @brief get generator description * @param generatorId generator identifier diff --git a/tools/projmgr/src/ProjMgrExtGenerator.cpp b/tools/projmgr/src/ProjMgrExtGenerator.cpp index 46ac1203b..3ca9b24fd 100644 --- a/tools/projmgr/src/ProjMgrExtGenerator.cpp +++ b/tools/projmgr/src/ProjMgrExtGenerator.cpp @@ -49,6 +49,11 @@ const string& ProjMgrExtGenerator::GetGlobalGenRunCmd(const string& generatorId) return g ? g->GetRunAttribute() : RteUtils::EMPTY_STRING; } +const string& ProjMgrExtGenerator::GetGlobalGenUrl(const string& generatorId) { + RteGenerator* g = ProjMgrKernel::Get()->GetExternalGenerator(generatorId); + return g ? g->GetURL() : RteUtils::EMPTY_STRING; +} + const string& ProjMgrExtGenerator::GetGlobalDescription(const string& generatorId) { RteGenerator* g = ProjMgrKernel::Get()->GetExternalGenerator(generatorId); return g ? g->GetDescription() : RteUtils::EMPTY_STRING; diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index f92121a7f..d7f77ffc8 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -5650,11 +5650,21 @@ bool ProjMgrWorker::ExecuteExtGenerator(std::string& generatorId) { fs::current_path(genDir, ec); StrIntPair result = CrossPlatformUtils::ExecCommand(runCmd); fs::current_path(workingDir, ec); - ProjMgrLogger::Get().Info("generator '" + generatorId + "' for context '" + selectedContextId + "' reported:\n" + result.first); if (result.second) { ProjMgrLogger::Get().Error("executing generator '" + generatorId + "' for context '" + selectedContextId + "' failed"); + ProjMgrLogger::Get().Info("generator '" + generatorId + "' for context '" + selectedContextId + "' reported:\n" + result.first); + + const string downloadUrl = m_extGenerator->GetGlobalGenUrl(generatorId); + if (!downloadUrl.empty()) { + ProjMgrLogger::Get().Error("check the URL for downloading the generator: " + downloadUrl); + } + else { + ProjMgrLogger::Get().Error("download URL is not available for generator '" + generatorId + "' in generator.yml"); + } return false; } + + ProjMgrLogger::Get().Info("generator '" + generatorId + "' for context '" + selectedContextId + "' reported:\n" + result.first); return true; } diff --git a/tools/projmgr/test/data/ExternalGenerator/extgen.csolution.yml b/tools/projmgr/test/data/ExternalGenerator/extgen.csolution.yml index 40b936360..d8591c3e4 100644 --- a/tools/projmgr/test/data/ExternalGenerator/extgen.csolution.yml +++ b/tools/projmgr/test/data/ExternalGenerator/extgen.csolution.yml @@ -24,6 +24,8 @@ solution: for-context: +CM0 - project: tz_ns/ns.cproject.yml for-context: +CM0 + - project: test-url/test-url.cproject.yml + for-context: +CM0 - project: multi_0/core0.cproject.yml for-context: +MultiCore - project: multi_1/core1.cproject.yml diff --git a/tools/projmgr/test/data/ExternalGenerator/global.generator.yml b/tools/projmgr/test/data/ExternalGenerator/global.generator.yml index 4bbd32284..e1df5f4c5 100644 --- a/tools/projmgr/test/data/ExternalGenerator/global.generator.yml +++ b/tools/projmgr/test/data/ExternalGenerator/global.generator.yml @@ -4,3 +4,7 @@ generator: download-url: https://raw.githubusercontent.com/Open-CMSIS-Pack run: ../bin/bridge tool.sh path: $SolutionDir()$/generated/$TargetType$ + - id: RteTestExternalGeneratorNoUrl + description: Global Registered Generator Without Url + run: ../bin/bridge tool.sh + path: $SolutionDir()$/generated/$TargetType$ diff --git a/tools/projmgr/test/data/ExternalGenerator/test-url/test-url.cproject.yml b/tools/projmgr/test/data/ExternalGenerator/test-url/test-url.cproject.yml new file mode 100644 index 000000000..f4c5bc861 --- /dev/null +++ b/tools/projmgr/test/data/ExternalGenerator/test-url/test-url.cproject.yml @@ -0,0 +1,15 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json + +project: + components: + - component: RteTestGeneratorNoUrl:Check Global Generator + + groups: + - group: sources + files: + - file: main.c + + generators: + options: + - generator: RteTestExternalGeneratorNoUrl + path: $ProjectDir()$/generated/ diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 2d008d687..8ee7e9bb3 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -4025,7 +4025,8 @@ TEST_F(ProjMgrUnitTests, ListComponents_MultiplePackSelection) { "ARM::Device:RteTest Generated Component:RteTestWithKey@1.1.0 (ARM::RteTestGenerator@0.1.0)", "ARM::Device:RteTest Generated Component:RteTestNoExe@1.1.0 (ARM::RteTestGenerator@0.1.0)", "ARM::Device:RteTest Generated Component:RteTestOverlap@1.1.0 (ARM::RteTestGenerator@0.1.0)", - "ARM::RteTestGenerator:Check Global Generator@0.9.0 (ARM::RteTestGenerator@0.1.0)" + "ARM::RteTestGenerator:Check Global Generator@0.9.0 (ARM::RteTestGenerator@0.1.0)", + "ARM::RteTestGeneratorNoUrl:Check Global Generator@0.9.0 (ARM::RteTestGenerator@0.1.0)" }; vector components; m_csolutionFile = testinput_folder + "/TestSolution/pack_contexts.csolution.yml"; @@ -5704,6 +5705,38 @@ TEST_F(ProjMgrUnitTests, ExternalGenerator_NoCgenFile) { RteFsUtils::RemoveFile(dstGlobalGenerator); } +TEST_F(ProjMgrUnitTests, ExternalGenerator_PrintUrl) { + const string& srcGlobalGenerator = testinput_folder + "/ExternalGenerator/global.generator.yml"; + const string& dstGlobalGenerator = etc_folder + "/global.generator.yml"; + RteFsUtils::CopyCheckFile(srcGlobalGenerator, dstGlobalGenerator, false); + + StdStreamRedirect streamRedirect; + // test case where the URL returns an exit code of 1 (simulated by not copying the 'bridge tool.sh' script) + char* argv[7]; + const string& csolution = testinput_folder + "/ExternalGenerator/extgen.csolution.yml"; + argv[1] = (char*)csolution.c_str(); + argv[2] = (char*)"run"; + argv[3] = (char*)"-g"; + argv[4] = (char*)"RteTestExternalGenerator"; + argv[5] = (char*)"-c"; + argv[6] = (char*)"single-core.Debug+CM0"; + EXPECT_EQ(1, RunProjMgr(7, argv, m_envp)); + string errStr = streamRedirect.GetErrorString(); + string errExpected = "check the URL for downloading the generator: https://raw.githubusercontent.com/Open-CMSIS-Pack"; + EXPECT_NE(string::npos, errStr.find(errExpected)); + + streamRedirect.ClearStringStreams(); + // test case where the download-url is missing of a generator + argv[4] = (char*)"RteTestExternalGeneratorNoUrl"; + argv[6] = (char*)"test-url.Debug+CM0"; + EXPECT_EQ(1, RunProjMgr(7, argv, m_envp)); + errStr = streamRedirect.GetErrorString(); + errExpected = "download URL is not available for generator '" + string(argv[4]) + "' in generator.yml"; + EXPECT_NE(string::npos, errStr.find(errExpected)); + + RteFsUtils::RemoveFile(dstGlobalGenerator); +} + TEST_F(ProjMgrUnitTests, ExternalGeneratorBoard) { const string& srcGlobalGenerator = testinput_folder + "/ExternalGenerator/global.generator.yml"; const string& dstGlobalGenerator = etc_folder + "/global.generator.yml"; From 253586fdd72b6344fa1fc4ca03d17c657fdd1d0d Mon Sep 17 00:00:00 2001 From: Jen-Tse Huang Date: Wed, 25 Mar 2026 17:09:22 +0100 Subject: [PATCH 2/6] Refine changes --- .../ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc | 2 -- tools/projmgr/test/src/ProjMgrUnitTests.cpp | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc b/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc index d45c8ce2d..45f18e7b4 100644 --- a/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc +++ b/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc @@ -27,8 +27,6 @@ RteTest ARM M Device Family - - diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 8ee7e9bb3..ad0149da8 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -5711,7 +5711,7 @@ TEST_F(ProjMgrUnitTests, ExternalGenerator_PrintUrl) { RteFsUtils::CopyCheckFile(srcGlobalGenerator, dstGlobalGenerator, false); StdStreamRedirect streamRedirect; - // test case where the URL returns an exit code of 1 (simulated by not copying the 'bridge tool.sh' script) + // test case where the URL returns an exit code of 1 (simulated by not copying the 'bridge tool.sh' script) char* argv[7]; const string& csolution = testinput_folder + "/ExternalGenerator/extgen.csolution.yml"; argv[1] = (char*)csolution.c_str(); @@ -5725,8 +5725,8 @@ TEST_F(ProjMgrUnitTests, ExternalGenerator_PrintUrl) { string errExpected = "check the URL for downloading the generator: https://raw.githubusercontent.com/Open-CMSIS-Pack"; EXPECT_NE(string::npos, errStr.find(errExpected)); - streamRedirect.ClearStringStreams(); - // test case where the download-url is missing of a generator + streamRedirect.ClearStringStreams(); + // test case where the download-url is missing of a generator argv[4] = (char*)"RteTestExternalGeneratorNoUrl"; argv[6] = (char*)"test-url.Debug+CM0"; EXPECT_EQ(1, RunProjMgr(7, argv, m_envp)); From d3f574a1ca1b06b219da467d822b145eae13b39c Mon Sep 17 00:00:00 2001 From: Jen-Tse Huang Date: Wed, 25 Mar 2026 18:47:12 +0100 Subject: [PATCH 3/6] Update numbers in RteChkTest --- libs/rtemodel/test/src/RteChkTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/rtemodel/test/src/RteChkTest.cpp b/libs/rtemodel/test/src/RteChkTest.cpp index 388813725..886bd60a1 100644 --- a/libs/rtemodel/test/src/RteChkTest.cpp +++ b/libs/rtemodel/test/src/RteChkTest.cpp @@ -30,9 +30,9 @@ Generic: 4\n\ DFP: 3\n\ BSP: 1\n\ \n\ -Components: 60\n\ +Components: 61\n\ From generic packs: 36\n\ -From DFP: 24\n\ +From DFP: 25\n\ From BSP: 0\n\ \n\ Devices: 10\n\ @@ -51,7 +51,7 @@ completed\n"; int res = rteChk.RunCheckRte(); EXPECT_EQ(res, 0); EXPECT_EQ(rteChk.GetPackCount(), 8); - EXPECT_EQ(rteChk.GetComponentCount(), 60); + EXPECT_EQ(rteChk.GetComponentCount(), 61); EXPECT_EQ(rteChk.GetDeviceCount(), 10); EXPECT_EQ(rteChk.GetBoardCount(), 15); From 043bf8a255df9a1f53184de98cf332362199bbba Mon Sep 17 00:00:00 2001 From: Jen-Tse Huang Date: Wed, 25 Mar 2026 18:47:12 +0100 Subject: [PATCH 4/6] Update numbers in RteChkTest --- libs/rtemodel/test/src/RteChkTest.cpp | 6 +++--- .../ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc | 9 +-------- .../ExternalGenerator/test-url/test-url.cproject.yml | 5 ----- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/libs/rtemodel/test/src/RteChkTest.cpp b/libs/rtemodel/test/src/RteChkTest.cpp index 388813725..886bd60a1 100644 --- a/libs/rtemodel/test/src/RteChkTest.cpp +++ b/libs/rtemodel/test/src/RteChkTest.cpp @@ -30,9 +30,9 @@ Generic: 4\n\ DFP: 3\n\ BSP: 1\n\ \n\ -Components: 60\n\ +Components: 61\n\ From generic packs: 36\n\ -From DFP: 24\n\ +From DFP: 25\n\ From BSP: 0\n\ \n\ Devices: 10\n\ @@ -51,7 +51,7 @@ completed\n"; int res = rteChk.RunCheckRte(); EXPECT_EQ(res, 0); EXPECT_EQ(rteChk.GetPackCount(), 8); - EXPECT_EQ(rteChk.GetComponentCount(), 60); + EXPECT_EQ(rteChk.GetComponentCount(), 61); EXPECT_EQ(rteChk.GetDeviceCount(), 10); EXPECT_EQ(rteChk.GetBoardCount(), 15); diff --git a/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc b/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc index 45f18e7b4..207ee9af0 100644 --- a/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc +++ b/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc @@ -195,14 +195,7 @@ - Component addressing external with exit code 1 - - - - - - - + Component addressing external without URL Component with overlaping file lists diff --git a/tools/projmgr/test/data/ExternalGenerator/test-url/test-url.cproject.yml b/tools/projmgr/test/data/ExternalGenerator/test-url/test-url.cproject.yml index f4c5bc861..dfb54cc4d 100644 --- a/tools/projmgr/test/data/ExternalGenerator/test-url/test-url.cproject.yml +++ b/tools/projmgr/test/data/ExternalGenerator/test-url/test-url.cproject.yml @@ -4,11 +4,6 @@ project: components: - component: RteTestGeneratorNoUrl:Check Global Generator - groups: - - group: sources - files: - - file: main.c - generators: options: - generator: RteTestExternalGeneratorNoUrl From 9fb87b59b876a510d3ebca8c344de0b246497a58 Mon Sep 17 00:00:00 2001 From: Jen-Tse Huang Date: Thu, 26 Mar 2026 12:19:44 +0100 Subject: [PATCH 5/6] Add suggestions --- .../0.1.0/ARM.RteTestGenerator.pdsc | 4 ++-- tools/projmgr/src/ProjMgrWorker.cpp | 13 +++++++------ tools/projmgr/test/src/ProjMgrUnitTests.cpp | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc b/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc index 207ee9af0..1154b0957 100644 --- a/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc +++ b/test/packs/ARM/RteTestGenerator/0.1.0/ARM.RteTestGenerator.pdsc @@ -185,7 +185,7 @@ Configuration via RteTest script - Component addressing external + Component addressing external generator @@ -195,7 +195,7 @@ - Component addressing external without URL + Component addressing external generator without URL Component with overlaping file lists diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index d7f77ffc8..fb34241e1 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -5651,20 +5651,21 @@ bool ProjMgrWorker::ExecuteExtGenerator(std::string& generatorId) { StrIntPair result = CrossPlatformUtils::ExecCommand(runCmd); fs::current_path(workingDir, ec); if (result.second) { - ProjMgrLogger::Get().Error("executing generator '" + generatorId + "' for context '" + selectedContextId + "' failed"); - ProjMgrLogger::Get().Info("generator '" + generatorId + "' for context '" + selectedContextId + "' reported:\n" + result.first); - + string errMsg = "executing generator '" + generatorId + "' for context '" + selectedContextId + "' failed:\n"; + errMsg += " " + result.first; + const string downloadUrl = m_extGenerator->GetGlobalGenUrl(generatorId); if (!downloadUrl.empty()) { - ProjMgrLogger::Get().Error("check the URL for downloading the generator: " + downloadUrl); + errMsg += " check the URL for downloading the generator: " + downloadUrl; } else { - ProjMgrLogger::Get().Error("download URL is not available for generator '" + generatorId + "' in generator.yml"); + errMsg += " download URL is not available for generator '" + generatorId + "' in generator.yml"; } + ProjMgrLogger::Get().Error(errMsg); return false; } - ProjMgrLogger::Get().Info("generator '" + generatorId + "' for context '" + selectedContextId + "' reported:\n" + result.first); + ProjMgrLogger::Get().Info("generator '" + generatorId + "' for context '" + selectedContextId + "' reported:\n " + result.first); return true; } diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index ad0149da8..437d16b4f 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -5722,7 +5722,7 @@ TEST_F(ProjMgrUnitTests, ExternalGenerator_PrintUrl) { argv[6] = (char*)"single-core.Debug+CM0"; EXPECT_EQ(1, RunProjMgr(7, argv, m_envp)); string errStr = streamRedirect.GetErrorString(); - string errExpected = "check the URL for downloading the generator: https://raw.githubusercontent.com/Open-CMSIS-Pack"; + string errExpected = " check the URL for downloading the generator: https://raw.githubusercontent.com/Open-CMSIS-Pack"; EXPECT_NE(string::npos, errStr.find(errExpected)); streamRedirect.ClearStringStreams(); @@ -5731,7 +5731,7 @@ TEST_F(ProjMgrUnitTests, ExternalGenerator_PrintUrl) { argv[6] = (char*)"test-url.Debug+CM0"; EXPECT_EQ(1, RunProjMgr(7, argv, m_envp)); errStr = streamRedirect.GetErrorString(); - errExpected = "download URL is not available for generator '" + string(argv[4]) + "' in generator.yml"; + errExpected = " download URL is not available for generator '" + string(argv[4]) + "' in generator.yml"; EXPECT_NE(string::npos, errStr.find(errExpected)); RteFsUtils::RemoveFile(dstGlobalGenerator); From 32f8c335af6bec595ea7d995fdb12e33d4da5a09 Mon Sep 17 00:00:00 2001 From: Jen-Tse Huang Date: Thu, 26 Mar 2026 14:06:14 +0100 Subject: [PATCH 6/6] Add suggestions 2 --- tools/projmgr/src/ProjMgrWorker.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index fb34241e1..d57494d07 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -5657,15 +5657,15 @@ bool ProjMgrWorker::ExecuteExtGenerator(std::string& generatorId) { const string downloadUrl = m_extGenerator->GetGlobalGenUrl(generatorId); if (!downloadUrl.empty()) { errMsg += " check the URL for downloading the generator: " + downloadUrl; - } - else { + } else { errMsg += " download URL is not available for generator '" + generatorId + "' in generator.yml"; } ProjMgrLogger::Get().Error(errMsg); return false; + } else { + ProjMgrLogger::Get().Info("generator '" + generatorId + "' for context '" + selectedContextId + "' reported:\n " + result.first); } - - ProjMgrLogger::Get().Info("generator '" + generatorId + "' for context '" + selectedContextId + "' reported:\n " + result.first); + return true; }