From ec4eef0254f277444e2e4e17907eabfdf11e4e71 Mon Sep 17 00:00:00 2001 From: Evgueni Driouk Date: Wed, 16 Sep 2026 14:17:51 +0200 Subject: [PATCH 1/4] Improve component selection diagnostic output --- libs/rtemodel/include/RteCondition.h | 3 ++- libs/rtemodel/src/RteCondition.cpp | 28 ++++++++++---------- tools/projmgr/include/ProjMgrWorker.h | 4 +-- tools/projmgr/src/ProjMgrRpcServer.cpp | 6 +++-- tools/projmgr/src/ProjMgrWorker.cpp | 12 ++++----- tools/projmgr/test/src/ProjMgrUnitTests.cpp | 29 ++++++++++++--------- 6 files changed, 44 insertions(+), 38 deletions(-) diff --git a/libs/rtemodel/include/RteCondition.h b/libs/rtemodel/include/RteCondition.h index e533d4897..555ed729b 100644 --- a/libs/rtemodel/include/RteCondition.h +++ b/libs/rtemodel/include/RteCondition.h @@ -540,9 +540,10 @@ class RteDependencyResult /** * @brief gets explanation text for available/incompatible selection * @param res RteItem::ConditionResult + * @param description aggregate description * @return explanation text or empty string */ - static std::string GetAggregateExplanationText(RteItem::ConditionResult res); + static std::string GetAggregateExplanationText(RteItem::ConditionResult res, const std::string& description); public: /** diff --git a/libs/rtemodel/src/RteCondition.cpp b/libs/rtemodel/src/RteCondition.cpp index fda306406..df500165d 100644 --- a/libs/rtemodel/src/RteCondition.cpp +++ b/libs/rtemodel/src/RteCondition.cpp @@ -620,7 +620,7 @@ std::string RteDependencyResult::GetComponentExplanationText(RteItem::ConditionR string message; switch(res) { case RteItem::CONFLICT: - message = "Conflict, select exactly one of available matches"; + message = "Conflict, select exactly one"; break; case RteItem::INSTALLED: case RteItem::SELECTABLE: @@ -632,7 +632,7 @@ std::string RteDependencyResult::GetComponentExplanationText(RteItem::ConditionR case RteItem::INCOMPATIBLE: case RteItem::INCOMPATIBLE_VERSION: case RteItem::INCOMPATIBLE_VARIANT: - message = "Incompatible dependency selection"; + message = "Incompatible dependency"; break; default: @@ -647,10 +647,10 @@ std::string RteDependencyResult::GetExpressionExplanationText(RteItem::Condition string message; switch(res) { case RteItem::INSTALLED: - message = "Select bundle and component from list"; + message = "Select bundle and component"; break; case RteItem::SELECTABLE: - message = "Select component from list"; + message = "Select a component"; break; case RteItem::MISSING: message = "Install missing component"; @@ -668,16 +668,16 @@ std::string RteDependencyResult::GetExpressionExplanationText(RteItem::Condition message = "Install required API version"; break; case RteItem::CONFLICT: - message = "Conflict, select exactly one component from list"; + message = "Conflict, select exactly one:"; break; case RteItem::INCOMPATIBLE: - message = "Select compatible component"; + message = "Select a compatible component"; break; case RteItem::INCOMPATIBLE_VERSION: - message = "Select compatible component version"; + message = "Select a compatible version"; break; case RteItem::INCOMPATIBLE_VARIANT: - message = "Select compatible component variant"; + message = "Select a compatible variant"; break; default: break; @@ -685,24 +685,24 @@ std::string RteDependencyResult::GetExpressionExplanationText(RteItem::Condition return message; } -std::string RteDependencyResult::GetAggregateExplanationText(RteItem::ConditionResult res) +std::string RteDependencyResult::GetAggregateExplanationText(RteItem::ConditionResult res, const string& description) { string message; switch(res) { case RteItem::CONFLICT: - message = "conflicted selection"; + message = description; break; case RteItem::SELECTABLE: - message = "available selection"; + message = description; break; case RteItem::INCOMPATIBLE: - message = "incompatible selection"; + message = "incompatible"; break; case RteItem::INCOMPATIBLE_VERSION: - message = "incompatible version selection"; + message = "incompatible version"; break; case RteItem::INCOMPATIBLE_VARIANT: - message = "incompatible variant selection"; + message = "incompatible variant"; break; default: break; diff --git a/tools/projmgr/include/ProjMgrWorker.h b/tools/projmgr/include/ProjMgrWorker.h index 8c3501284..69e65dc99 100644 --- a/tools/projmgr/include/ProjMgrWorker.h +++ b/tools/projmgr/include/ProjMgrWorker.h @@ -281,7 +281,7 @@ struct ContextTypesItem { struct ValidationCondition { RteItem::ConditionResult result; std::string expression; - StrSet aggregates; + StrMap aggregates; }; /** @@ -295,7 +295,7 @@ struct ValidationCondition { struct ValidationResult { RteItem::ConditionResult result; std::string id; - StrSet aggregates; + StrMap aggregates; std::vector conditions; }; diff --git a/tools/projmgr/src/ProjMgrRpcServer.cpp b/tools/projmgr/src/ProjMgrRpcServer.cpp index dd8b42f26..29a15abc2 100644 --- a/tools/projmgr/src/ProjMgrRpcServer.cpp +++ b/tools/projmgr/src/ProjMgrRpcServer.cpp @@ -739,7 +739,8 @@ RpcArgs::Results RpcHandler::ValidateComponents(const string& context) { r.result = RteItem::ConditionResultToString(validation.result); r.id = validation.id; if(!validation.aggregates.empty()) { - r.aggregates = vector(validation.aggregates.begin(), validation.aggregates.end()); + auto aggrehateIds = key_set(validation.aggregates); + r.aggregates = vector(aggrehateIds.begin(), aggrehateIds.end()); } if(!validation.conditions.empty()) { RpcArgs::Condition c; @@ -748,7 +749,8 @@ RpcArgs::Results RpcHandler::ValidateComponents(const string& context) { c.expression = condition.expression; c.result = RteItem::ConditionResultToString(condition.result); if(!condition.aggregates.empty()) { - c.aggregates = vector(condition.aggregates.begin(), condition.aggregates.end()); + auto aggrehateIds = key_set(condition.aggregates); + c.aggregates = vector(aggrehateIds.begin(), aggrehateIds.end()); } r.conditions->push_back(c); } diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index b584ac967..1c3a04347 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -2857,7 +2857,7 @@ RteItem::ConditionResult ProjMgrWorker::ValidateContext(ContextItem& context) { validation.id = item->ConstructComponentID(true); for (const auto& aggregate : componentResult.GetComponentAggregates()) { - validation.aggregates.insert(aggregate->ConstructComponentID(true)); + validation.aggregates.emplace(aggregate->ConstructComponentID(true), aggregate->GetDescription()); } const auto& depResults = componentResult.GetResults(); @@ -2870,7 +2870,7 @@ RteItem::ConditionResult ProjMgrWorker::ValidateContext(ContextItem& context) { condition.result = conditionRes; condition.expression = item->GetDependencyExpressionID(); for (const auto& aggregate : result.GetComponentAggregates()) { - condition.aggregates.insert(aggregate->ConstructComponentID(true)); + condition.aggregates.emplace(aggregate->ConstructComponentID(true), aggregate->GetDescription()); } validation.conditions.push_back(condition); } @@ -4801,11 +4801,11 @@ bool ProjMgrWorker::ListTemplates(vector& templates, const string& filte return true; } -static string FormatAggregates(RteItem::ConditionResult result, const StrSet& aggregates, unsigned indent) { +static string FormatAggregates(RteItem::ConditionResult result, const StrMap& aggregates, unsigned indent) { stringstream ss; - for(const auto& id : aggregates) { + for(const auto& [id, desc] : aggregates) { ss << endl << RteUtils::GetIndent(indent); - ss << "- component " << id << " - " << RteDependencyResult::GetAggregateExplanationText(result); + ss << "- component " << id << " # " << RteDependencyResult::GetAggregateExplanationText(result, desc); } return ss.str(); } @@ -4822,7 +4822,7 @@ bool ProjMgrWorker::FormatValidationResults(set& results, const ContextI ss << validation.id << " : " << RteDependencyResult::GetComponentExplanationText(validation.result); for(const auto& condition : validation.conditions) { - ss << "\n failed '" << condition.expression << "' : " << RteDependencyResult::GetExpressionExplanationText(condition.result); + ss << "\n " << condition.expression << " : " << RteDependencyResult::GetExpressionExplanationText(condition.result); ss << FormatAggregates(condition.result, condition.aggregates, 4); } ss << FormatAggregates(validation.result, validation.aggregates, 2); // API aggregates diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 33c900454..70da9deab 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -4282,24 +4282,24 @@ TEST_F(ProjMgrUnitTests, Convert_ValidationResults_Dependencies) { map testData = { {"conflict+CM0", "warning csolution: dependency validation for context 'conflict+CM0' failed:\n\ -API RteTest:ApiExclusive@1.0.0 : Conflict, select exactly one of available matches\n\ - - component ARM::RteTest:ApiExclusive:S1 - conflicted selection\n\ - - component ARM::RteTest:ApiExclusive:S2 - conflicted selection" }, +API RteTest:ApiExclusive@1.0.0 : Conflict, select exactly one\n\ + - component ARM::RteTest:ApiExclusive:S1 # RteTest Exclusive API component S1\n\ + - component ARM::RteTest:ApiExclusive:S2 # RteTest Exclusive API component S2\n" }, {"incompatible+CM0", "warning csolution: dependency validation for context 'incompatible+CM0' failed:\n\ -component ARM::RteTest:Check:Incompatible@0.9.9 : Incompatible dependency selection\n\ - failed 'deny RteTest:Dependency:Incompatible_component' : Select compatible component\n\ - - component ARM::RteTest:Dependency:Incompatible_component - incompatible selection" }, +component ARM::RteTest:Check:Incompatible@0.9.9 : Incompatible dependency\n\ + deny RteTest:Dependency:Incompatible_component : Select a compatible component\n\ + - component ARM::RteTest:Dependency:Incompatible_component # incompatible\n" }, {"incompatible-variant+CM0", "warning csolution: dependency validation for context 'incompatible-variant+CM0' failed:\n\ -component ARM::RteTest:Check:IncompatibleVariant@0.9.9 : Incompatible dependency selection\n\ - failed 'require RteTest:Dependency:Variant&Compatible' : Select compatible component variant\n\ - - component ARM::RteTest:Dependency:Variant - incompatible variant selection" }, +component ARM::RteTest:Check:IncompatibleVariant@0.9.9 : Incompatible dependency\n\ + require RteTest:Dependency:Variant&Compatible : Select a compatible variant\n\ + - component ARM::RteTest:Dependency:Variant # incompatible variant\n" }, {"missing+CM0", "warning csolution: dependency validation for context 'missing+CM0' failed:\n\ component ARM::RteTest:Check:Missing@0.9.9 : Unresolved dependencies\n\ - failed 'require RteTest:Dependency:Missing' : Install missing component" }, + require RteTest:Dependency:Missing : Install missing component\n" }, {"selectable+CM0", "warning csolution: dependency validation for context 'selectable+CM0' failed:\n\ component ARM::Device:Startup&RteTest Startup@2.0.3 : Unresolved dependencies\n\ - failed 'require RteTest:CORE' : Select component from list\n\ - - component ARM::RteTest:CORE - available selection" } + require RteTest:CORE : Select a component\n\ + - component ARM::RteTest:CORE # RteTest CORE component for Cortex-M\n" } }; for (const auto& [context, expected] : testData) { @@ -4308,7 +4308,10 @@ component ARM::Device:Startup&RteTest Startup@2.0.3 : Unresolved dependencies\n\ argv[6] = (char*)context.c_str(); EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); auto errorStr = streamRedirect.GetErrorString(); - EXPECT_NE(string::npos, errorStr.find(expected)); + auto pos = errorStr.find("warning csolution: dependency validation"); + EXPECT_NE(string::npos, pos); + auto s = errorStr.substr(pos); + EXPECT_EQ(s, expected); } } From 015c08fba4b84d214ee10161a20f4c64e43ff03a Mon Sep 17 00:00:00 2001 From: Evgueni Driouk Date: Wed, 16 Sep 2026 14:45:02 +0200 Subject: [PATCH 2/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tools/projmgr/src/ProjMgrRpcServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/projmgr/src/ProjMgrRpcServer.cpp b/tools/projmgr/src/ProjMgrRpcServer.cpp index 29a15abc2..cf85682f2 100644 --- a/tools/projmgr/src/ProjMgrRpcServer.cpp +++ b/tools/projmgr/src/ProjMgrRpcServer.cpp @@ -739,7 +739,7 @@ RpcArgs::Results RpcHandler::ValidateComponents(const string& context) { r.result = RteItem::ConditionResultToString(validation.result); r.id = validation.id; if(!validation.aggregates.empty()) { - auto aggrehateIds = key_set(validation.aggregates); + auto aggregateIds = key_set(validation.aggregates); r.aggregates = vector(aggrehateIds.begin(), aggrehateIds.end()); } if(!validation.conditions.empty()) { From 320f7f02ba791311c5f35bfeafbb87c30ac03305 Mon Sep 17 00:00:00 2001 From: Evgueni Driouk Date: Wed, 16 Sep 2026 14:45:17 +0200 Subject: [PATCH 3/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tools/projmgr/src/ProjMgrWorker.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/projmgr/src/ProjMgrWorker.cpp b/tools/projmgr/src/ProjMgrWorker.cpp index 1c3a04347..7d570ebdb 100644 --- a/tools/projmgr/src/ProjMgrWorker.cpp +++ b/tools/projmgr/src/ProjMgrWorker.cpp @@ -4805,7 +4805,11 @@ static string FormatAggregates(RteItem::ConditionResult result, const StrMap& ag stringstream ss; for(const auto& [id, desc] : aggregates) { ss << endl << RteUtils::GetIndent(indent); - ss << "- component " << id << " # " << RteDependencyResult::GetAggregateExplanationText(result, desc); + auto explanation = RteDependencyResult::GetAggregateExplanationText(result, desc); + ss << "- component " << id; + if (!explanation.empty()) { + ss << " # " << explanation; + } } return ss.str(); } From 584cf3aa2e2c64b66f163d8b48f475860cf41297 Mon Sep 17 00:00:00 2001 From: Evgueni Driouk Date: Wed, 16 Sep 2026 14:54:39 +0200 Subject: [PATCH 4/4] Variable spelling --- tools/projmgr/src/ProjMgrRpcServer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/projmgr/src/ProjMgrRpcServer.cpp b/tools/projmgr/src/ProjMgrRpcServer.cpp index cf85682f2..430672508 100644 --- a/tools/projmgr/src/ProjMgrRpcServer.cpp +++ b/tools/projmgr/src/ProjMgrRpcServer.cpp @@ -740,7 +740,7 @@ RpcArgs::Results RpcHandler::ValidateComponents(const string& context) { r.id = validation.id; if(!validation.aggregates.empty()) { auto aggregateIds = key_set(validation.aggregates); - r.aggregates = vector(aggrehateIds.begin(), aggrehateIds.end()); + r.aggregates = vector(aggregateIds.begin(), aggregateIds.end()); } if(!validation.conditions.empty()) { RpcArgs::Condition c; @@ -749,8 +749,8 @@ RpcArgs::Results RpcHandler::ValidateComponents(const string& context) { c.expression = condition.expression; c.result = RteItem::ConditionResultToString(condition.result); if(!condition.aggregates.empty()) { - auto aggrehateIds = key_set(condition.aggregates); - c.aggregates = vector(aggrehateIds.begin(), aggrehateIds.end()); + auto aggregateIds = key_set(condition.aggregates); + c.aggregates = vector(aggregateIds.begin(), aggregateIds.end()); } r.conditions->push_back(c); }