Skip to content

Commit 79cc827

Browse files
committed
Validate component Cbundle conflicts (ignore Cvendor)
1 parent 447b1e5 commit 79cc827

8 files changed

Lines changed: 183 additions & 33 deletions

File tree

test/local_packs/S/SomeVendor.RteTest.pdsc

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
</packages>
2222
</requirements>
2323

24+
<conditions>
25+
<condition id="Require_G0">
26+
<require Cclass="RteTestBundle" Cgroup="G0"/>
27+
</condition>
28+
</conditions>
29+
2430
<components>
2531

2632
<component Cclass="RteTest" Cgroup="LocalFile" Cversion="0.0.3">
@@ -30,6 +36,54 @@
3036
<file category="sourceC" name="PreInclude/MyLocalPreInclude.c" />
3137
</files>
3238
</component>
39+
40+
<bundle Cbundle="BundleOne" Cclass="RteTestBundle" Cversion="1.1.0" Cvendor="SomeVendor" isDefaultVariant="1" licenseSet="TestPropLicense">
41+
<description>Test bundle one</description>
42+
<doc>https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html#Component_Bundle</doc>
43+
<component Cgroup="G0" Cversion="1.0.0" >
44+
<description>Bundle One, component G0, version differs from bundle</description>
45+
<files>
46+
<file category="doc" name="https://arm-software.github.io/CMSIS_5/Pack/html/cp_PackTutorial.html"/>
47+
</files>
48+
</component>
49+
<component Cgroup="G1">
50+
<description>Bundle One, component G1, only in bundle 1</description>
51+
<files>
52+
<file category="doc" name="https://arm-software.github.io/CMSIS_5/Pack/html/createPackUtil.html"/>
53+
</files>
54+
</component>
55+
<component Cgroup="G2" condition="Require_G0">
56+
<description>Bundle One, component G2</description>
57+
<files>
58+
<file category="doc" name="https://arm-software.github.io/CMSIS_5/Pack/html/createPackUtil.html"/>
59+
</files>
60+
</component>
61+
</bundle>
62+
63+
<bundle Cbundle="BundleTwo" Cclass="RteTestBundle" Cversion="1.2.0" Cvendor="SomeVendor">
64+
<description>Test bundle two</description>
65+
<doc>https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html#element_bundle</doc>
66+
<component Cgroup="G0" Cversion="2.0.0" >
67+
<description>Bundle Two, component G, version differs from bundle</description>
68+
<files>
69+
<file category="doc" name="https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_conditions_pg.html"/>
70+
</files>
71+
</component>
72+
<component Cgroup="G2" condition="Require_G0">
73+
<description>Bundle Two, component G2</description>
74+
<files>
75+
<file category="doc" name="https://arm-software.github.io/CMSIS_5/Pack/html/createPackUtil.html"/>
76+
</files>
77+
</component>
78+
</bundle>
79+
80+
<component Cclass="RteTestBundle" Cgroup="G0" Cversion="0.9.0">
81+
<description>Component G without bundle, but the same class and group as in bundle</description>
82+
<files>
83+
<file category="doc" name="https://arm-software.github.io/CMSIS_5/Pack/html/pdsc_components_pg.html"/>
84+
</files>
85+
</component>
86+
3387
</components>
3488

3589
</package>

tools/projmgr/src/ProjMgrWorker.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,6 +1907,7 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) {
19071907
}
19081908

19091909
map<string, vector<string>> processedComponents;
1910+
map<string, map<string, vector<string>>> processedBundles;
19101911
for (auto& [item, layer] : context.componentRequirements) {
19111912
if (item.component.empty()) {
19121913
continue;
@@ -1937,6 +1938,15 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) {
19371938
error = true;
19381939
}
19391940

1941+
string bundleId = matchedComponent->GetCbundleName();
1942+
string classId = matchedComponent->GetCclassName();
1943+
if (bundleId.empty()) { bundleId = "noBundle"; }
1944+
processedBundles[classId][bundleId].push_back(item.component);
1945+
if (processedBundles[classId].size() > 1) {
1946+
// multiple bundle of the same component found
1947+
error = true;
1948+
}
1949+
19401950
// Set layer's rtePath attribute
19411951
if (!layer.empty()) {
19421952
error_code ec;
@@ -2025,6 +2035,19 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) {
20252035
ProjMgrLogger::Get().Error(errMsg, context.name);
20262036
}
20272037
}
2038+
// check if same component bundles are specified multiple times (without considering Cvendor)
2039+
for (const auto& [_, bundleMap] : processedBundles) {
2040+
if (bundleMap.size() > 1) {
2041+
string errMsg = "components from multiple bundles are specified:";
2042+
for (const auto& [bundleId, components] : bundleMap) {
2043+
errMsg += "\n bundle '" + bundleId + "':";
2044+
for (const auto& comp : components) {
2045+
errMsg += "\n - " + comp;
2046+
}
2047+
}
2048+
ProjMgrLogger::Get().Error(errMsg, context.name);
2049+
}
2050+
}
20282051
}
20292052

20302053
// Add required components into RTE
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
project:
2+
components:
3+
- component: Startup
4+
- component: RteTest:CORE
5+
- component: ARM::RteTestBundle&BundleOne:G0
6+
- component: ARM::RteTestBundle&BundleOne:G1
7+
- component: SomeVendor::RteTestBundle&BundleOne:G0
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
project:
2+
components:
3+
- component: Startup
4+
- component: CORE
5+
- component: ARM::RteTestBundle&BundleOne:G0
6+
- component: ARM::RteTestBundle&BundleOne:G1
7+
- component: ARM::RteTestBundle&BundleTwo:G0
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
project:
2+
components:
3+
- component: Startup
4+
- component: CORE
5+
- component: ARM::RteTestBundle&BundleOne:G0
6+
- component: SomeVendor::RteTestBundle&BundleTwo:G0
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
project:
2+
components:
3+
- component: Startup
4+
- component: CORE
5+
- component: ARM::RteTestBundle&BundleOne:G0
6+
- component: SomeVendor::RteTestBundle:G0
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
solution:
2+
target-types:
3+
- type: CM0
4+
device: RteTest_ARMCM0
5+
target-set:
6+
- set:
7+
images:
8+
- project-context: testProject1.Debug
9+
10+
build-types:
11+
- type: Debug
12+
compiler: AC6
13+
14+
packs:
15+
- pack: ARM::RteTest
16+
- pack: ARM::RteTest_DFP@0.2.0
17+
- pack: SomeVendor::RteTest@0.0.1
18+
19+
projects:
20+
- project: ./TestProject1/testProject1.cproject.yml
21+
- project: ./TestProject2/testProject2.cproject.yml
22+
- project: ./TestProject3/testProject3.cproject.yml
23+
- project: ./TestProject4/testProject4.cproject.yml

tools/projmgr/test/src/ProjMgrUnitTests.cpp

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6461,6 +6461,41 @@ TEST_F(ProjMgrUnitTests, RunProjMgr_MultiVariantComponent) {
64616461
errMsg.find("multiple variants of the same component are specified:\n - Device:Test variant\n - Device:Test variant&Variant name"));
64626462
}
64636463

6464+
TEST_F(ProjMgrUnitTests, RunProjMgr_MultiBundleComponent) {
6465+
StdStreamRedirect streamRedirect;
6466+
char* argv[8];
6467+
string csolutionFile = testinput_folder + "/TestSolution/MultiBundleComponent/multiBundleComponent.csolution.yml";
6468+
argv[1] = (char*)"convert";
6469+
argv[2] = (char*)"--solution";
6470+
argv[3] = (char*)csolutionFile.c_str();
6471+
argv[4] = (char*)"-o";
6472+
argv[5] = (char*)testoutput_folder.c_str();
6473+
argv[6] = (char*)"--context";
6474+
6475+
// testProject1 - successed
6476+
argv[7] = (char*)"testProject1";
6477+
EXPECT_EQ(0, RunProjMgr(8, argv, m_envp));
6478+
auto errMsg = streamRedirect.GetErrorString();
6479+
EXPECT_EQ(string::npos, errMsg.find("components from multiple bundles are specified:"));
6480+
6481+
// testProject2, 3, 4 - failed
6482+
const char* failProjects[] = { "testProject2", "testProject3", "testProject4" };
6483+
const char* expectedComponents[][2] = {
6484+
{"ARM::RteTestBundle&BundleOne:G0", "ARM::RteTestBundle&BundleTwo:G0"},
6485+
{"ARM::RteTestBundle&BundleOne:G0", "SomeVendor::RteTestBundle&BundleTwo:G0"},
6486+
{"ARM::RteTestBundle&BundleOne:G0", "SomeVendor::RteTestBundle:G0"}
6487+
};
6488+
for (int i = 0; i < 3; i++) {
6489+
argv[7] = (char*)failProjects[i];
6490+
EXPECT_EQ(1, RunProjMgr(8, argv, m_envp));
6491+
errMsg = streamRedirect.GetErrorString();
6492+
EXPECT_NE(string::npos, errMsg.find("components from multiple bundles are specified:"));
6493+
EXPECT_NE(string::npos, errMsg.find(expectedComponents[i][0]));
6494+
EXPECT_NE(string::npos, errMsg.find(expectedComponents[i][1]));
6495+
streamRedirect.ClearStringStreams();
6496+
}
6497+
}
6498+
64646499
TEST_F(ProjMgrUnitTests, RunProjMgr_ListPacks_ContextSet) {
64656500
char* argv[6];
64666501
StdStreamRedirect streamRedirect;
@@ -7401,37 +7436,26 @@ TEST_F(ProjMgrUnitTests, TargetSetDependencies) {
74017436
}
74027437

74037438
TEST_F(ProjMgrUnitTests, DuplicateComponents) {
7404-
StdStreamRedirect streamRedirect;
7405-
7406-
const string csolution = testinput_folder + "/TestSolution/DuplicateComponents/duplicateComponents.csolution.yml";
7407-
7408-
char* argv[9];
7409-
argv[1] = (char*)"convert";
7410-
argv[2] = (char*)"--solution";
7411-
argv[3] = (char*)csolution.c_str();
7412-
argv[4] = (char*)"-o";
7413-
argv[5] = (char*)testoutput_folder.c_str();
7414-
argv[6] = (char*)"--context";
7415-
argv[7] = (char*)"duplicateComponents_cproject";
7416-
argv[8] = (char*)"--no-check-schema";
7417-
7418-
EXPECT_EQ(1, RunProjMgr(8, argv, m_envp));
7419-
auto errStr = streamRedirect.GetErrorString();
7420-
EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times"));
7421-
7422-
argv[7] = (char*)"duplicateComponents_clayer";
7423-
EXPECT_EQ(1, RunProjMgr(8, argv, m_envp));
7424-
errStr = streamRedirect.GetErrorString();
7425-
EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times"));
7426-
7427-
// Run with "--no-check-schema"
7428-
argv[7] = (char*)"duplicateComponents_cproject";
7429-
EXPECT_EQ(1, RunProjMgr(9, argv, m_envp));
7430-
errStr = streamRedirect.GetErrorString();
7431-
EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times"));
7432-
7433-
argv[7] = (char*)"duplicateComponents_clayer";
7434-
EXPECT_EQ(1, RunProjMgr(9, argv, m_envp));
7435-
errStr = streamRedirect.GetErrorString();
7436-
EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times"));
7439+
StdStreamRedirect streamRedirect;
7440+
const string csolution = testinput_folder + "/TestSolution/DuplicateComponents/duplicateComponents.csolution.yml";
7441+
char* argv[9];
7442+
argv[1] = (char*)"convert";
7443+
argv[2] = (char*)"--solution";
7444+
argv[3] = (char*)csolution.c_str();
7445+
argv[4] = (char*)"-o";
7446+
argv[5] = (char*)testoutput_folder.c_str();
7447+
argv[6] = (char*)"--context";
7448+
argv[8] = (char*)"--no-check-schema";
7449+
7450+
const char* contexts[] = { "duplicateComponents_cproject", "duplicateComponents_clayer" };
7451+
int argCounts[] = { 8, 9 }; // without/with --no-check-schema
7452+
for (int argCount : argCounts) {
7453+
for (const char* context : contexts) {
7454+
argv[7] = (char*)context;
7455+
EXPECT_EQ(1, RunProjMgr(argCount, argv, m_envp));
7456+
auto errStr = streamRedirect.GetErrorString();
7457+
EXPECT_NE(string::npos, errStr.find("error csolution: conflict: component 'RteTest:CORE' is listed multiple times"));
7458+
streamRedirect.ClearStringStreams();
7459+
}
7460+
}
74377461
}

0 commit comments

Comments
 (0)