forked from Open-CMSIS-Pack/devtools
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathProjMgrCbuildPack.cpp
More file actions
149 lines (125 loc) · 5.2 KB
/
Copy pathProjMgrCbuildPack.cpp
File metadata and controls
149 lines (125 loc) · 5.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
* Copyright (c) 2020-2024 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "ProjMgrCbuildBase.h"
#include "ProjMgrYamlEmitter.h"
#include "ProjMgrYamlParser.h"
using namespace std;
// cbuild-pack
class ProjMgrCbuildPack : public ProjMgrCbuildBase {
public:
ProjMgrCbuildPack(YAML::Node node, const vector<ContextItem*>& processedContexts,
ProjMgrParser* parser, bool keepExistingPackContent);
};
ProjMgrCbuildPack::ProjMgrCbuildPack(YAML::Node node, const vector<ContextItem*>& processedContexts,
ProjMgrParser* parser, bool keepExistingPackContent) :
ProjMgrCbuildBase(false) {
const auto& csolution = parser->GetCsolution();
struct ModelItem {
PackInfo info;
ResolvedPackItem resolvedPack;
};
map<string, ModelItem> model;
// Stage 1: Add all known items from the current cbuild pack file, if considering all contexts
if (keepExistingPackContent) {
for (const auto& resolvedItem : csolution.cbuildPack.packs) {
ModelItem modelItem;
ProjMgrUtils::ConvertToPackInfo(resolvedItem.pack, modelItem.info);
modelItem.resolvedPack.pack = resolvedItem.pack;
modelItem.resolvedPack.selectedByPack = resolvedItem.selectedByPack;
model[resolvedItem.pack] = modelItem;
}
}
// Stage 2: Process packs that are required by used components
for (const auto& context : processedContexts) {
for (const auto& [packId, package] : context->packages) {
// Skip project local packs
const string& packPath = package->GetRootFilePath(false);
if (context->localPackPaths.find(packPath) != context->localPackPaths.end()) {
continue;
}
if (model.find(packId) == model.end()) {
// Add pack
ModelItem modelItem;
ProjMgrUtils::ConvertToPackInfo(packId, modelItem.info);
modelItem.resolvedPack.pack = packId;
model[packId] = modelItem;
}
}
}
// Stage 3: Add all user input expression on the matching resolved pack
for (const auto& context : processedContexts) {
for (const auto& [userInput, resolvedPacks] : context->userInputToResolvedPackIdMap) {
for (const auto& [resolvedPack, _] : resolvedPacks) {
if (model.find(resolvedPack) == model.end()) {
ModelItem modelItem;
ProjMgrUtils::ConvertToPackInfo(resolvedPack, modelItem.info);
modelItem.resolvedPack.pack = resolvedPack;
model[resolvedPack] = modelItem;
}
CollectionUtils::PushBackUniquely(model[resolvedPack].resolvedPack.selectedByPack, userInput);
}
}
}
// Stage 4: Process all wildcard patterns from user and add to selected-by-pack list
for (const auto& context : processedContexts) {
for (const auto& packItem : context->packRequirements) {
// Skip project local packs
if (!packItem.path.empty()) {
continue;
}
const PackInfo& reqInfo = packItem.pack;
if (reqInfo.name.empty() || WildCards::IsWildcardPattern(reqInfo.name)) {
const string packId = RtePackage::ComposePackageID(reqInfo.vendor, reqInfo.name, reqInfo.version);
for (auto& [_, item] : model) {
if (ProjMgrUtils::IsMatchingPackInfo(item.info, reqInfo)) {
CollectionUtils::PushBackUniquely(item.resolvedPack.selectedByPack, packId);
}
}
}
}
}
// Sort model before saving to ensure stable cbuild-pack.yml content
vector<pair<string, ModelItem>> sortedModel;
for (const auto& item : model) {
sortedModel.push_back(item);
}
std::sort(sortedModel.begin(), sortedModel.end(), [](const pair<string, ModelItem>& item1, const pair<string, ModelItem>& item2) {
PackInfo packInfo1, packInfo2;
ProjMgrUtils::ConvertToPackInfo(item1.first, packInfo1);
ProjMgrUtils::ConvertToPackInfo(item2.first, packInfo2);
if (packInfo1.vendor == packInfo2.vendor) {
if (packInfo1.name == packInfo2.name) {
// Order by pack version
return VersionCmp::Compare(packInfo1.version, packInfo2.version) < 0;
}
// Order by pack name
return packInfo1.name < packInfo2.name;
}
// Order by vendor name
return packInfo1.vendor < packInfo2.vendor;
});
// Produce the yml output
for (auto& [packId, modelItem] : sortedModel) {
YAML::Node resolvedPackNode;
auto& packItem = modelItem.resolvedPack;
SetNodeValue(resolvedPackNode[YAML_RESOLVED_PACK], packId);
sort(packItem.selectedByPack.begin(), packItem.selectedByPack.end());
SetNodeValue(resolvedPackNode[YAML_SELECTED_BY_PACK], packItem.selectedByPack);
node[YAML_RESOLVED_PACKS].push_back(resolvedPackNode);
}
}
//-- ProjMgrYamlEmitter::GenerateCbuildPack -------------------------------------------------------
bool ProjMgrYamlEmitter::GenerateCbuildPack(const vector<ContextItem*> contexts,
bool keepExistingPackContent, bool cbuildPackFrozen) {
if (m_parser->GetCsolution().name.empty()) {
return false;
}
// generate cbuild-pack.yml
const string& filename = m_parser->GetCsolution().directory + "/" + m_parser->GetCsolution().name + ".cbuild-pack.yml";
YAML::Node rootNode;
ProjMgrCbuildPack cbuildPack(rootNode[YAML_CBUILD_PACK], contexts, m_parser, keepExistingPackContent);
return WriteFile(rootNode, filename, "", !cbuildPackFrozen);
}