@eui/tools 6.1.0 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.version.properties +1 -1
- package/CHANGELOG.md +15 -0
- package/bin/eui-scripts.js +2 -0
- package/bin/scripts/audit-package.js +10 -0
- package/bin/scripts/csdr-upgrade-deps.js +1 -4
- package/package.json +1 -1
- package/sandbox.js +137 -18
- package/scripts/csdr/audit/audit-utils.js +3 -98
- package/scripts/csdr/audit/deps.js +89 -0
- package/scripts/csdr/audit/styles.js +457 -0
- package/scripts/csdr/audit/yarn.js +105 -0
- package/scripts/csdr/config/global.js +17 -17
- package/scripts/csdr/config/packages.js +67 -5
- package/scripts/csdr/config/projects.js +14 -4
- package/scripts/csdr/config/sync.js +0 -1
- package/scripts/csdr/init/global.js +122 -0
- package/scripts/csdr/init/init-utils.js +8 -358
- package/scripts/csdr/init/init.js +19 -12
- package/scripts/csdr/init/packages.js +142 -0
- package/scripts/csdr/init/projects.js +112 -0
- package/scripts/csdr/init/remotes.js +21 -0
- package/scripts/csdr/install/common.js +26 -391
- package/scripts/csdr/install/local-dev.js +54 -50
- package/scripts/csdr/install/packages.js +183 -3
- package/scripts/csdr/install/projects.js +198 -9
- package/scripts/csdr/release/package/ui.js +6 -85
- package/scripts/csdr/sync/sync-utils.js +8 -8
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// GLOBAL
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const glob = require('glob');
|
|
6
|
+
|
|
7
|
+
// LOCAL
|
|
8
|
+
const tools = require('../../utils/tools');
|
|
9
|
+
const notificationUtils = require('../../utils/notification/notification-utils');
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
const runStylesAudit = module.exports.runStylesAudit = (pkg) => {
|
|
13
|
+
|
|
14
|
+
const generateIndicesContent = (indices, file, fileContent) => {
|
|
15
|
+
let content = [];
|
|
16
|
+
|
|
17
|
+
indices.forEach((i) => {
|
|
18
|
+
for (var pos = i-1; pos >=0; pos--) {
|
|
19
|
+
if (fileContent.charAt(pos) === '\n') {
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const remaining = fileContent.substring(pos+1).trim();
|
|
24
|
+
const breakPos = remaining.indexOf('\n');
|
|
25
|
+
const indiceContent = remaining.substring(0, breakPos-1);
|
|
26
|
+
|
|
27
|
+
const lineNumber = fileContent.substring(0, i).split('\n').length;
|
|
28
|
+
|
|
29
|
+
content.push({
|
|
30
|
+
file: file,
|
|
31
|
+
lineNumber: lineNumber,
|
|
32
|
+
content: indiceContent,
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
return content;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const getStatus = (count) => {
|
|
40
|
+
return (count > 5) ? 'CRITICAL' : (count > 0 && count <= 5) ? 'IMPROVE' : 'OK';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
tools.logTitle(`Auditing : ${pkg.name}`);
|
|
47
|
+
|
|
48
|
+
const report = {
|
|
49
|
+
package: null,
|
|
50
|
+
score: 0,
|
|
51
|
+
total: 0,
|
|
52
|
+
pcScore: 0,
|
|
53
|
+
scssFilesCount: 0,
|
|
54
|
+
scssEmptyFiles: 0,
|
|
55
|
+
htmlFilesCount: 0,
|
|
56
|
+
htmlLinesCount: 0,
|
|
57
|
+
scssLinescount: 0,
|
|
58
|
+
tsOver500: {
|
|
59
|
+
count: 0,
|
|
60
|
+
files: []
|
|
61
|
+
},
|
|
62
|
+
euiOverrides: {
|
|
63
|
+
count: 0,
|
|
64
|
+
indices: []
|
|
65
|
+
},
|
|
66
|
+
sizesPxEm: {
|
|
67
|
+
count: 0,
|
|
68
|
+
indices: []
|
|
69
|
+
},
|
|
70
|
+
boxShadow: {
|
|
71
|
+
count: 0,
|
|
72
|
+
indices: []
|
|
73
|
+
},
|
|
74
|
+
fontFamily: {
|
|
75
|
+
count: 0,
|
|
76
|
+
indices: []
|
|
77
|
+
},
|
|
78
|
+
important: {
|
|
79
|
+
count: 0,
|
|
80
|
+
indices: []
|
|
81
|
+
},
|
|
82
|
+
plainColors: {
|
|
83
|
+
count: 0,
|
|
84
|
+
indices: []
|
|
85
|
+
},
|
|
86
|
+
ngDeep: {
|
|
87
|
+
count: 0,
|
|
88
|
+
indices: []
|
|
89
|
+
},
|
|
90
|
+
inlineStyles: {
|
|
91
|
+
count: 0,
|
|
92
|
+
indices: []
|
|
93
|
+
},
|
|
94
|
+
material: {
|
|
95
|
+
count: 0,
|
|
96
|
+
indices: []
|
|
97
|
+
},
|
|
98
|
+
primeng: {
|
|
99
|
+
count: 0,
|
|
100
|
+
indices: []
|
|
101
|
+
},
|
|
102
|
+
uxCmp: {
|
|
103
|
+
count: 0,
|
|
104
|
+
// indices: []
|
|
105
|
+
},
|
|
106
|
+
finalReport: {}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
report.package = pkg.name;
|
|
111
|
+
|
|
112
|
+
let files = glob.sync('**/*.scss', { cwd: pkg.paths.src, nodir: true, follow: true, dot: true });
|
|
113
|
+
|
|
114
|
+
report.scssFilesCount += files.length;
|
|
115
|
+
|
|
116
|
+
files.forEach(file => {
|
|
117
|
+
const filePath = path.join(pkg.paths.src, file);
|
|
118
|
+
const fileContent = tools.getFileContent(filePath).trim();
|
|
119
|
+
const linesCount = fileContent.split('\n').length;
|
|
120
|
+
|
|
121
|
+
if (fileContent === '') {
|
|
122
|
+
report.scssEmptyFiles++;
|
|
123
|
+
}
|
|
124
|
+
report.scssLinescount += linesCount;
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
let result, euiIndices = [];
|
|
128
|
+
let regex = /\.eui|\.ux/gi;
|
|
129
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
130
|
+
euiIndices.push(result.index);
|
|
131
|
+
}
|
|
132
|
+
report.euiOverrides.count += euiIndices.length;
|
|
133
|
+
report.euiOverrides.indices = [...report.euiOverrides.indices, ...generateIndicesContent(euiIndices, file, fileContent)];
|
|
134
|
+
|
|
135
|
+
let sizesIndices = [];
|
|
136
|
+
regex = /px/gi;
|
|
137
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
138
|
+
sizesIndices.push(result.index);
|
|
139
|
+
}
|
|
140
|
+
report.sizesPxEm.count += sizesIndices.length;
|
|
141
|
+
report.sizesPxEm.indices = [...report.sizesPxEm.indices, ...generateIndicesContent(sizesIndices, file, fileContent)];
|
|
142
|
+
|
|
143
|
+
let boxShadowIndices = [];
|
|
144
|
+
regex = /box-shadow/gi;
|
|
145
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
146
|
+
boxShadowIndices.push(result.index);
|
|
147
|
+
}
|
|
148
|
+
report.boxShadow.count += boxShadowIndices.length;
|
|
149
|
+
report.boxShadow.indices = [...report.boxShadow.indices, ...generateIndicesContent(boxShadowIndices, file, fileContent)];
|
|
150
|
+
|
|
151
|
+
let fontFamilyIndices = [];
|
|
152
|
+
regex = /font-family/gi;
|
|
153
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
154
|
+
fontFamilyIndices.push(result.index);
|
|
155
|
+
}
|
|
156
|
+
report.fontFamily.count += fontFamilyIndices.length;
|
|
157
|
+
report.fontFamily.indices = [...report.fontFamily.indices, ...generateIndicesContent(fontFamilyIndices, file, fileContent)];
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
let importantIndices = [];
|
|
161
|
+
regex = /!important/gi;
|
|
162
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
163
|
+
importantIndices.push(result.index);
|
|
164
|
+
}
|
|
165
|
+
report.important.count += importantIndices.length;
|
|
166
|
+
report.important.indices = [...report.important.indices, ...generateIndicesContent(importantIndices, file, fileContent)];
|
|
167
|
+
|
|
168
|
+
let colorsIndices = [];
|
|
169
|
+
regex = /#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})|rgba|hsl/gi;
|
|
170
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
171
|
+
colorsIndices.push(result.index);
|
|
172
|
+
}
|
|
173
|
+
report.plainColors.count += colorsIndices.length;
|
|
174
|
+
report.plainColors.indices = [...report.plainColors.indices, ...generateIndicesContent(colorsIndices, file, fileContent)];
|
|
175
|
+
|
|
176
|
+
let ngDeepIndices = [];
|
|
177
|
+
regex = /::ng-deep/gi;
|
|
178
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
179
|
+
ngDeepIndices.push(result.index);
|
|
180
|
+
}
|
|
181
|
+
report.ngDeep.count += ngDeepIndices.length;
|
|
182
|
+
report.ngDeep.indices = [...report.ngDeep.indices, ...generateIndicesContent(ngDeepIndices, file, fileContent)];
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
files = glob.sync('**/*.html', { cwd: pkg.paths.src, nodir: true, follow: true, dot: true });
|
|
188
|
+
|
|
189
|
+
report.htmlFilesCount += files.length;
|
|
190
|
+
|
|
191
|
+
files.forEach(file => {
|
|
192
|
+
const filePath = path.join(pkg.paths.src, file);
|
|
193
|
+
const fileContent = tools.getFileContent(filePath);
|
|
194
|
+
const linesCount = fileContent.split('\n').length;
|
|
195
|
+
|
|
196
|
+
report.htmlLinesCount += linesCount;
|
|
197
|
+
|
|
198
|
+
let result, inlineStylesIndices = [];
|
|
199
|
+
let regex = /style=/gi;
|
|
200
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
201
|
+
inlineStylesIndices.push(result.index);
|
|
202
|
+
}
|
|
203
|
+
report.inlineStyles.count += inlineStylesIndices.length;
|
|
204
|
+
report.inlineStyles.indices = [...report.inlineStyles.indices, ...generateIndicesContent(inlineStylesIndices, file, fileContent)];
|
|
205
|
+
|
|
206
|
+
let uxCmpIndices = [];
|
|
207
|
+
regex = /ux-/gi;
|
|
208
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
209
|
+
uxCmpIndices.push(result.index);
|
|
210
|
+
}
|
|
211
|
+
report.uxCmp.count += uxCmpIndices.length;
|
|
212
|
+
// report.uxCmp.indices = [...report.uxCmp.indices, ...generateIndicesContent(uxCmpIndices, file, fileContent)];
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
files = glob.sync('**/*.ts', { cwd: pkg.paths.src, nodir: true, follow: true, dot: true });
|
|
219
|
+
|
|
220
|
+
files.forEach(file => {
|
|
221
|
+
const filePath = path.join(pkg.paths.src, file);
|
|
222
|
+
const fileContent = tools.getFileContent(filePath);
|
|
223
|
+
const linesCount = fileContent.split('\n').length;
|
|
224
|
+
|
|
225
|
+
if (linesCount > 500) {
|
|
226
|
+
report.tsOver500.count++;
|
|
227
|
+
report.tsOver500.files.push(file);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
let result, primengIndices = [];
|
|
231
|
+
let regex = /primeng/gi;
|
|
232
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
233
|
+
primengIndices.push(result.index);
|
|
234
|
+
}
|
|
235
|
+
report.primeng.count += primengIndices.length;
|
|
236
|
+
report.primeng.indices = [...report.primeng.indices, ...generateIndicesContent(primengIndices, file, fileContent)];
|
|
237
|
+
|
|
238
|
+
let materialIndices = [];
|
|
239
|
+
regex = /@angular\/material/gi;
|
|
240
|
+
while ( (result = regex.exec(fileContent)) ) {
|
|
241
|
+
materialIndices.push(result.index);
|
|
242
|
+
}
|
|
243
|
+
report.material.count += materialIndices.length;
|
|
244
|
+
report.material.indices = [...report.material.indices, ...generateIndicesContent(materialIndices, file, fileContent)];
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
// GLOBAL STATS - ANALYZING DATA / SET STATUS
|
|
252
|
+
|
|
253
|
+
if (report.htmlFilesCount !== 0) {
|
|
254
|
+
const scssHtmlRatio = Math.floor(100 * report.scssFilesCount / report.htmlFilesCount);
|
|
255
|
+
report.finalReport['scssHtmlRatio'] = {
|
|
256
|
+
description: 'scss files VS html files',
|
|
257
|
+
value: `${report.scssFilesCount} out of ${report.htmlFilesCount} (${scssHtmlRatio}%)`,
|
|
258
|
+
status: (scssHtmlRatio >= 25) ? 'CRITICAL' : (scssHtmlRatio >= 10 && scssHtmlRatio <= 25) ? 'IMPROVE' : 'OK',
|
|
259
|
+
comment: null,
|
|
260
|
+
}
|
|
261
|
+
if (report.finalReport['scssHtmlRatio'].status === 'CRITICAL') {
|
|
262
|
+
report.finalReport['scssHtmlRatio'].comment = 'The percentage of html files having scss declaration is too high';
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (report.htmlLinesCount !== 0) {
|
|
267
|
+
const scssHtmlLinesRatio = Math.floor(100 * report.scssLinescount / report.htmlLinesCount);
|
|
268
|
+
report.finalReport['scssHtmlLinesRatio'] = {
|
|
269
|
+
description: 'scss lines count VS html lines count',
|
|
270
|
+
value: `${report.scssLinescount} / ${report.htmlLinesCount} (${scssHtmlLinesRatio}%)`,
|
|
271
|
+
status: (scssHtmlLinesRatio >= 25) ? 'CRITICAL' : (scssHtmlLinesRatio >= 10 && scssHtmlLinesRatio <= 25) ? 'IMPROVE' : 'OK',
|
|
272
|
+
comment: null,
|
|
273
|
+
}
|
|
274
|
+
if (report.finalReport['scssHtmlLinesRatio'].status === 'CRITICAL') {
|
|
275
|
+
report.finalReport['scssHtmlLinesRatio'].comment = 'The percentage of scss lines is too high';
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (report.scssFilesCount !== 0) {
|
|
280
|
+
report.finalReport['scssEmptyFiles'] = {
|
|
281
|
+
description: 'scss empty files',
|
|
282
|
+
value: `${report.scssEmptyFiles} out of ${report.scssFilesCount} (${Math.floor(100 * report.scssEmptyFiles / report.scssFilesCount)}%)`,
|
|
283
|
+
status: (report.scssEmptyFiles !== 0) ? 'IMPROVE' : 'OK',
|
|
284
|
+
comment: (report.scssEmptyFiles !== 0) ? 'Scss files without content should be cleaned up' : null
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
// BALANCED - styles content
|
|
291
|
+
|
|
292
|
+
if (report.scssFilesCount !== 0) {
|
|
293
|
+
|
|
294
|
+
report.finalReport['euiOverrides'] = {
|
|
295
|
+
description: 'eUI overrides found',
|
|
296
|
+
value: report.euiOverrides.count,
|
|
297
|
+
status: getStatus(report.euiOverrides.count),
|
|
298
|
+
comment: (report.euiOverrides.count !== 0) ? 'No eUI overrides should be applied, contact eUI support for assistance' : null
|
|
299
|
+
}
|
|
300
|
+
report.finalReport['sizesPxEm'] = {
|
|
301
|
+
description: 'Sizes in px usage found',
|
|
302
|
+
value: report.sizesPxEm.count,
|
|
303
|
+
status: getStatus(report.sizesPxEm.count),
|
|
304
|
+
comment: (report.sizesPxEm.count !== 0) ? 'if sizes should be tweaked, usage of eUI CSS vars should be applied' : null
|
|
305
|
+
}
|
|
306
|
+
report.finalReport['boxShadow'] = {
|
|
307
|
+
description: 'box-shadow usage found',
|
|
308
|
+
value: report.boxShadow.count,
|
|
309
|
+
status: getStatus(report.boxShadow.count),
|
|
310
|
+
comment: (report.boxShadow.count !== 0) ? 'if box-shadow should be tweaked (on specific context), usage of eUI CSS vars should be applied' : null
|
|
311
|
+
}
|
|
312
|
+
report.finalReport['fontFamily'] = {
|
|
313
|
+
description: 'font-family usage found',
|
|
314
|
+
value: report.fontFamily.count,
|
|
315
|
+
status: getStatus(report.fontFamily.count),
|
|
316
|
+
comment: (report.fontFamily.count !== 0) ? 'if font-family should be tweaked (on specific context), usage of eUI CSS vars should be applied' : null
|
|
317
|
+
}
|
|
318
|
+
report.finalReport['plainColors'] = {
|
|
319
|
+
description: 'Plain colors usage found',
|
|
320
|
+
value: report.plainColors.count,
|
|
321
|
+
status: getStatus(report.plainColors.count),
|
|
322
|
+
comment: (report.plainColors.count !== 0) ? 'if colors should be used in scss, usage of eUI CSS vars should be applied' : null
|
|
323
|
+
}
|
|
324
|
+
report.finalReport['important'] = {
|
|
325
|
+
description: '!important usage found',
|
|
326
|
+
value: report.important.count,
|
|
327
|
+
status: getStatus(report.important.count),
|
|
328
|
+
comment: (report.important.count !== 0) ? 'No !important allowed' : null
|
|
329
|
+
}
|
|
330
|
+
report.finalReport['ngDeep'] = {
|
|
331
|
+
description: '::ng-deep usage found',
|
|
332
|
+
value: report.ngDeep.count,
|
|
333
|
+
status: getStatus(report.ngDeep.count),
|
|
334
|
+
comment: (report.ngDeep.count !== 0) ? 'Avoid ::ng-deep usage' : null
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// CRITICAL ONLY
|
|
339
|
+
|
|
340
|
+
report.finalReport['inlineStyles'] = {
|
|
341
|
+
description: 'inline styles found in HTML',
|
|
342
|
+
value: report.inlineStyles.count,
|
|
343
|
+
status: (report.inlineStyles.count !== 0) ? 'CRITICAL' : 'OK',
|
|
344
|
+
comment: (report.inlineStyles.count !== 0) ? 'No inline styles should be present in html, usage classes with scss / eUI utilities instead' : null
|
|
345
|
+
}
|
|
346
|
+
report.finalReport['material'] = {
|
|
347
|
+
description: 'material component usage found in HTML',
|
|
348
|
+
value: report.material.count,
|
|
349
|
+
status: (report.material.count !== 0) ? 'CRITICAL' : 'OK',
|
|
350
|
+
comment: (report.material.count !== 0) ? 'Usage of material should be avoided' : null
|
|
351
|
+
}
|
|
352
|
+
report.finalReport['primeng'] = {
|
|
353
|
+
description: 'PrimeNG components usage found in HTML',
|
|
354
|
+
value: report.primeng.count,
|
|
355
|
+
status: (report.primeng.count !== 0) ? 'CRITICAL' : 'OK',
|
|
356
|
+
comment: (report.primeng.count !== 0) ? 'Remove any PrimeNG usage, deprecated in eUI' : null
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
// IMPROVE ONLY
|
|
362
|
+
|
|
363
|
+
report.finalReport['uxCmp'] = {
|
|
364
|
+
description: 'eUI ux- components usage found in HTML',
|
|
365
|
+
value: report.uxCmp.count,
|
|
366
|
+
status: (report.uxCmp.count !== 0) ? 'IMPROVE' : 'OK',
|
|
367
|
+
comment: (report.uxCmp.count !== 0) ? 'Replace by "eui-" components whenever possible, to ensure future proof migration' : null
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
report.finalReport['tsOver500'] = {
|
|
371
|
+
description: 'TS file containing more than 500 lines',
|
|
372
|
+
value: report.tsOver500.count,
|
|
373
|
+
status: (report.tsOver500.count !== 0) ? 'IMPROVE' : 'OK',
|
|
374
|
+
comment: (report.tsOver500.count !== 0) ? 'Split TS files into multiple ones for readability' : null
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
// Calculating score
|
|
379
|
+
|
|
380
|
+
let score = 0, total = 0;
|
|
381
|
+
|
|
382
|
+
Object.entries(report.finalReport).forEach((v) => {
|
|
383
|
+
total++;
|
|
384
|
+
|
|
385
|
+
switch(v[1].status) {
|
|
386
|
+
case 'OK':
|
|
387
|
+
score++;
|
|
388
|
+
break;
|
|
389
|
+
case 'IMPROVE':
|
|
390
|
+
score+=0.5;
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
report.score = score;
|
|
396
|
+
report.total = total;
|
|
397
|
+
report.pcScore = Math.floor(100 * score / total);
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
// return JSON report
|
|
401
|
+
|
|
402
|
+
tools.logInfo('STATS report');
|
|
403
|
+
console.log(JSON.stringify(report, null, 2));
|
|
404
|
+
|
|
405
|
+
return report;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
module.exports.audit = (pkg) => {
|
|
412
|
+
if (pkg.remote) {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
tools.logTitle('Audit package styles');
|
|
417
|
+
|
|
418
|
+
return Promise.resolve()
|
|
419
|
+
.then(() => {
|
|
420
|
+
|
|
421
|
+
const report = runStylesAudit(pkg);
|
|
422
|
+
|
|
423
|
+
// FINAL REPORT
|
|
424
|
+
|
|
425
|
+
let finalReportMessage = `*STYLES AUDIT REPORT for ${pkg.name}:*\n\n`;
|
|
426
|
+
|
|
427
|
+
Object.entries(report.finalReport).forEach((v) => {
|
|
428
|
+
let statusEmoji;
|
|
429
|
+
|
|
430
|
+
if (v[1].status === 'CRITICAL') {
|
|
431
|
+
statusEmoji = ':no_entry:';
|
|
432
|
+
} else if (v[1].status === 'IMPROVE') {
|
|
433
|
+
statusEmoji = ':warning:';
|
|
434
|
+
} else {
|
|
435
|
+
statusEmoji = ':white_tick:';
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
finalReportMessage += `:black_small_square: ${statusEmoji} *${v[1].description}*: found *${v[1].value}* - status: *${v[1].status}* ${(v[1].comment) ? '==> ' + v[1].comment : ''}\n`;
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
finalReportMessage +=`\neUI compliance score : *${report.score}* out of *${report.total}* *(${report.pcScore}%)*`;
|
|
442
|
+
|
|
443
|
+
tools.logInfo('Sending final report message');
|
|
444
|
+
console.log(finalReportMessage);
|
|
445
|
+
|
|
446
|
+
return notificationUtils.package.sendPackageMessage({
|
|
447
|
+
package: pkg,
|
|
448
|
+
text: finalReportMessage
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
})
|
|
452
|
+
.catch((e) => {
|
|
453
|
+
console.log(e);
|
|
454
|
+
})
|
|
455
|
+
|
|
456
|
+
}
|
|
457
|
+
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// GLOBAL
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const execa = require('execa');
|
|
6
|
+
|
|
7
|
+
// LOCAL
|
|
8
|
+
const tools = require('../../utils/tools');
|
|
9
|
+
const notificationUtils = require('../../utils/notification/notification-utils');
|
|
10
|
+
|
|
11
|
+
// GET ARGS
|
|
12
|
+
const { dryRun } = tools.getArgs();
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
const getVulnerabilitiesList = () => {
|
|
17
|
+
let auditContent;
|
|
18
|
+
const auditFile = path.join(process.cwd(), 'audit.json');
|
|
19
|
+
|
|
20
|
+
if (tools.isFileExists(auditFile)) {
|
|
21
|
+
auditContent = tools.getFileContent(auditFile);
|
|
22
|
+
} else {
|
|
23
|
+
tools.logWarning(`${auditFile} not found... unable to precess audit content`);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let auditContentArray = [];
|
|
28
|
+
let vulnerabilitiesFound = {};
|
|
29
|
+
|
|
30
|
+
// yarn audit output uses a specific json-lines format, we need to split it first
|
|
31
|
+
auditContentArray = auditContent.split('\n');
|
|
32
|
+
|
|
33
|
+
// extracting the audit summary lines
|
|
34
|
+
auditContentArray.forEach((c) => {
|
|
35
|
+
try {
|
|
36
|
+
const parsedContent = JSON.parse(c);
|
|
37
|
+
if (parsedContent && parsedContent.type === 'auditSummary') {
|
|
38
|
+
vulnerabilitiesFound = parsedContent.data.vulnerabilities;
|
|
39
|
+
}
|
|
40
|
+
} catch(e) {} // it can fail
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
return vulnerabilitiesFound;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
module.exports.audit = (pkg) => {
|
|
48
|
+
if (dryRun) return;
|
|
49
|
+
|
|
50
|
+
tools.logTitle('Yarn auditing package');
|
|
51
|
+
|
|
52
|
+
return Promise.resolve()
|
|
53
|
+
|
|
54
|
+
// first pass to display the visual report into the CI logs
|
|
55
|
+
.then(() => {
|
|
56
|
+
return Promise.resolve()
|
|
57
|
+
.then(() => {
|
|
58
|
+
return execa.shellSync('yarn audit --level high', { cwd: process.cwd(), stdio: 'inherit' });
|
|
59
|
+
})
|
|
60
|
+
.catch((e) => {}) // it can fail
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// second pass to extract the audit summary lines
|
|
64
|
+
.then(() => {
|
|
65
|
+
return Promise.resolve()
|
|
66
|
+
.then(() => {
|
|
67
|
+
const auditFile = path.join(process.cwd(), 'audit.json');
|
|
68
|
+
tools.logInfo(`Creating audit file`)
|
|
69
|
+
return execa.shellSync(`yarn audit --level high --json > ${auditFile}`, { cwd: process.cwd(), stdio: 'inherit' });
|
|
70
|
+
})
|
|
71
|
+
.then(() => {
|
|
72
|
+
tools.logSuccess();
|
|
73
|
+
return null;
|
|
74
|
+
})
|
|
75
|
+
.catch((e) => {
|
|
76
|
+
tools.logError('Auditing detected vulnerabilities in dependencies');
|
|
77
|
+
return getVulnerabilitiesList();
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
// sending output to slack channel
|
|
82
|
+
.then((vulnerabilityReport) => {
|
|
83
|
+
if (!vulnerabilityReport) {
|
|
84
|
+
tools.logSuccess('OK, no vulnerabilities detected');
|
|
85
|
+
|
|
86
|
+
return notificationUtils.package.sendPackageMessage({
|
|
87
|
+
package: pkg,
|
|
88
|
+
text: 'Dependencies audit : NO vulnerabilities detected'
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
} else {
|
|
92
|
+
tools.logWarning(JSON.stringify(vulnerabilityReport));
|
|
93
|
+
|
|
94
|
+
let message = '';
|
|
95
|
+
Object.entries(vulnerabilityReport).forEach((v) => {
|
|
96
|
+
message += `${v[0]}:*${v[1]}* `;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return notificationUtils.package.sendPackageMessage({
|
|
100
|
+
package: pkg,
|
|
101
|
+
text: `Dependencies audit detected vulnerabilities : ${message}`
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
}
|
|
@@ -61,24 +61,24 @@ module.exports.getCsdrConfig = (full = true) => {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
const migrateConfig = (euircBaseFile) => {
|
|
65
|
-
|
|
64
|
+
// const migrateConfig = (euircBaseFile) => {
|
|
65
|
+
// tools.logInfo('Upgrading local euirc config to new version');
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
// const actualConfig = require(euircBaseFile);
|
|
68
|
+
// const updatedConfig = {};
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
// updatedConfig.projects = Object.keys(actualConfig.projects);
|
|
71
|
+
// updatedConfig.packages = Object.keys(actualConfig.packages)
|
|
72
|
+
// .map(p => actualConfig.packages[p])
|
|
73
|
+
// .filter((p) => {
|
|
74
|
+
// return !p.child;
|
|
75
|
+
// })
|
|
76
|
+
// .map(p => p.name);
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
// tools.writeJsonFileSync(path.join(process.cwd(), '.csdr', '.euirc.json'), updatedConfig);
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
}
|
|
80
|
+
// return updatedConfig;
|
|
81
|
+
// }
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
const getGeneratedConfig = (euircBaseFile) => {
|
|
@@ -87,9 +87,9 @@ const getGeneratedConfig = (euircBaseFile) => {
|
|
|
87
87
|
let configContent = require(euircBaseFile);
|
|
88
88
|
|
|
89
89
|
// check if actual generated config file contains new version format
|
|
90
|
-
if (!Array.isArray(configContent.projects)) {
|
|
91
|
-
|
|
92
|
-
}
|
|
90
|
+
// if (!Array.isArray(configContent.projects)) {
|
|
91
|
+
// configContent = migrateConfig(euircBaseFile);
|
|
92
|
+
// }
|
|
93
93
|
|
|
94
94
|
// fetching global csdr config
|
|
95
95
|
const globalConfig = this.getCsdrConfig();
|