@code-pushup/utils 0.27.1 → 0.29.0
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 +354 -93
- package/package.json +1 -1
- package/src/index.d.ts +5 -4
package/index.js
CHANGED
|
@@ -1004,6 +1004,9 @@ function style(text, styles = ["b"]) {
|
|
|
1004
1004
|
function headline(text, hierarchy = 1) {
|
|
1005
1005
|
return `${"#".repeat(hierarchy)} ${text}`;
|
|
1006
1006
|
}
|
|
1007
|
+
function h1(text) {
|
|
1008
|
+
return headline(text, 1);
|
|
1009
|
+
}
|
|
1007
1010
|
function h2(text) {
|
|
1008
1011
|
return headline(text, 2);
|
|
1009
1012
|
}
|
|
@@ -1011,6 +1014,11 @@ function h3(text) {
|
|
|
1011
1014
|
return headline(text, 3);
|
|
1012
1015
|
}
|
|
1013
1016
|
|
|
1017
|
+
// packages/utils/src/lib/reports/md/image.ts
|
|
1018
|
+
function image(src, alt) {
|
|
1019
|
+
return ``;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1014
1022
|
// packages/utils/src/lib/reports/md/link.ts
|
|
1015
1023
|
function link2(href, text) {
|
|
1016
1024
|
return `[${text || href}](${href})`;
|
|
@@ -1022,6 +1030,11 @@ function li(text, order = "unordered") {
|
|
|
1022
1030
|
return `${style2} ${text}`;
|
|
1023
1031
|
}
|
|
1024
1032
|
|
|
1033
|
+
// packages/utils/src/lib/reports/md/paragraphs.ts
|
|
1034
|
+
function paragraphs(...sections) {
|
|
1035
|
+
return sections.filter(Boolean).join("\n\n");
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1025
1038
|
// packages/utils/src/lib/reports/md/table.ts
|
|
1026
1039
|
var alignString = /* @__PURE__ */ new Map([
|
|
1027
1040
|
["l", ":--"],
|
|
@@ -1056,6 +1069,10 @@ function tableHtml(data) {
|
|
|
1056
1069
|
function formatReportScore(score) {
|
|
1057
1070
|
return Math.round(score * 100).toString();
|
|
1058
1071
|
}
|
|
1072
|
+
function formatScoreWithColor(score, options) {
|
|
1073
|
+
const styledNumber = options?.skipBold ? formatReportScore(score) : style(formatReportScore(score));
|
|
1074
|
+
return `${getRoundScoreMarker(score)} ${styledNumber}`;
|
|
1075
|
+
}
|
|
1059
1076
|
function getRoundScoreMarker(score) {
|
|
1060
1077
|
if (score >= SCORE_COLOR_RANGE.GREEN_MIN) {
|
|
1061
1078
|
return "\u{1F7E2}";
|
|
@@ -1074,6 +1091,30 @@ function getSquaredScoreMarker(score) {
|
|
|
1074
1091
|
}
|
|
1075
1092
|
return "\u{1F7E5}";
|
|
1076
1093
|
}
|
|
1094
|
+
function getDiffMarker(diff) {
|
|
1095
|
+
if (diff > 0) {
|
|
1096
|
+
return "\u2191";
|
|
1097
|
+
}
|
|
1098
|
+
if (diff < 0) {
|
|
1099
|
+
return "\u2193";
|
|
1100
|
+
}
|
|
1101
|
+
return "";
|
|
1102
|
+
}
|
|
1103
|
+
function colorByScoreDiff(text, diff) {
|
|
1104
|
+
const color = diff > 0 ? "green" : diff < 0 ? "red" : "gray";
|
|
1105
|
+
return shieldsBadge(text, color);
|
|
1106
|
+
}
|
|
1107
|
+
function shieldsBadge(text, color) {
|
|
1108
|
+
return image(
|
|
1109
|
+
`https://img.shields.io/badge/${encodeURIComponent(text)}-${color}`,
|
|
1110
|
+
text
|
|
1111
|
+
);
|
|
1112
|
+
}
|
|
1113
|
+
function formatDiffNumber(diff) {
|
|
1114
|
+
const number = Math.abs(diff) === Number.POSITIVE_INFINITY ? "\u221E" : `${Math.abs(diff)}`;
|
|
1115
|
+
const sign = diff < 0 ? "\u2212" : "+";
|
|
1116
|
+
return `${sign}${number}`;
|
|
1117
|
+
}
|
|
1077
1118
|
function getSeverityIcon(severity) {
|
|
1078
1119
|
if (severity === "error") {
|
|
1079
1120
|
return "\u{1F6A8}";
|
|
@@ -1084,7 +1125,7 @@ function getSeverityIcon(severity) {
|
|
|
1084
1125
|
return "\u2139\uFE0F";
|
|
1085
1126
|
}
|
|
1086
1127
|
function calcDuration(start, stop) {
|
|
1087
|
-
return Math.
|
|
1128
|
+
return Math.round((stop ?? performance.now()) - start);
|
|
1088
1129
|
}
|
|
1089
1130
|
function countCategoryAudits(refs, plugins) {
|
|
1090
1131
|
const groupLookup = plugins.reduce(
|
|
@@ -1496,95 +1537,6 @@ function getProgressBar(taskName) {
|
|
|
1496
1537
|
};
|
|
1497
1538
|
}
|
|
1498
1539
|
|
|
1499
|
-
// packages/utils/src/lib/reports/log-stdout-summary.ts
|
|
1500
|
-
import chalk4 from "chalk";
|
|
1501
|
-
function log(msg = "") {
|
|
1502
|
-
ui().logger.log(msg);
|
|
1503
|
-
}
|
|
1504
|
-
function logStdoutSummary(report) {
|
|
1505
|
-
const printCategories = report.categories.length > 0;
|
|
1506
|
-
log(reportToHeaderSection(report));
|
|
1507
|
-
log();
|
|
1508
|
-
logPlugins(report);
|
|
1509
|
-
if (printCategories) {
|
|
1510
|
-
logCategories(report);
|
|
1511
|
-
}
|
|
1512
|
-
log(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
|
|
1513
|
-
log();
|
|
1514
|
-
}
|
|
1515
|
-
function reportToHeaderSection(report) {
|
|
1516
|
-
const { packageName, version } = report;
|
|
1517
|
-
return `${chalk4.bold(reportHeadlineText)} - ${packageName}@${version}`;
|
|
1518
|
-
}
|
|
1519
|
-
function logPlugins(report) {
|
|
1520
|
-
const { plugins } = report;
|
|
1521
|
-
plugins.forEach((plugin) => {
|
|
1522
|
-
const { title, audits } = plugin;
|
|
1523
|
-
log();
|
|
1524
|
-
log(chalk4.magentaBright.bold(`${title} audits`));
|
|
1525
|
-
log();
|
|
1526
|
-
audits.forEach((audit) => {
|
|
1527
|
-
ui().row([
|
|
1528
|
-
{
|
|
1529
|
-
text: applyScoreColor({ score: audit.score, text: "\u25CF" }),
|
|
1530
|
-
width: 2,
|
|
1531
|
-
padding: [0, 1, 0, 0]
|
|
1532
|
-
},
|
|
1533
|
-
{
|
|
1534
|
-
text: audit.title,
|
|
1535
|
-
// eslint-disable-next-line no-magic-numbers
|
|
1536
|
-
padding: [0, 3, 0, 0]
|
|
1537
|
-
},
|
|
1538
|
-
{
|
|
1539
|
-
text: chalk4.cyanBright(audit.displayValue || `${audit.value}`),
|
|
1540
|
-
width: 10,
|
|
1541
|
-
padding: [0, 0, 0, 0]
|
|
1542
|
-
}
|
|
1543
|
-
]);
|
|
1544
|
-
});
|
|
1545
|
-
log();
|
|
1546
|
-
});
|
|
1547
|
-
}
|
|
1548
|
-
function logCategories({ categories, plugins }) {
|
|
1549
|
-
const hAlign = (idx) => idx === 0 ? "left" : "right";
|
|
1550
|
-
const rows = categories.map(({ title, score, refs }) => [
|
|
1551
|
-
title,
|
|
1552
|
-
applyScoreColor({ score }),
|
|
1553
|
-
countCategoryAudits(refs, plugins)
|
|
1554
|
-
]);
|
|
1555
|
-
const table = ui().table();
|
|
1556
|
-
table.columnWidths([TERMINAL_WIDTH - 9 - 10 - 4, 9, 10]);
|
|
1557
|
-
table.head(
|
|
1558
|
-
reportRawOverviewTableHeaders.map((heading, idx) => ({
|
|
1559
|
-
content: chalk4.cyan(heading),
|
|
1560
|
-
hAlign: hAlign(idx)
|
|
1561
|
-
}))
|
|
1562
|
-
);
|
|
1563
|
-
rows.forEach(
|
|
1564
|
-
(row) => table.row(
|
|
1565
|
-
row.map((content, idx) => ({
|
|
1566
|
-
content: content.toString(),
|
|
1567
|
-
hAlign: hAlign(idx)
|
|
1568
|
-
}))
|
|
1569
|
-
)
|
|
1570
|
-
);
|
|
1571
|
-
log(chalk4.magentaBright.bold("Categories"));
|
|
1572
|
-
log();
|
|
1573
|
-
table.render();
|
|
1574
|
-
log();
|
|
1575
|
-
}
|
|
1576
|
-
function applyScoreColor({ score, text }) {
|
|
1577
|
-
const formattedScore = text ?? formatReportScore(score);
|
|
1578
|
-
const style2 = text ? chalk4 : chalk4.bold;
|
|
1579
|
-
if (score >= SCORE_COLOR_RANGE.GREEN_MIN) {
|
|
1580
|
-
return style2.green(formattedScore);
|
|
1581
|
-
}
|
|
1582
|
-
if (score >= SCORE_COLOR_RANGE.YELLOW_MIN) {
|
|
1583
|
-
return style2.yellow(formattedScore);
|
|
1584
|
-
}
|
|
1585
|
-
return style2.red(formattedScore);
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
1540
|
// packages/utils/src/lib/reports/flatten-plugins.ts
|
|
1589
1541
|
function listGroupsFromAllPlugins(report) {
|
|
1590
1542
|
return report.plugins.flatMap(
|
|
@@ -1603,7 +1555,7 @@ function generateMdReport(report) {
|
|
|
1603
1555
|
return (
|
|
1604
1556
|
// header section
|
|
1605
1557
|
// eslint-disable-next-line prefer-template
|
|
1606
|
-
|
|
1558
|
+
reportToHeaderSection() + NEW_LINE + // categories overview section
|
|
1607
1559
|
(printCategories ? reportToOverviewSection(report) + NEW_LINE + NEW_LINE : "") + // categories section
|
|
1608
1560
|
(printCategories ? reportToCategoriesSection(report) + NEW_LINE + NEW_LINE : "") + // audits section
|
|
1609
1561
|
reportToAuditsSection(report) + NEW_LINE + NEW_LINE + // about section
|
|
@@ -1611,7 +1563,7 @@ function generateMdReport(report) {
|
|
|
1611
1563
|
`${FOOTER_PREFIX} ${link2(README_LINK, "Code PushUp")}`
|
|
1612
1564
|
);
|
|
1613
1565
|
}
|
|
1614
|
-
function
|
|
1566
|
+
function reportToHeaderSection() {
|
|
1615
1567
|
return headline(reportHeadlineText) + NEW_LINE;
|
|
1616
1568
|
}
|
|
1617
1569
|
function reportToOverviewSection(report) {
|
|
@@ -1734,7 +1686,7 @@ function reportToDetailsSection(audit) {
|
|
|
1734
1686
|
function reportToAboutSection(report) {
|
|
1735
1687
|
const date = formatDate(/* @__PURE__ */ new Date());
|
|
1736
1688
|
const { duration, version, commit, plugins, categories } = report;
|
|
1737
|
-
const commitInfo = commit ? `${commit.message} (${commit.hash
|
|
1689
|
+
const commitInfo = commit ? `${commit.message} (${commit.hash})` : "N/A";
|
|
1738
1690
|
const reportMetaTable = [
|
|
1739
1691
|
reportMetaTableHeaders,
|
|
1740
1692
|
[
|
|
@@ -1784,6 +1736,314 @@ function getAuditResult(audit, isHtml = false) {
|
|
|
1784
1736
|
return isHtml ? `<b>${displayValue || value}</b>` : style(String(displayValue || value));
|
|
1785
1737
|
}
|
|
1786
1738
|
|
|
1739
|
+
// packages/utils/src/lib/reports/generate-md-reports-diff.ts
|
|
1740
|
+
var MAX_ROWS = 100;
|
|
1741
|
+
function generateMdReportsDiff(diff) {
|
|
1742
|
+
return paragraphs(
|
|
1743
|
+
formatDiffHeaderSection(diff),
|
|
1744
|
+
formatDiffCategoriesSection(diff),
|
|
1745
|
+
formatDiffGroupsSection(diff),
|
|
1746
|
+
formatDiffAuditsSection(diff)
|
|
1747
|
+
);
|
|
1748
|
+
}
|
|
1749
|
+
function formatDiffHeaderSection(diff) {
|
|
1750
|
+
const outcomeTexts = {
|
|
1751
|
+
positive: `\u{1F973} Code PushUp report has ${style("improved")}`,
|
|
1752
|
+
negative: `\u{1F61F} Code PushUp report has ${style("regressed")}`,
|
|
1753
|
+
mixed: `\u{1F928} Code PushUp report has both ${style(
|
|
1754
|
+
"improvements and regressions"
|
|
1755
|
+
)}`,
|
|
1756
|
+
unchanged: `\u{1F610} Code PushUp report is ${style("unchanged")}`
|
|
1757
|
+
};
|
|
1758
|
+
const outcome = mergeDiffOutcomes(
|
|
1759
|
+
changesToDiffOutcomes([
|
|
1760
|
+
...diff.categories.changed,
|
|
1761
|
+
...diff.groups.changed,
|
|
1762
|
+
...diff.audits.changed
|
|
1763
|
+
])
|
|
1764
|
+
);
|
|
1765
|
+
const styleCommits = (commits) => `compared target commit ${commits.after.hash} with source commit ${commits.before.hash}`;
|
|
1766
|
+
return paragraphs(
|
|
1767
|
+
h1("Code PushUp"),
|
|
1768
|
+
diff.commits ? `${outcomeTexts[outcome]} \u2013 ${styleCommits(diff.commits)}.` : `${outcomeTexts[outcome]}.`
|
|
1769
|
+
);
|
|
1770
|
+
}
|
|
1771
|
+
function formatDiffCategoriesSection(diff) {
|
|
1772
|
+
const { changed, unchanged, added } = diff.categories;
|
|
1773
|
+
const categoriesCount = changed.length + unchanged.length + added.length;
|
|
1774
|
+
const hasChanges = unchanged.length < categoriesCount;
|
|
1775
|
+
if (categoriesCount === 0) {
|
|
1776
|
+
return "";
|
|
1777
|
+
}
|
|
1778
|
+
return paragraphs(
|
|
1779
|
+
h2("\u{1F3F7}\uFE0F Categories"),
|
|
1780
|
+
categoriesCount > 0 && tableMd(
|
|
1781
|
+
[
|
|
1782
|
+
[
|
|
1783
|
+
"\u{1F3F7}\uFE0F Category",
|
|
1784
|
+
hasChanges ? "\u2B50 Current score" : "\u2B50 Score",
|
|
1785
|
+
"\u2B50 Previous score",
|
|
1786
|
+
"\u{1F504} Score change"
|
|
1787
|
+
],
|
|
1788
|
+
...sortChanges(changed).map((category) => [
|
|
1789
|
+
category.title,
|
|
1790
|
+
formatScoreWithColor(category.scores.after),
|
|
1791
|
+
formatScoreWithColor(category.scores.before, { skipBold: true }),
|
|
1792
|
+
formatScoreChange(category.scores.diff)
|
|
1793
|
+
]),
|
|
1794
|
+
...added.map((category) => [
|
|
1795
|
+
category.title,
|
|
1796
|
+
formatScoreWithColor(category.score),
|
|
1797
|
+
style("n/a (\\*)", ["i"]),
|
|
1798
|
+
style("n/a (\\*)", ["i"])
|
|
1799
|
+
]),
|
|
1800
|
+
...unchanged.map((category) => [
|
|
1801
|
+
category.title,
|
|
1802
|
+
formatScoreWithColor(category.score),
|
|
1803
|
+
formatScoreWithColor(category.score, { skipBold: true }),
|
|
1804
|
+
"\u2013"
|
|
1805
|
+
])
|
|
1806
|
+
].map((row) => hasChanges ? row : row.slice(0, 2)),
|
|
1807
|
+
hasChanges ? ["l", "c", "c", "c"] : ["l", "c"]
|
|
1808
|
+
),
|
|
1809
|
+
added.length > 0 && style("(\\*) New category.", ["i"])
|
|
1810
|
+
);
|
|
1811
|
+
}
|
|
1812
|
+
function formatDiffGroupsSection(diff) {
|
|
1813
|
+
if (diff.groups.changed.length + diff.groups.unchanged.length === 0) {
|
|
1814
|
+
return "";
|
|
1815
|
+
}
|
|
1816
|
+
return paragraphs(
|
|
1817
|
+
h2("\u{1F397}\uFE0F Groups"),
|
|
1818
|
+
formatGroupsOrAuditsDetails("group", diff.groups, {
|
|
1819
|
+
headings: [
|
|
1820
|
+
"\u{1F50C} Plugin",
|
|
1821
|
+
"\u{1F5C3}\uFE0F Group",
|
|
1822
|
+
"\u2B50 Current score",
|
|
1823
|
+
"\u2B50 Previous score",
|
|
1824
|
+
"\u{1F504} Score change"
|
|
1825
|
+
],
|
|
1826
|
+
rows: sortChanges(diff.groups.changed).map((group) => [
|
|
1827
|
+
group.plugin.title,
|
|
1828
|
+
group.title,
|
|
1829
|
+
formatScoreWithColor(group.scores.after),
|
|
1830
|
+
formatScoreWithColor(group.scores.before, { skipBold: true }),
|
|
1831
|
+
formatScoreChange(group.scores.diff)
|
|
1832
|
+
]),
|
|
1833
|
+
align: ["l", "l", "c", "c", "c"]
|
|
1834
|
+
})
|
|
1835
|
+
);
|
|
1836
|
+
}
|
|
1837
|
+
function formatDiffAuditsSection(diff) {
|
|
1838
|
+
return paragraphs(
|
|
1839
|
+
h2("\u{1F6E1}\uFE0F Audits"),
|
|
1840
|
+
formatGroupsOrAuditsDetails("audit", diff.audits, {
|
|
1841
|
+
headings: [
|
|
1842
|
+
"\u{1F50C} Plugin",
|
|
1843
|
+
"\u{1F6E1}\uFE0F Audit",
|
|
1844
|
+
"\u{1F4CF} Current value",
|
|
1845
|
+
"\u{1F4CF} Previous value",
|
|
1846
|
+
"\u{1F504} Value change"
|
|
1847
|
+
],
|
|
1848
|
+
rows: sortChanges(diff.audits.changed).map((audit) => [
|
|
1849
|
+
audit.plugin.title,
|
|
1850
|
+
audit.title,
|
|
1851
|
+
`${getSquaredScoreMarker(audit.scores.after)} ${style(
|
|
1852
|
+
audit.displayValues.after || audit.values.after.toString()
|
|
1853
|
+
)}`,
|
|
1854
|
+
`${getSquaredScoreMarker(audit.scores.before)} ${audit.displayValues.before || audit.values.before.toString()}`,
|
|
1855
|
+
formatValueChange(audit)
|
|
1856
|
+
]),
|
|
1857
|
+
align: ["l", "l", "c", "c", "c"]
|
|
1858
|
+
})
|
|
1859
|
+
);
|
|
1860
|
+
}
|
|
1861
|
+
function formatGroupsOrAuditsDetails(token, { changed, unchanged }, table) {
|
|
1862
|
+
return changed.length === 0 ? summarizeUnchanged(token, { changed, unchanged }) : details(
|
|
1863
|
+
summarizeDiffOutcomes(changesToDiffOutcomes(changed), token),
|
|
1864
|
+
paragraphs(
|
|
1865
|
+
tableMd(
|
|
1866
|
+
[table.headings, ...table.rows.slice(0, MAX_ROWS)],
|
|
1867
|
+
table.align
|
|
1868
|
+
),
|
|
1869
|
+
changed.length > MAX_ROWS && style(
|
|
1870
|
+
`Only the ${MAX_ROWS} most affected ${pluralize(
|
|
1871
|
+
token
|
|
1872
|
+
)} are listed above for brevity.`,
|
|
1873
|
+
["i"]
|
|
1874
|
+
),
|
|
1875
|
+
unchanged.length > 0 && summarizeUnchanged(token, { changed, unchanged })
|
|
1876
|
+
)
|
|
1877
|
+
);
|
|
1878
|
+
}
|
|
1879
|
+
function formatScoreChange(diff) {
|
|
1880
|
+
const marker = getDiffMarker(diff);
|
|
1881
|
+
const text = formatDiffNumber(Math.round(diff * 100));
|
|
1882
|
+
return colorByScoreDiff(`${marker} ${text}`, diff);
|
|
1883
|
+
}
|
|
1884
|
+
function formatValueChange({
|
|
1885
|
+
values,
|
|
1886
|
+
scores
|
|
1887
|
+
}) {
|
|
1888
|
+
const marker = getDiffMarker(values.diff);
|
|
1889
|
+
const percentage = values.before === 0 ? values.diff > 0 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY : Math.round(100 * values.diff / values.before);
|
|
1890
|
+
const text = `${formatDiffNumber(percentage)}\u2009%`;
|
|
1891
|
+
return colorByScoreDiff(`${marker} ${text}`, scores.diff);
|
|
1892
|
+
}
|
|
1893
|
+
function summarizeUnchanged(token, { changed, unchanged }) {
|
|
1894
|
+
return [
|
|
1895
|
+
changed.length > 0 ? pluralizeToken(`other ${token}`, unchanged.length) : `All of ${pluralizeToken(token, unchanged.length)}`,
|
|
1896
|
+
unchanged.length === 1 ? "is" : "are",
|
|
1897
|
+
"unchanged."
|
|
1898
|
+
].join(" ");
|
|
1899
|
+
}
|
|
1900
|
+
function summarizeDiffOutcomes(outcomes, token) {
|
|
1901
|
+
return objectToEntries(countDiffOutcomes(outcomes)).filter(
|
|
1902
|
+
(entry) => entry[0] !== "unchanged" && entry[1] > 0
|
|
1903
|
+
).map(([outcome, count]) => {
|
|
1904
|
+
const formattedCount = `<strong>${count}</strong> ${pluralize(
|
|
1905
|
+
token,
|
|
1906
|
+
count
|
|
1907
|
+
)}`;
|
|
1908
|
+
switch (outcome) {
|
|
1909
|
+
case "positive":
|
|
1910
|
+
return `\u{1F44D} ${formattedCount} improved`;
|
|
1911
|
+
case "negative":
|
|
1912
|
+
return `\u{1F44E} ${formattedCount} regressed`;
|
|
1913
|
+
case "mixed":
|
|
1914
|
+
return `${formattedCount} changed without impacting score`;
|
|
1915
|
+
}
|
|
1916
|
+
}).join(", ");
|
|
1917
|
+
}
|
|
1918
|
+
function sortChanges(changes) {
|
|
1919
|
+
return [...changes].sort(
|
|
1920
|
+
(a, b) => Math.abs(b.scores.diff) - Math.abs(a.scores.diff) || Math.abs(b.values?.diff ?? 0) - Math.abs(a.values?.diff ?? 0)
|
|
1921
|
+
);
|
|
1922
|
+
}
|
|
1923
|
+
function changesToDiffOutcomes(changes) {
|
|
1924
|
+
return changes.map((change) => {
|
|
1925
|
+
if (change.scores.diff > 0) {
|
|
1926
|
+
return "positive";
|
|
1927
|
+
}
|
|
1928
|
+
if (change.scores.diff < 0) {
|
|
1929
|
+
return "negative";
|
|
1930
|
+
}
|
|
1931
|
+
if (change.values != null && change.values.diff !== 0) {
|
|
1932
|
+
return "mixed";
|
|
1933
|
+
}
|
|
1934
|
+
return "unchanged";
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
function mergeDiffOutcomes(outcomes) {
|
|
1938
|
+
if (outcomes.every((outcome) => outcome === "unchanged")) {
|
|
1939
|
+
return "unchanged";
|
|
1940
|
+
}
|
|
1941
|
+
if (outcomes.includes("positive") && !outcomes.includes("negative")) {
|
|
1942
|
+
return "positive";
|
|
1943
|
+
}
|
|
1944
|
+
if (outcomes.includes("negative") && !outcomes.includes("positive")) {
|
|
1945
|
+
return "negative";
|
|
1946
|
+
}
|
|
1947
|
+
return "mixed";
|
|
1948
|
+
}
|
|
1949
|
+
function countDiffOutcomes(outcomes) {
|
|
1950
|
+
return {
|
|
1951
|
+
positive: outcomes.filter((outcome) => outcome === "positive").length,
|
|
1952
|
+
negative: outcomes.filter((outcome) => outcome === "negative").length,
|
|
1953
|
+
mixed: outcomes.filter((outcome) => outcome === "mixed").length,
|
|
1954
|
+
unchanged: outcomes.filter((outcome) => outcome === "unchanged").length
|
|
1955
|
+
};
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
// packages/utils/src/lib/reports/log-stdout-summary.ts
|
|
1959
|
+
import chalk4 from "chalk";
|
|
1960
|
+
function log(msg = "") {
|
|
1961
|
+
ui().logger.log(msg);
|
|
1962
|
+
}
|
|
1963
|
+
function logStdoutSummary(report) {
|
|
1964
|
+
const printCategories = report.categories.length > 0;
|
|
1965
|
+
log(reportToHeaderSection2(report));
|
|
1966
|
+
log();
|
|
1967
|
+
logPlugins(report);
|
|
1968
|
+
if (printCategories) {
|
|
1969
|
+
logCategories(report);
|
|
1970
|
+
}
|
|
1971
|
+
log(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
|
|
1972
|
+
log();
|
|
1973
|
+
}
|
|
1974
|
+
function reportToHeaderSection2(report) {
|
|
1975
|
+
const { packageName, version } = report;
|
|
1976
|
+
return `${chalk4.bold(reportHeadlineText)} - ${packageName}@${version}`;
|
|
1977
|
+
}
|
|
1978
|
+
function logPlugins(report) {
|
|
1979
|
+
const { plugins } = report;
|
|
1980
|
+
plugins.forEach((plugin) => {
|
|
1981
|
+
const { title, audits } = plugin;
|
|
1982
|
+
log();
|
|
1983
|
+
log(chalk4.magentaBright.bold(`${title} audits`));
|
|
1984
|
+
log();
|
|
1985
|
+
audits.forEach((audit) => {
|
|
1986
|
+
ui().row([
|
|
1987
|
+
{
|
|
1988
|
+
text: applyScoreColor({ score: audit.score, text: "\u25CF" }),
|
|
1989
|
+
width: 2,
|
|
1990
|
+
padding: [0, 1, 0, 0]
|
|
1991
|
+
},
|
|
1992
|
+
{
|
|
1993
|
+
text: audit.title,
|
|
1994
|
+
// eslint-disable-next-line no-magic-numbers
|
|
1995
|
+
padding: [0, 3, 0, 0]
|
|
1996
|
+
},
|
|
1997
|
+
{
|
|
1998
|
+
text: chalk4.cyanBright(audit.displayValue || `${audit.value}`),
|
|
1999
|
+
width: 10,
|
|
2000
|
+
padding: [0, 0, 0, 0]
|
|
2001
|
+
}
|
|
2002
|
+
]);
|
|
2003
|
+
});
|
|
2004
|
+
log();
|
|
2005
|
+
});
|
|
2006
|
+
}
|
|
2007
|
+
function logCategories({ categories, plugins }) {
|
|
2008
|
+
const hAlign = (idx) => idx === 0 ? "left" : "right";
|
|
2009
|
+
const rows = categories.map(({ title, score, refs }) => [
|
|
2010
|
+
title,
|
|
2011
|
+
applyScoreColor({ score }),
|
|
2012
|
+
countCategoryAudits(refs, plugins)
|
|
2013
|
+
]);
|
|
2014
|
+
const table = ui().table();
|
|
2015
|
+
table.columnWidths([TERMINAL_WIDTH - 9 - 10 - 4, 9, 10]);
|
|
2016
|
+
table.head(
|
|
2017
|
+
reportRawOverviewTableHeaders.map((heading, idx) => ({
|
|
2018
|
+
content: chalk4.cyan(heading),
|
|
2019
|
+
hAlign: hAlign(idx)
|
|
2020
|
+
}))
|
|
2021
|
+
);
|
|
2022
|
+
rows.forEach(
|
|
2023
|
+
(row) => table.row(
|
|
2024
|
+
row.map((content, idx) => ({
|
|
2025
|
+
content: content.toString(),
|
|
2026
|
+
hAlign: hAlign(idx)
|
|
2027
|
+
}))
|
|
2028
|
+
)
|
|
2029
|
+
);
|
|
2030
|
+
log(chalk4.magentaBright.bold("Categories"));
|
|
2031
|
+
log();
|
|
2032
|
+
table.render();
|
|
2033
|
+
log();
|
|
2034
|
+
}
|
|
2035
|
+
function applyScoreColor({ score, text }) {
|
|
2036
|
+
const formattedScore = text ?? formatReportScore(score);
|
|
2037
|
+
const style2 = text ? chalk4 : chalk4.bold;
|
|
2038
|
+
if (score >= SCORE_COLOR_RANGE.GREEN_MIN) {
|
|
2039
|
+
return style2.green(formattedScore);
|
|
2040
|
+
}
|
|
2041
|
+
if (score >= SCORE_COLOR_RANGE.YELLOW_MIN) {
|
|
2042
|
+
return style2.yellow(formattedScore);
|
|
2043
|
+
}
|
|
2044
|
+
return style2.red(formattedScore);
|
|
2045
|
+
}
|
|
2046
|
+
|
|
1787
2047
|
// packages/utils/src/lib/reports/scoring.ts
|
|
1788
2048
|
var GroupRefInvalidError = class extends Error {
|
|
1789
2049
|
constructor(auditSlug, pluginSlug) {
|
|
@@ -1965,6 +2225,7 @@ export {
|
|
|
1965
2225
|
formatDuration,
|
|
1966
2226
|
formatGitPath,
|
|
1967
2227
|
generateMdReport,
|
|
2228
|
+
generateMdReportsDiff,
|
|
1968
2229
|
getCurrentBranchOrTag,
|
|
1969
2230
|
getGitRoot,
|
|
1970
2231
|
getLatestCommit,
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
export { exists } from '@code-pushup/models';
|
|
2
|
-
export { Diff,
|
|
2
|
+
export { Diff, comparePairs, matchArrayItemsByKey } from './lib/diff';
|
|
3
3
|
export { ProcessConfig, ProcessError, ProcessObserver, ProcessResult, executeProcess, } from './lib/execute-process';
|
|
4
4
|
export { CrawlFileSystemOptions, FileResult, MultipleFileResults, crawlFileSystem, directoryExists, ensureDirectoryExists, fileExists, findLineNumberInText, importEsmModule, logMultipleFileResults, pluginWorkDir, readJsonFile, readTextFile, removeDirectoryIfExists, } from './lib/file-system';
|
|
5
5
|
export { filterItemRefsBy } from './lib/filter';
|
|
6
6
|
export { formatBytes, formatDuration, pluralize, pluralizeToken, slugify, truncateDescription, truncateIssueMessage, truncateText, truncateTitle, } from './lib/formatting';
|
|
7
|
-
export { formatGitPath, getGitRoot, getLatestCommit,
|
|
7
|
+
export { formatGitPath, getCurrentBranchOrTag, getGitRoot, getLatestCommit, safeCheckout, toGitPath, } from './lib/git';
|
|
8
8
|
export { groupByStatus } from './lib/group-by-status';
|
|
9
9
|
export { isPromiseFulfilledResult, isPromiseRejectedResult, } from './lib/guards';
|
|
10
10
|
export { logMultipleResults } from './lib/log-results';
|
|
11
|
+
export { CliUi, Column, link, ui } from './lib/logging';
|
|
11
12
|
export { ProgressBar, getProgressBar } from './lib/progress';
|
|
12
|
-
export { logStdoutSummary } from './lib/reports/log-stdout-summary';
|
|
13
13
|
export { CODE_PUSHUP_DOMAIN, FOOTER_PREFIX, README_LINK, TERMINAL_WIDTH, } from './lib/reports/constants';
|
|
14
14
|
export { listAuditsFromAllPlugins, listGroupsFromAllPlugins, } from './lib/reports/flatten-plugins';
|
|
15
15
|
export { generateMdReport } from './lib/reports/generate-md-report';
|
|
16
|
+
export { generateMdReportsDiff } from './lib/reports/generate-md-reports-diff';
|
|
17
|
+
export { logStdoutSummary } from './lib/reports/log-stdout-summary';
|
|
16
18
|
export { scoreReport } from './lib/reports/scoring';
|
|
17
19
|
export { sortReport } from './lib/reports/sorting';
|
|
18
20
|
export { ScoredCategoryConfig, ScoredGroup, ScoredReport, } from './lib/reports/types';
|
|
19
21
|
export { calcDuration, compareIssueSeverity, loadReport, } from './lib/reports/utils';
|
|
20
22
|
export { CliArgsObject, capitalize, countOccurrences, distinct, factorOf, objectToCliArgs, objectToEntries, objectToKeys, toArray, toNumberPrecision, toOrdinal, toUnixNewlines, toUnixPath, } from './lib/transform';
|
|
21
23
|
export { verboseUtils } from './lib/verbose-utils';
|
|
22
|
-
export { link, ui, CliUi, Column } from './lib/logging';
|