@code-pushup/core 0.8.21 → 0.8.23
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/index.js +72 -82
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -566,13 +566,14 @@ function slugify(text) {
|
|
|
566
566
|
}
|
|
567
567
|
function formatBytes(bytes, decimals = 2) {
|
|
568
568
|
bytes = Math.max(bytes, 0);
|
|
569
|
-
if (!bytes)
|
|
569
|
+
if (!bytes) {
|
|
570
570
|
return "0 B";
|
|
571
|
+
}
|
|
571
572
|
const k = 1024;
|
|
572
573
|
const dm = decimals < 0 ? 0 : decimals;
|
|
573
574
|
const sizes = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
574
575
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
575
|
-
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
576
|
+
return `${Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
576
577
|
}
|
|
577
578
|
function formatDuration(duration) {
|
|
578
579
|
if (duration < 1e3) {
|
|
@@ -609,7 +610,7 @@ function logMultipleResults(results, messagePrefix, succeededCallback, failedCal
|
|
|
609
610
|
}
|
|
610
611
|
}
|
|
611
612
|
function logPromiseResults(results, logMessage, callback) {
|
|
612
|
-
if (results.length) {
|
|
613
|
+
if (results.length > 0) {
|
|
613
614
|
if (results[0]?.status === "fulfilled") {
|
|
614
615
|
console.info(logMessage);
|
|
615
616
|
} else {
|
|
@@ -658,9 +659,8 @@ async function ensureDirectoryExists(baseDir) {
|
|
|
658
659
|
function logMultipleFileResults(fileResults, messagePrefix) {
|
|
659
660
|
const succeededCallback = (result) => {
|
|
660
661
|
const [fileName, size] = result.value;
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
);
|
|
662
|
+
const formattedSize = size ? ` (${chalk.gray(formatBytes(size))})` : "";
|
|
663
|
+
console.info(`- ${chalk.bold(fileName)}${formattedSize}`);
|
|
664
664
|
};
|
|
665
665
|
const failedCallback = (result) => {
|
|
666
666
|
console.warn(`- ${chalk.bold(result.reason)}`);
|
|
@@ -689,6 +689,7 @@ async function importEsmModule(options) {
|
|
|
689
689
|
}
|
|
690
690
|
|
|
691
691
|
// packages/utils/src/lib/reports/constants.ts
|
|
692
|
+
var TERMINAL_WIDTH = 80;
|
|
692
693
|
var NEW_LINE = "\n";
|
|
693
694
|
var SCORE_COLOR_RANGE = {
|
|
694
695
|
GREEN_MIN: 0.9,
|
|
@@ -757,28 +758,20 @@ function getSeverityIcon(severity) {
|
|
|
757
758
|
return "\u2139\uFE0F";
|
|
758
759
|
}
|
|
759
760
|
function calcDuration(start, stop) {
|
|
760
|
-
stop
|
|
761
|
+
stop ??= performance.now();
|
|
761
762
|
return Math.floor(stop - start);
|
|
762
763
|
}
|
|
763
764
|
function countCategoryAudits(refs, plugins) {
|
|
764
765
|
const groupLookup = plugins.reduce(
|
|
765
766
|
(lookup, plugin) => {
|
|
766
|
-
if (
|
|
767
|
+
if (plugin.groups.length === 0) {
|
|
767
768
|
return lookup;
|
|
768
769
|
}
|
|
769
770
|
return {
|
|
770
771
|
...lookup,
|
|
771
|
-
[plugin.slug]:
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
return {
|
|
775
|
-
...groupLookup2,
|
|
776
|
-
[group.slug]: group
|
|
777
|
-
};
|
|
778
|
-
},
|
|
779
|
-
{}
|
|
780
|
-
)
|
|
781
|
-
}
|
|
772
|
+
[plugin.slug]: Object.fromEntries(
|
|
773
|
+
plugin.groups.map((group) => [group.slug, group])
|
|
774
|
+
)
|
|
782
775
|
};
|
|
783
776
|
},
|
|
784
777
|
{}
|
|
@@ -786,7 +779,7 @@ function countCategoryAudits(refs, plugins) {
|
|
|
786
779
|
return refs.reduce((acc, ref) => {
|
|
787
780
|
if (ref.type === "group") {
|
|
788
781
|
const groupRefs = groupLookup[ref.plugin]?.[ref.slug]?.refs;
|
|
789
|
-
return acc + (groupRefs?.length
|
|
782
|
+
return acc + (groupRefs?.length ?? 0);
|
|
790
783
|
}
|
|
791
784
|
return acc + 1;
|
|
792
785
|
}, 0);
|
|
@@ -892,7 +885,7 @@ function compareIssues(a, b) {
|
|
|
892
885
|
return 1;
|
|
893
886
|
}
|
|
894
887
|
if (a.source?.file !== b.source?.file) {
|
|
895
|
-
return a.source?.file.localeCompare(b.source?.file || "")
|
|
888
|
+
return a.source?.file.localeCompare(b.source?.file || "") ?? 0;
|
|
896
889
|
}
|
|
897
890
|
if (!a.source?.position && b.source?.position) {
|
|
898
891
|
return -1;
|
|
@@ -901,7 +894,7 @@ function compareIssues(a, b) {
|
|
|
901
894
|
return 1;
|
|
902
895
|
}
|
|
903
896
|
if (a.source?.position?.startLine !== b.source?.position?.startLine) {
|
|
904
|
-
return (a.source?.position?.startLine
|
|
897
|
+
return (a.source?.position?.startLine ?? 0) - (b.source?.position?.startLine ?? 0);
|
|
905
898
|
}
|
|
906
899
|
return 0;
|
|
907
900
|
}
|
|
@@ -919,12 +912,12 @@ var ProcessError = class extends Error {
|
|
|
919
912
|
}
|
|
920
913
|
};
|
|
921
914
|
function executeProcess(cfg) {
|
|
922
|
-
const { observer, cwd } = cfg;
|
|
923
|
-
const { onStdout, onError, onComplete } = observer
|
|
915
|
+
const { observer, cwd, command, args } = cfg;
|
|
916
|
+
const { onStdout, onError, onComplete } = observer ?? {};
|
|
924
917
|
const date = (/* @__PURE__ */ new Date()).toISOString();
|
|
925
918
|
const start = performance.now();
|
|
926
919
|
return new Promise((resolve, reject) => {
|
|
927
|
-
const process2 = spawn(
|
|
920
|
+
const process2 = spawn(command, args, { cwd, shell: true });
|
|
928
921
|
let stdout = "";
|
|
929
922
|
let stderr = "";
|
|
930
923
|
process2.stdout.on("data", (data) => {
|
|
@@ -1058,7 +1051,7 @@ function style(text, styles = ["b"]) {
|
|
|
1058
1051
|
|
|
1059
1052
|
// packages/utils/src/lib/reports/md/headline.ts
|
|
1060
1053
|
function headline(text, hierarchy = 1) {
|
|
1061
|
-
return `${
|
|
1054
|
+
return `${"#".repeat(hierarchy)} ${text}`;
|
|
1062
1055
|
}
|
|
1063
1056
|
function h2(text) {
|
|
1064
1057
|
return headline(text, 2);
|
|
@@ -1088,45 +1081,50 @@ function tableMd(data, align) {
|
|
|
1088
1081
|
if (data.length === 0) {
|
|
1089
1082
|
throw new Error("Data can't be empty");
|
|
1090
1083
|
}
|
|
1091
|
-
align
|
|
1092
|
-
const
|
|
1093
|
-
const secondRow =
|
|
1094
|
-
return
|
|
1084
|
+
align ??= data[0]?.map(() => "c");
|
|
1085
|
+
const tableContent = data.map((arr) => `|${arr.join("|")}|`);
|
|
1086
|
+
const secondRow = `|${align?.map((s) => alignString.get(s)).join("|")}|`;
|
|
1087
|
+
return tableContent.shift() + NEW_LINE + secondRow + NEW_LINE + tableContent.join(NEW_LINE);
|
|
1095
1088
|
}
|
|
1096
1089
|
function tableHtml(data) {
|
|
1097
1090
|
if (data.length === 0) {
|
|
1098
1091
|
throw new Error("Data can't be empty");
|
|
1099
1092
|
}
|
|
1100
|
-
const
|
|
1093
|
+
const tableContent = data.map((arr, index) => {
|
|
1101
1094
|
if (index === 0) {
|
|
1102
|
-
|
|
1095
|
+
const headerRow = arr.map((s) => `<th>${s}</th>`).join("");
|
|
1096
|
+
return `<tr>${headerRow}</tr>`;
|
|
1103
1097
|
}
|
|
1104
|
-
|
|
1098
|
+
const row = arr.map((s) => `<td>${s}</td>`).join("");
|
|
1099
|
+
return `<tr>${row}</tr>`;
|
|
1105
1100
|
});
|
|
1106
|
-
return
|
|
1101
|
+
return `<table>${tableContent.join("")}</table>`;
|
|
1107
1102
|
}
|
|
1108
1103
|
|
|
1109
1104
|
// packages/utils/src/lib/reports/generate-md-report.ts
|
|
1110
1105
|
function generateMdReport(report, commitData) {
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1106
|
+
return (
|
|
1107
|
+
// header section
|
|
1108
|
+
// eslint-disable-next-line prefer-template
|
|
1109
|
+
reportToHeaderSection() + NEW_LINE + // overview section
|
|
1110
|
+
reportToOverviewSection(report) + NEW_LINE + NEW_LINE + // categories section
|
|
1111
|
+
reportToCategoriesSection(report) + NEW_LINE + NEW_LINE + // audits section
|
|
1112
|
+
reportToAuditsSection(report) + NEW_LINE + NEW_LINE + // about section
|
|
1113
|
+
reportToAboutSection(report, commitData) + NEW_LINE + NEW_LINE + // footer section
|
|
1114
|
+
`${FOOTER_PREFIX} ${link(README_LINK, "Code PushUp")}`
|
|
1115
|
+
);
|
|
1118
1116
|
}
|
|
1119
1117
|
function reportToHeaderSection() {
|
|
1120
1118
|
return headline(reportHeadlineText) + NEW_LINE;
|
|
1121
1119
|
}
|
|
1122
1120
|
function reportToOverviewSection(report) {
|
|
1123
|
-
const { categories } = report;
|
|
1121
|
+
const { categories, plugins } = report;
|
|
1124
1122
|
const tableContent = [
|
|
1125
1123
|
reportOverviewTableHeaders,
|
|
1126
1124
|
...categories.map(({ title, refs, score }) => [
|
|
1127
1125
|
link(`#${slugify(title)}`, title),
|
|
1128
1126
|
`${getRoundScoreMarker(score)} ${style(formatReportScore(score))}`,
|
|
1129
|
-
countCategoryAudits(refs,
|
|
1127
|
+
countCategoryAudits(refs, plugins).toString()
|
|
1130
1128
|
])
|
|
1131
1129
|
];
|
|
1132
1130
|
return tableMd(tableContent, ["l", "c", "c"]);
|
|
@@ -1262,7 +1260,10 @@ function reportToAboutSection(report, commitData) {
|
|
|
1262
1260
|
formatDuration(duration2)
|
|
1263
1261
|
])
|
|
1264
1262
|
];
|
|
1265
|
-
return
|
|
1263
|
+
return (
|
|
1264
|
+
// eslint-disable-next-line prefer-template
|
|
1265
|
+
h2("About") + NEW_LINE + NEW_LINE + `Report was created by [Code PushUp](${README_LINK}) on ${date}.` + NEW_LINE + NEW_LINE + tableMd(reportMetaTable, ["l", "c", "c", "c", "c", "c"]) + NEW_LINE + NEW_LINE + "The following plugins were run:" + NEW_LINE + NEW_LINE + tableMd(pluginMetaTable, ["l", "c", "c", "c"])
|
|
1266
|
+
);
|
|
1266
1267
|
}
|
|
1267
1268
|
function getDocsAndDescription({
|
|
1268
1269
|
docsUrl,
|
|
@@ -1296,13 +1297,7 @@ function addLine(line = "") {
|
|
|
1296
1297
|
return line + NEW_LINE;
|
|
1297
1298
|
}
|
|
1298
1299
|
function generateStdoutSummary(report) {
|
|
1299
|
-
|
|
1300
|
-
output += addLine(reportToHeaderSection2(report));
|
|
1301
|
-
output += addLine();
|
|
1302
|
-
output += addLine(reportToDetailSection(report));
|
|
1303
|
-
output += addLine(reportToOverviewSection2(report));
|
|
1304
|
-
output += addLine(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
|
|
1305
|
-
return output;
|
|
1300
|
+
return addLine(reportToHeaderSection2(report)) + addLine() + addLine(reportToDetailSection(report)) + addLine(reportToOverviewSection2(report)) + addLine(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
|
|
1306
1301
|
}
|
|
1307
1302
|
function reportToHeaderSection2(report) {
|
|
1308
1303
|
const { packageName, version: version2 } = report;
|
|
@@ -1310,12 +1305,9 @@ function reportToHeaderSection2(report) {
|
|
|
1310
1305
|
}
|
|
1311
1306
|
function reportToDetailSection(report) {
|
|
1312
1307
|
const { plugins } = report;
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
output += addLine(chalk3.magentaBright.bold(`${title} audits`));
|
|
1317
|
-
output += addLine();
|
|
1318
|
-
const ui = cliui({ width: 80 });
|
|
1308
|
+
return plugins.reduce((acc, plugin) => {
|
|
1309
|
+
const { title, audits } = plugin;
|
|
1310
|
+
const ui = cliui({ width: TERMINAL_WIDTH });
|
|
1319
1311
|
audits.forEach(({ score, title: title2, displayValue, value }) => {
|
|
1320
1312
|
ui.div(
|
|
1321
1313
|
{
|
|
@@ -1325,6 +1317,7 @@ function reportToDetailSection(report) {
|
|
|
1325
1317
|
},
|
|
1326
1318
|
{
|
|
1327
1319
|
text: title2,
|
|
1320
|
+
// eslint-disable-next-line no-magic-numbers
|
|
1328
1321
|
padding: [0, 3, 0, 0]
|
|
1329
1322
|
},
|
|
1330
1323
|
{
|
|
@@ -1334,17 +1327,13 @@ function reportToDetailSection(report) {
|
|
|
1334
1327
|
}
|
|
1335
1328
|
);
|
|
1336
1329
|
});
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
});
|
|
1340
|
-
return output;
|
|
1330
|
+
return acc + addLine() + addLine(chalk3.magentaBright.bold(`${title} audits`)) + addLine() + addLine(ui.toString()) + addLine();
|
|
1331
|
+
}, "");
|
|
1341
1332
|
}
|
|
1342
1333
|
function reportToOverviewSection2({
|
|
1343
1334
|
categories,
|
|
1344
1335
|
plugins
|
|
1345
1336
|
}) {
|
|
1346
|
-
let output = addLine(chalk3.magentaBright.bold("Categories"));
|
|
1347
|
-
output += addLine();
|
|
1348
1337
|
const table = new Table({
|
|
1349
1338
|
head: reportRawOverviewTableHeaders,
|
|
1350
1339
|
colAligns: ["left", "right", "right"],
|
|
@@ -1359,8 +1348,7 @@ function reportToOverviewSection2({
|
|
|
1359
1348
|
countCategoryAudits(refs, plugins)
|
|
1360
1349
|
])
|
|
1361
1350
|
);
|
|
1362
|
-
|
|
1363
|
-
return output;
|
|
1351
|
+
return addLine(chalk3.magentaBright.bold("Categories")) + addLine() + addLine(table.toString());
|
|
1364
1352
|
}
|
|
1365
1353
|
function withColor({ score, text }) {
|
|
1366
1354
|
const formattedScore = text ?? formatReportScore(score);
|
|
@@ -1414,28 +1402,28 @@ function scoreReport(report) {
|
|
|
1414
1402
|
const scoredReport = deepClone(report);
|
|
1415
1403
|
const allScoredAuditsAndGroups = /* @__PURE__ */ new Map();
|
|
1416
1404
|
scoredReport.plugins?.forEach((plugin) => {
|
|
1417
|
-
const { audits } = plugin;
|
|
1405
|
+
const { slug, audits } = plugin;
|
|
1418
1406
|
const groups = plugin.groups || [];
|
|
1419
1407
|
audits.forEach((audit) => {
|
|
1420
|
-
const key = `${
|
|
1421
|
-
audit.plugin =
|
|
1408
|
+
const key = `${slug}-${audit.slug}-audit`;
|
|
1409
|
+
audit.plugin = slug;
|
|
1422
1410
|
allScoredAuditsAndGroups.set(key, audit);
|
|
1423
1411
|
});
|
|
1424
1412
|
function groupScoreFn(ref) {
|
|
1425
1413
|
const score = allScoredAuditsAndGroups.get(
|
|
1426
|
-
`${
|
|
1414
|
+
`${slug}-${ref.slug}-audit`
|
|
1427
1415
|
)?.score;
|
|
1428
1416
|
if (score == null) {
|
|
1429
1417
|
throw new Error(
|
|
1430
|
-
`Group has invalid ref - audit with slug ${
|
|
1418
|
+
`Group has invalid ref - audit with slug ${slug}-${ref.slug}-audit not found`
|
|
1431
1419
|
);
|
|
1432
1420
|
}
|
|
1433
1421
|
return score;
|
|
1434
1422
|
}
|
|
1435
1423
|
groups.forEach((group) => {
|
|
1436
|
-
const key = `${
|
|
1424
|
+
const key = `${slug}-${group.slug}-group`;
|
|
1437
1425
|
group.score = calculateScore(group.refs, groupScoreFn);
|
|
1438
|
-
group.plugin =
|
|
1426
|
+
group.plugin = slug;
|
|
1439
1427
|
allScoredAuditsAndGroups.set(key, group);
|
|
1440
1428
|
});
|
|
1441
1429
|
plugin.groups = groups;
|
|
@@ -1455,7 +1443,7 @@ function scoreReport(report) {
|
|
|
1455
1443
|
category.score = calculateScore(category.refs, catScoreFn);
|
|
1456
1444
|
scoredCategoriesMap.set(category.slug, category);
|
|
1457
1445
|
}
|
|
1458
|
-
scoredReport.categories =
|
|
1446
|
+
scoredReport.categories = [...scoredCategoriesMap.values()];
|
|
1459
1447
|
return scoredReport;
|
|
1460
1448
|
}
|
|
1461
1449
|
|
|
@@ -1481,7 +1469,7 @@ function sortReport(report) {
|
|
|
1481
1469
|
...groups,
|
|
1482
1470
|
...audits.sort(compareCategoryAudits)
|
|
1483
1471
|
];
|
|
1484
|
-
const sortedRefs = category.refs.
|
|
1472
|
+
const sortedRefs = [...category.refs].sort((a, b) => {
|
|
1485
1473
|
const aIndex = sortedAuditsAndGroups.findIndex(
|
|
1486
1474
|
(ref) => ref.slug === a.slug
|
|
1487
1475
|
);
|
|
@@ -1494,13 +1482,15 @@ function sortReport(report) {
|
|
|
1494
1482
|
});
|
|
1495
1483
|
const sortedPlugins = plugins.map((plugin) => ({
|
|
1496
1484
|
...plugin,
|
|
1497
|
-
audits: plugin.audits.sort(compareAudits).map(
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1485
|
+
audits: [...plugin.audits].sort(compareAudits).map(
|
|
1486
|
+
(audit) => audit.details?.issues ? {
|
|
1487
|
+
...audit,
|
|
1488
|
+
details: {
|
|
1489
|
+
...audit.details,
|
|
1490
|
+
issues: [...audit.details.issues].sort(compareIssues)
|
|
1491
|
+
}
|
|
1492
|
+
} : audit
|
|
1493
|
+
)
|
|
1504
1494
|
}));
|
|
1505
1495
|
return {
|
|
1506
1496
|
...report,
|
|
@@ -1706,7 +1696,7 @@ function auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits)
|
|
|
1706
1696
|
|
|
1707
1697
|
// packages/core/package.json
|
|
1708
1698
|
var name = "@code-pushup/core";
|
|
1709
|
-
var version = "0.8.
|
|
1699
|
+
var version = "0.8.23";
|
|
1710
1700
|
|
|
1711
1701
|
// packages/core/src/lib/implementation/collect.ts
|
|
1712
1702
|
async function collect(options) {
|