From a8143f3b02e8c08399dcfd8884616195d1d71386 Mon Sep 17 00:00:00 2001 From: Daniel Brondani Date: Thu, 16 Apr 2026 09:45:11 +0200 Subject: [PATCH] [projmgr] Accept listing same component multiple times in clayers --- tools/projmgr/include/ProjMgrWorker.h | 3 ++- tools/projmgr/src/ProjMgrWorker.cpp | 9 +++++++-- tools/projmgr/test/src/ProjMgrUnitTests.cpp | 22 ++++++++++----------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/tools/projmgr/include/ProjMgrWorker.h b/tools/projmgr/include/ProjMgrWorker.h index 3aa897d1d..381a5a79c 100644 --- a/tools/projmgr/include/ProjMgrWorker.h +++ b/tools/projmgr/include/ProjMgrWorker.h @@ -1235,7 +1235,8 @@ class ProjMgrWorker { void AddMiscUniquely(MiscItem& dst, std::vector& srcVec); bool AddGroup(const GroupNode& src, std::vector& dst, ContextItem& context, const std::string root); bool AddFile(const FileNode& src, std::vector& dst, ContextItem& context, const std::string root); - bool AddComponent(const ComponentItem& src, const std::string& layer, std::vector>& dst, TypePair type, ContextItem& context); + bool AddComponent(const ComponentItem& src, const std::string& layer, std::vector>& dst, TypePair type, ContextItem& context, bool ignoreDuplicates = false); void GetDeviceItem(const std::string& element, DeviceItem& device) const; void GetBoardItem (const std::string& element, BoardItem& board) const; bool GetPrecedentValue(std::string& outValue, const std::string& element) const; diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 8f56bc090..04a678333 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -3525,7 +3525,7 @@ bool ProjMgrWorker::ProcessSequencesRelatives(ContextItem & context, bool rerun) if (!ProcessSequencesRelatives(context, component.build, clayer->directory)) { return false; } - if (!AddComponent(component, name, context.componentRequirements, context.type, context)) { + if (!AddComponent(component, name, context.componentRequirements, context.type, context, true)) { return false; } } @@ -3795,10 +3795,15 @@ bool ProjMgrWorker::AddFile(const FileNode& src, vector& dst, ContextI return true; } -bool ProjMgrWorker::AddComponent(const ComponentItem& src, const string& layer, vector>& dst, TypePair type, ContextItem& context) { +bool ProjMgrWorker::AddComponent(const ComponentItem& src, const string& layer, vector>& dst, + TypePair type, ContextItem& context, bool ignoreDuplicates) { if (CheckContextFilters(src.type, context)) { for (auto& [dstNode, layer] : dst) { if (dstNode.component == src.component) { + if (ignoreDuplicates) { + ProjMgrLogger::Get().Warn("ignoring conflict: component '" + dstNode.component + "' is listed multiple times", context.name); + return true; + } ProjMgrLogger::Get().Error("conflict: component '" + dstNode.component + "' is listed multiple times", context.name); return false; } diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index d86e090a9..fff6854c3 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -7529,19 +7529,17 @@ TEST_F(ProjMgrUnitTests, DuplicateComponents) { argv[4] = (char*)"-o"; argv[5] = (char*)testoutput_folder.c_str(); argv[6] = (char*)"--context"; + argv[7] = (char*)"duplicateComponents_cproject"; argv[8] = (char*)"--no-check-schema"; - - const char* contexts[] = { "duplicateComponents_cproject", "duplicateComponents_clayer" }; - int argCounts[] = { 8, 9 }; // without/with --no-check-schema - for (int argCount : argCounts) { - for (const char* context : contexts) { - argv[7] = (char*)context; - EXPECT_EQ(1, RunProjMgr(argCount, argv, m_envp)); - auto errStr = streamRedirect.GetErrorString(); - EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times")); - streamRedirect.ClearStringStreams(); - } - } + EXPECT_EQ(1, RunProjMgr(9, argv, m_envp)); + auto errStr = streamRedirect.GetErrorString(); + EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times")); + + streamRedirect.ClearStringStreams(); + argv[7] = (char*)"duplicateComponents_clayer"; + EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + errStr = streamRedirect.GetErrorString(); + EXPECT_NE(string::npos, errStr.find("warning csolution: ignoring conflict: component 'RteTest:CORE' is listed multiple times")); } TEST_F(ProjMgrUnitTests, ParseCommandLine_MutualExclusionOptions) {