From 985a5450c9b0bf546ae69750fe0bc75290b94d09 Mon Sep 17 00:00:00 2001 From: Daniel Brondani Date: Thu, 8 Jan 2026 11:48:54 +0100 Subject: [PATCH] [projmgr] Improve errors/warnings around component validation (#1384) --- tools/projmgr/include/ProjMgrWorker.h | 4 +++- tools/projmgr/src/ProjMgrWorker.cpp | 18 +++++++----------- tools/projmgr/test/src/ProjMgrRpcTests.cpp | 4 ++-- tools/projmgr/test/src/ProjMgrUnitTests.cpp | 16 ++++++++-------- .../test/src/ProjMgrWorkerUnitTests.cpp | 6 +++--- 5 files changed, 23 insertions(+), 25 deletions(-) diff --git a/tools/projmgr/include/ProjMgrWorker.h b/tools/projmgr/include/ProjMgrWorker.h index 27c52b495..83f2f98d6 100644 --- a/tools/projmgr/include/ProjMgrWorker.h +++ b/tools/projmgr/include/ProjMgrWorker.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2025 Arm Limited. All rights reserved. + * Copyright (c) 2020-2026 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -479,6 +479,7 @@ struct VariablesConfiguration { * west options * west on flag * layer variables configurations + * unresolved components */ struct ContextItem { CdefaultItem* cdefault = nullptr; @@ -551,6 +552,7 @@ struct ContextItem { WestDesc west; bool westOn = false; std::vector variablesConfigurations; + std::set unresolvedComponents; }; /** diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 2239f4999..f5fb24e9f 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2025 Arm Limited. All rights reserved. + * Copyright (c) 2020-2026 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -1906,7 +1906,7 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) { RteComponent* matchedComponent = matchedComponentInstance->GetComponent(); if (!matchedComponent) { // No match - ProjMgrLogger::Get().Error("no component was found with identifier '" + item.component + "'" + + ProjMgrLogger::Get().Error("component '" + item.component + "' not found in included packs" + (!hint.empty() ? "\n did you mean '" + hint + "'?" : ""), context.name); error = true; if(!m_rpcMode) { @@ -2168,14 +2168,9 @@ bool ProjMgrWorker::AddRequiredComponents(ContextItem& context) { for (auto& [_, component] : context.components) { selItems.push_back(component.instance); } - set unresolvedComponents; - context.rteActiveProject->AddCprjComponents(selItems, context.rteActiveTarget, unresolvedComponents); - if (!unresolvedComponents.empty()) { - string msg = "unresolved components:"; - for (const auto& component : unresolvedComponents) { - msg += "\n" + component->GetComponentID(true); - } - ProjMgrLogger::Get().Error(msg, context.name); + context.rteActiveProject->AddCprjComponents(selItems, context.rteActiveTarget, context.unresolvedComponents); + if (!context.unresolvedComponents.empty()) { + // unresolved components error messages are previously sent during component processing return false; } return true; @@ -3967,7 +3962,8 @@ bool ProjMgrWorker::ProcessContext(ContextItem& context, bool loadGenFiles, bool // TODO: Add uniquely identified missing dependencies to RTE Model // Get dependency validation results - if (ValidateContext(context) < RteItem::ConditionResult::FULFILLED ) { + if (ValidateContext(context) < RteItem::ConditionResult::FULFILLED + && context.unresolvedComponents.empty()) { string msg = "dependency validation for context '" + context.name + "' failed:"; set results; FormatValidationResults(results, context); diff --git a/tools/projmgr/test/src/ProjMgrRpcTests.cpp b/tools/projmgr/test/src/ProjMgrRpcTests.cpp index d5387f4d1..3383f8581 100644 --- a/tools/projmgr/test/src/ProjMgrRpcTests.cpp +++ b/tools/projmgr/test/src/ProjMgrRpcTests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2025 Arm Limited. All rights reserved. + * Copyright (c) 2020-2026 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -453,7 +453,7 @@ TEST_F(ProjMgrRpcTests, RpcLoadSolution_UnknownComponent) { const auto& responses = RunRpcMethods(requests); EXPECT_TRUE(responses[0]["result"]["success"]); EXPECT_TRUE(responses[1]["result"]["success"]); - EXPECT_EQ("no component was found with identifier 'ARM::UNKNOWN:COMPONENT'", + EXPECT_EQ("component 'ARM::UNKNOWN:COMPONENT' not found in included packs", responses[2]["result"]["errors"][0]); } diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 769fb7987..67aa2aa8e 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2025 Arm Limited. All rights reserved. + * Copyright (c) 2020-2026 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -1341,7 +1341,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFindUnspecifiedPackUsingLoad streamRedirect.ClearStringStreams(); EXPECT_EQ(1, RunProjMgr(9, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); - EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: no component was found with identifier 'RteTest:ComponentLevel'"), string::npos); + EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: component 'RteTest:ComponentLevel' not found in included packs"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRequiredUpdated, cbuildPack); // Test with --load required and with cbuild-pack.yml file @@ -1350,7 +1350,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFindUnspecifiedPackUsingLoad streamRedirect.ClearStringStreams(); EXPECT_EQ(1, RunProjMgr(9, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file is already up-to-date"), string::npos); - EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: no component was found with identifier 'RteTest:ComponentLevel'"), string::npos); + EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: component 'RteTest:ComponentLevel' not found in included packs"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRequired, cbuildPack); // Test without --load and without cbuild-pack.yml file @@ -1358,7 +1358,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFindUnspecifiedPackUsingLoad streamRedirect.ClearStringStreams(); EXPECT_EQ(1, RunProjMgr(7, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); - EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: no component was found with identifier 'RteTest:ComponentLevel'"), string::npos); + EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: component 'RteTest:ComponentLevel' not found in included packs"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRequiredUpdated, cbuildPack); // Test without --load but with cbuild-pack.yml file @@ -1366,7 +1366,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFindUnspecifiedPackUsingLoad streamRedirect.ClearStringStreams(); EXPECT_EQ(1, RunProjMgr(7, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file is already up-to-date"), string::npos); - EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: no component was found with identifier 'RteTest:ComponentLevel'"), string::npos); + EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: component 'RteTest:ComponentLevel' not found in included packs"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRequired, cbuildPack); } @@ -4056,7 +4056,7 @@ TEST_F(ProjMgrUnitTests, Convert_ValidationResults_Filtering) { {"recursive", 1, "\ warning csolution: RTE Model reports:\n\ ARM::RteTestRecursive@0.1.0: condition 'Recursive': error #503: direct or indirect recursion detected\n\ -error csolution: no component was found with identifier 'RteTest:Check:Recursive'\n"}, +error csolution: component 'RteTest:Check:Recursive' not found in included packs\n"}, {"missing-condition", 0, "\ warning csolution: RTE Model reports:\n\ ARM::RteTestMissingCondition@0.1.0: component 'ARM::RteTest:Check:MissingCondition@0.9.9(MissingCondition)[]': error #501: error(s) in component definition:\n\ @@ -4081,7 +4081,7 @@ TEST_F(ProjMgrUnitTests, Convert_ValidationResults_Quiet_Mode) { argv[2] = (char*)"--solution"; argv[4] = (char*)"-c"; - string expectedMsg = "error csolution: no component was found with identifier 'RteTest:Check:Recursive'\nerror csolution: processing context 'recursive+CM0' failed\n"; + string expectedMsg = "error csolution: component 'RteTest:Check:Recursive' not found in included packs\nerror csolution: processing context 'recursive+CM0' failed\n"; StdStreamRedirect streamRedirect; const string& csolution = testinput_folder + "/Validation/recursive.csolution.yml"; @@ -5621,7 +5621,7 @@ TEST_F(ProjMgrUnitTests, ExternalGenerator_WrongGeneratedData) { argv[4] = (char*)"wrong.WrongComponent+CM0"; EXPECT_EQ(1, RunProjMgr(5, argv, 0)); errStr = streamRedirect.GetErrorString(); - EXPECT_TRUE(errStr.find("error csolution: no component was found with identifier 'UnknownVendor:UnknownComponent'") != string::npos); + EXPECT_TRUE(errStr.find("error csolution: component 'UnknownVendor:UnknownComponent' not found in included packs") != string::npos); streamRedirect.ClearStringStreams(); argv[4] = (char*)"wrong.WrongGroup+CM0"; diff --git a/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp b/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp index febd5fef6..ce943d5e3 100644 --- a/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2025 Arm Limited. All rights reserved. + * Copyright (c) 2020-2026 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -469,8 +469,8 @@ TEST_F(ProjMgrWorkerUnitTests, ProcessComponents_Csub) { EXPECT_TRUE(context.components.find("ARM::Board:Test:Rev1@1.1.1") != context.components.end()); auto errorMap = ProjMgrLogger::Get().GetErrors(); - EXPECT_EQ("no component was found with identifier 'Board:Test'\n did you mean 'Board:Test:Rev1'?", errorMap["test_component_csub"][0]); - EXPECT_EQ("no component was found with identifier 'Device:Startup'\n did you mean 'Device:Startup&RteTest Startup'?", + EXPECT_EQ("component 'Board:Test' not found in included packs\n did you mean 'Board:Test:Rev1'?", errorMap["test_component_csub"][0]); + EXPECT_EQ("component 'Device:Startup' not found in included packs\n did you mean 'Device:Startup&RteTest Startup'?", errorMap["test_component_csub"][1]); }