Skip to content

Commit 0e66ee6

Browse files
authored
[projmgr] Add list examples command
1 parent 93e34d1 commit 0e66ee6

File tree

8 files changed

+347
-0
lines changed

8 files changed

+347
-0
lines changed

test/packs/ARM/RteTest/0.1.0/ARM.RteTest.pdsc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@
418418
</project>
419419
<attributes>
420420
<component Cclass="RteTest" Cgroup="GlobalLevel"/>
421+
<category>Example Project</category>
422+
<keyword>Getting Started</keyword>
421423
</attributes>
422424
</example>
423425
</examples>

tools/projmgr/include/ProjMgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ class ProjMgr {
192192
bool RunListComponents();
193193
bool RunListConfigs();
194194
bool RunListDependencies();
195+
bool RunListExamples();
195196
bool RunListContexts();
196197
bool RunListTargetSets();
197198
bool RunListGenerators();

tools/projmgr/include/ProjMgrWorker.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,42 @@ struct GdbServerItem {
279279
std::string pname;
280280
};
281281

282+
/**
283+
* @brief example environment item containing
284+
* project file with extension
285+
* subdirectory to be copied
286+
*/
287+
struct EnvironmentItem {
288+
std::string load;
289+
std::string folder;
290+
};
291+
292+
/**
293+
* @brief example item containing
294+
* name of example
295+
* description
296+
* documentation
297+
* version
298+
* archive
299+
* map of environments
300+
* list of compatible boards
301+
* list of components
302+
* list of categories
303+
* list of keywords
304+
*/
305+
struct ExampleItem {
306+
std::string name;
307+
std::string description;
308+
std::string doc;
309+
std::string version;
310+
std::string archive;
311+
std::map<std::string, EnvironmentItem> environments;
312+
std::vector<BoardItem> boards;
313+
std::vector<std::string> components;
314+
std::vector<std::string> categories;
315+
std::vector<std::string> keywords;
316+
};
317+
282318
/**
283319
* @brief debugger type
284320
* name of debug configuration
@@ -545,6 +581,14 @@ class ProjMgrWorker {
545581
*/
546582
bool ListDependencies(std::vector<std::string>& dependencies, const std::string& filter = RteUtils::EMPTY_STRING);
547583

584+
/**
585+
* @brief list available examples
586+
* @param reference to list of examples
587+
* @param filter words to filter results
588+
* @return true if executed successfully
589+
*/
590+
bool ListExamples(std::vector<std::string>& examples, const std::string& filter = RteUtils::EMPTY_STRING);
591+
548592
/**
549593
* @brief list contexts
550594
* @param reference to list of contexts
@@ -1099,6 +1143,9 @@ class ProjMgrWorker {
10991143
bool IsCreatedByExecute(const std::string file, const std::string dir);
11001144
bool CollectAllRequiredPdscFiles();
11011145
bool ParseTargetSetContextSelection();
1146+
std::vector<ExampleItem> CollectExamples(ContextItem& context);
1147+
std::vector<RteBoard*> GetCompatibleBoards(ContextItem& context);
1148+
bool IsBoardListCompatible(const std::vector<RteBoard*> compatibleBoards, const Collection<RteItem*>& boards);
11021149
};
11031150

11041151
#endif // PROJMGRWORKER_H

tools/projmgr/src/ProjMgr.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Commands:\n\
3030
list dependencies Print list of unresolved project dependencies\n\
3131
list devices Print list of available device names\n\
3232
list environment Print list of environment configurations\n\
33+
list examples Print list of examples\n\
3334
list generators Print list of code generators of a given context\n\
3435
list layers Print list of available, referenced and compatible layers\n\
3536
list packs Print list of used packs from the pack repository\n\
@@ -181,6 +182,7 @@ int ProjMgr::ParseCommandLine(int argc, char** argv) {
181182
{"list configs", { false, {context, contextSet, activeTargetSet, debug, filter, load, quiet, schemaCheck, toolchain, verbose}}},
182183
{"list components", { true, {context, contextSet, activeTargetSet, debug, filter, load, quiet, schemaCheck, toolchain, verbose}}},
183184
{"list dependencies", { false, {context, contextSet, activeTargetSet, debug, filter, load, quiet, schemaCheck, toolchain, verbose}}},
185+
{"list examples", { false, {context, contextSet, activeTargetSet, debug, filter, load, quiet, schemaCheck, toolchain, verbose}}},
184186
{"list contexts", { false, {debug, filter, quiet, schemaCheck, verbose, ymlOrder}}},
185187
{"list target-sets", { false, {debug, filter, quiet, schemaCheck, verbose}}},
186188
{"list generators", { false, {context, contextSet, activeTargetSet, debug, load, quiet, schemaCheck, toolchain, verbose}}},
@@ -370,6 +372,10 @@ int ProjMgr::ProcessCommands() {
370372
if (!RunListDependencies()) {
371373
return ErrorCode::ERROR;
372374
}
375+
} else if (m_args == "examples") {
376+
if (!RunListExamples()) {
377+
return ErrorCode::ERROR;
378+
}
373379
} else if (m_args == "contexts") {
374380
if (!RunListContexts()) {
375381
return ErrorCode::ERROR;
@@ -907,6 +913,31 @@ bool ProjMgr::RunListDependencies(void) {
907913
return true;
908914
}
909915

916+
bool ProjMgr::RunListExamples(void) {
917+
if (!m_csolutionFile.empty()) {
918+
// Parse all input files and create contexts
919+
if (!PopulateContexts()) {
920+
return false;
921+
}
922+
}
923+
924+
// Parse context selection
925+
if (!ParseAndValidateContexts()) {
926+
return false;
927+
}
928+
929+
vector<string> examples;
930+
if (!m_worker.ListExamples(examples, m_filter)) {
931+
ProjMgrLogger::Get().Error("processing examples list failed");
932+
return false;
933+
}
934+
935+
for (const auto& example : examples) {
936+
ProjMgrLogger::out() << example << endl;
937+
}
938+
return true;
939+
}
940+
910941
bool ProjMgr::RunListContexts(void) {
911942
// Parse all input files and create contexts
912943
if (!PopulateContexts()) {

tools/projmgr/src/ProjMgrWorker.cpp

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4187,6 +4187,167 @@ bool ProjMgrWorker::ListDependencies(vector<string>& dependencies, const string&
41874187
return true;
41884188
}
41894189

4190+
vector<RteBoard*> ProjMgrWorker::GetCompatibleBoards(ContextItem& context) {
4191+
vector<RteBoard*> compatibleBoards;
4192+
if (!context.board.empty()) {
4193+
compatibleBoards.push_back(context.rteBoard);
4194+
} else if (!context.device.empty()) {
4195+
context.rteFilteredModel->GetCompatibleBoards(compatibleBoards, context.rteDevice);
4196+
}
4197+
return compatibleBoards;
4198+
}
4199+
4200+
bool ProjMgrWorker::IsBoardListCompatible(const vector<RteBoard*> compatibleBoards, const Collection<RteItem*>& boards) {
4201+
if (boards.empty() || compatibleBoards.empty()) {
4202+
return true;
4203+
}
4204+
for (const auto& board : boards) {
4205+
for (const auto& compatibleBoard : compatibleBoards) {
4206+
if ((compatibleBoard->GetVendorString() == board->GetVendorString()) &&
4207+
(compatibleBoard->GetName() == board->GetName())) {
4208+
return true;
4209+
}
4210+
}
4211+
}
4212+
return false;
4213+
}
4214+
4215+
std::vector<ExampleItem> ProjMgrWorker::CollectExamples(ContextItem& context) {
4216+
std::vector<ExampleItem> examples;
4217+
vector<const RteItem*> rteExamples;
4218+
const auto& packs = context.rteFilteredModel->GetPackages();
4219+
for (const auto& [_, pack] : packs) {
4220+
const RteItem* packExamples = pack->GetExamples();
4221+
if (packExamples) {
4222+
const Collection<RteItem*> items = packExamples->GetChildren();
4223+
for (const RteItem* item : items) {
4224+
if (item->GetTag() == "example") {
4225+
rteExamples.push_back(item);
4226+
}
4227+
}
4228+
}
4229+
}
4230+
const auto& compatibleBoards = GetCompatibleBoards(context);
4231+
for (const auto& rteExample : rteExamples) {
4232+
Collection<RteItem*> boards;
4233+
boards = rteExample->GetChildrenByTag("board", boards);
4234+
if (!IsBoardListCompatible(compatibleBoards, boards)) {
4235+
continue;
4236+
}
4237+
ExampleItem example;
4238+
example.name = rteExample->GetName();
4239+
example.description = rteExample->GetChildText("description");
4240+
string folder = rteExample->GetFolderString();
4241+
RteFsUtils::NormalizePath(folder, rteExample->GetAbsolutePackagePath());
4242+
example.doc = rteExample->GetDocValue();
4243+
RteFsUtils::NormalizePath(example.doc, folder);
4244+
string archive = rteExample->GetAttribute("archive");
4245+
if (!archive.empty()) {
4246+
RteFsUtils::NormalizePath(archive, folder);
4247+
example.archive = archive;
4248+
}
4249+
for (const auto& board : boards) {
4250+
example.boards.push_back(BoardItem{ board->GetVendorString(), board->GetName() });
4251+
}
4252+
const auto& version = rteExample->GetVersionString();
4253+
if (!version.empty()) {
4254+
example.version = version;
4255+
}
4256+
4257+
Collection<RteItem*> environments;
4258+
environments = rteExample->GetChildrenByTag("environment", environments);
4259+
for (const auto& item : environments) {
4260+
string load = item->GetAttribute("load");
4261+
RteFsUtils::NormalizePath(load, folder);
4262+
const auto& name = item->GetName();
4263+
example.environments[name].load = load;
4264+
example.environments[name].folder = item->GetFolderString();
4265+
RteFsUtils::NormalizePath(example.environments[name].folder, folder);
4266+
}
4267+
4268+
Collection<RteItem*> components;
4269+
components = rteExample->GetChildrenByTag("component", components);
4270+
for (const auto& item : components) {
4271+
example.components.push_back(item->GetComponentID(true));
4272+
}
4273+
4274+
Collection<RteItem*> categories;
4275+
categories = rteExample->GetChildrenByTag("category", categories);
4276+
for (const auto& item : categories) {
4277+
example.categories.push_back(item->GetText());
4278+
}
4279+
4280+
Collection<RteItem*> keywords;
4281+
components = rteExample->GetChildrenByTag("keyword", keywords);
4282+
for (const auto& item : keywords) {
4283+
example.keywords.push_back(item->GetText());
4284+
}
4285+
4286+
examples.push_back(example);
4287+
}
4288+
return examples;
4289+
}
4290+
4291+
bool ProjMgrWorker::ListExamples(vector<string>& examples, const string& filter) {
4292+
const auto& selectedContext = m_selectedContexts.front();
4293+
ContextItem& context = m_contexts[selectedContext];
4294+
if (!LoadPacks(context)) {
4295+
return false;
4296+
}
4297+
if (!selectedContext.empty()) {
4298+
if (!ProcessPrecedences(context, BoardOrDevice::Both)) {
4299+
return false;
4300+
}
4301+
}
4302+
if (!SetTargetAttributes(context, context.targetAttributes)) {
4303+
return false;
4304+
}
4305+
4306+
const auto& collectedExamples = CollectExamples(context);
4307+
4308+
for (const auto& exampleItem : collectedExamples) {
4309+
string example = exampleItem.name;
4310+
example += exampleItem.version.empty() ? "" : "@" + exampleItem.version;
4311+
example += "\n description: " + exampleItem.description;
4312+
example += "\n doc: " + exampleItem.doc;
4313+
if (!exampleItem.archive.empty()) {
4314+
example += "\n archive: " + exampleItem.archive;
4315+
}
4316+
for (const auto& [name, environment] : exampleItem.environments) {
4317+
example += "\n environment: " + name + "\n load: " + environment.load;
4318+
example += "\n folder: " + environment.folder;
4319+
}
4320+
if (!exampleItem.boards.empty()) {
4321+
example += "\n boards:";
4322+
for (const auto& board : exampleItem.boards) {
4323+
example += "\n " + board.vendor + "::" + board.name;
4324+
}
4325+
}
4326+
if (!exampleItem.components.empty()) {
4327+
example += "\n components:";
4328+
for (const auto& component : exampleItem.components) {
4329+
example += "\n " + component;
4330+
}
4331+
}
4332+
if (!exampleItem.categories.empty()) {
4333+
example += "\n categories:";
4334+
for (const auto& category : exampleItem.categories) {
4335+
example += "\n " + category;
4336+
}
4337+
}
4338+
if (!exampleItem.keywords.empty()) {
4339+
example += "\n keywords:";
4340+
for (const auto& keyword : exampleItem.keywords) {
4341+
example += "\n " + keyword;
4342+
}
4343+
}
4344+
if (filter.empty() || example.find(filter) != string::npos) {
4345+
examples.push_back(example);
4346+
}
4347+
}
4348+
return true;
4349+
}
4350+
41904351
bool ProjMgrWorker::FormatValidationResults(set<string>& results, const ContextItem& context) {
41914352
for (const auto& validation : context.validationResults) {
41924353
string resultStr = RteItem::ConditionResultToString(validation.result) + " " + validation.id;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json
2+
3+
project:
4+
5+
components:
6+
- component: Startup
7+
- component: CORE
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/csolution.schema.json
2+
3+
solution:
4+
5+
packs:
6+
- pack: ARM::RteTest_DFP
7+
- pack: ARM::RteTest
8+
9+
compiler: AC6
10+
11+
target-types:
12+
- type: TestBoard
13+
board: RteTest Dummy board
14+
device: :cm0_core0
15+
target-set:
16+
- set:
17+
images:
18+
- project-context: project
19+
- type: CM0_Dual
20+
device: RteTest_ARMCM0_Dual:cm0_core0
21+
target-set:
22+
- set:
23+
images:
24+
- project-context: project
25+
- type: CM0
26+
device: RteTest_ARMCM0
27+
target-set:
28+
- set:
29+
images:
30+
- project-context: project
31+
32+
projects:
33+
- project: project.cproject.yml

0 commit comments

Comments
 (0)