@code-pushup/utils 0.27.1 → 0.28.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.
Files changed (3) hide show
  1. package/index.js +358 -92
  2. package/package.json +1 -1
  3. 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 `![${alt}](${src})`;
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.floor((stop ?? performance.now()) - start);
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
- reportToHeaderSection2() + NEW_LINE + // categories overview section
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 reportToHeaderSection2() {
1566
+ function reportToHeaderSection() {
1615
1567
  return headline(reportHeadlineText) + NEW_LINE;
1616
1568
  }
1617
1569
  function reportToOverviewSection(report) {
@@ -1784,6 +1736,319 @@ 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 styleCommit = (commit) => style(commit.hash.slice(0, 7), ["c"]);
1766
+ const styleCommits = (commits) => {
1767
+ const src = styleCommit(commits.before);
1768
+ const tgt = styleCommit(commits.after);
1769
+ return `compared target commit ${tgt} with source commit ${src}`;
1770
+ };
1771
+ return paragraphs(
1772
+ h1("Code PushUp"),
1773
+ diff.commits ? `${outcomeTexts[outcome]} \u2013 ${styleCommits(diff.commits)}.` : `${outcomeTexts[outcome]}.`
1774
+ );
1775
+ }
1776
+ function formatDiffCategoriesSection(diff) {
1777
+ const { changed, unchanged, added } = diff.categories;
1778
+ const categoriesCount = changed.length + unchanged.length + added.length;
1779
+ const hasChanges = unchanged.length < categoriesCount;
1780
+ if (categoriesCount === 0) {
1781
+ return "";
1782
+ }
1783
+ return paragraphs(
1784
+ h2("\u{1F3F7}\uFE0F Categories"),
1785
+ categoriesCount > 0 && tableMd(
1786
+ [
1787
+ [
1788
+ "\u{1F3F7}\uFE0F Category",
1789
+ hasChanges ? "\u2B50 Current score" : "\u2B50 Score",
1790
+ "\u2B50 Previous score",
1791
+ "\u{1F504} Score change"
1792
+ ],
1793
+ ...sortChanges(changed).map((category) => [
1794
+ category.title,
1795
+ formatScoreWithColor(category.scores.after),
1796
+ formatScoreWithColor(category.scores.before, { skipBold: true }),
1797
+ formatScoreChange(category.scores.diff)
1798
+ ]),
1799
+ ...added.map((category) => [
1800
+ category.title,
1801
+ formatScoreWithColor(category.score),
1802
+ style("n/a (\\*)", ["i"]),
1803
+ style("n/a (\\*)", ["i"])
1804
+ ]),
1805
+ ...unchanged.map((category) => [
1806
+ category.title,
1807
+ formatScoreWithColor(category.score),
1808
+ formatScoreWithColor(category.score, { skipBold: true }),
1809
+ "\u2013"
1810
+ ])
1811
+ ].map((row) => hasChanges ? row : row.slice(0, 2)),
1812
+ hasChanges ? ["l", "c", "c", "c"] : ["l", "c"]
1813
+ ),
1814
+ added.length > 0 && style("(\\*) New category.", ["i"])
1815
+ );
1816
+ }
1817
+ function formatDiffGroupsSection(diff) {
1818
+ if (diff.groups.changed.length + diff.groups.unchanged.length === 0) {
1819
+ return "";
1820
+ }
1821
+ return paragraphs(
1822
+ h2("\u{1F397}\uFE0F Groups"),
1823
+ formatGroupsOrAuditsDetails("group", diff.groups, {
1824
+ headings: [
1825
+ "\u{1F50C} Plugin",
1826
+ "\u{1F5C3}\uFE0F Group",
1827
+ "\u2B50 Current score",
1828
+ "\u2B50 Previous score",
1829
+ "\u{1F504} Score change"
1830
+ ],
1831
+ rows: sortChanges(diff.groups.changed).map((group) => [
1832
+ group.plugin.title,
1833
+ group.title,
1834
+ formatScoreWithColor(group.scores.after),
1835
+ formatScoreWithColor(group.scores.before, { skipBold: true }),
1836
+ formatScoreChange(group.scores.diff)
1837
+ ]),
1838
+ align: ["l", "l", "c", "c", "c"]
1839
+ })
1840
+ );
1841
+ }
1842
+ function formatDiffAuditsSection(diff) {
1843
+ return paragraphs(
1844
+ h2("\u{1F6E1}\uFE0F Audits"),
1845
+ formatGroupsOrAuditsDetails("audit", diff.audits, {
1846
+ headings: [
1847
+ "\u{1F50C} Plugin",
1848
+ "\u{1F6E1}\uFE0F Audit",
1849
+ "\u{1F4CF} Current value",
1850
+ "\u{1F4CF} Previous value",
1851
+ "\u{1F504} Value change"
1852
+ ],
1853
+ rows: sortChanges(diff.audits.changed).map((audit) => [
1854
+ audit.plugin.title,
1855
+ audit.title,
1856
+ `${getSquaredScoreMarker(audit.scores.after)} ${style(
1857
+ audit.displayValues.after || audit.values.after.toString()
1858
+ )}`,
1859
+ `${getSquaredScoreMarker(audit.scores.before)} ${audit.displayValues.before || audit.values.before.toString()}`,
1860
+ formatValueChange(audit)
1861
+ ]),
1862
+ align: ["l", "l", "c", "c", "c"]
1863
+ })
1864
+ );
1865
+ }
1866
+ function formatGroupsOrAuditsDetails(token, { changed, unchanged }, table) {
1867
+ return changed.length === 0 ? summarizeUnchanged(token, { changed, unchanged }) : details(
1868
+ summarizeDiffOutcomes(changesToDiffOutcomes(changed), token),
1869
+ paragraphs(
1870
+ tableMd(
1871
+ [table.headings, ...table.rows.slice(0, MAX_ROWS)],
1872
+ table.align
1873
+ ),
1874
+ changed.length > MAX_ROWS && style(
1875
+ `Only the ${MAX_ROWS} most affected ${pluralize(
1876
+ token
1877
+ )} are listed above for brevity.`,
1878
+ ["i"]
1879
+ ),
1880
+ unchanged.length > 0 && summarizeUnchanged(token, { changed, unchanged })
1881
+ )
1882
+ );
1883
+ }
1884
+ function formatScoreChange(diff) {
1885
+ const marker = getDiffMarker(diff);
1886
+ const text = formatDiffNumber(Math.round(diff * 100));
1887
+ return colorByScoreDiff(`${marker} ${text}`, diff);
1888
+ }
1889
+ function formatValueChange({
1890
+ values,
1891
+ scores
1892
+ }) {
1893
+ const marker = getDiffMarker(values.diff);
1894
+ const percentage = values.before === 0 ? values.diff > 0 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY : Math.round(100 * values.diff / values.before);
1895
+ const text = `${formatDiffNumber(percentage)}\u2009%`;
1896
+ return colorByScoreDiff(`${marker} ${text}`, scores.diff);
1897
+ }
1898
+ function summarizeUnchanged(token, { changed, unchanged }) {
1899
+ return [
1900
+ changed.length > 0 ? pluralizeToken(`other ${token}`, unchanged.length) : `All of ${pluralizeToken(token, unchanged.length)}`,
1901
+ unchanged.length === 1 ? "is" : "are",
1902
+ "unchanged."
1903
+ ].join(" ");
1904
+ }
1905
+ function summarizeDiffOutcomes(outcomes, token) {
1906
+ return objectToEntries(countDiffOutcomes(outcomes)).filter(
1907
+ (entry) => entry[0] !== "unchanged" && entry[1] > 0
1908
+ ).map(([outcome, count]) => {
1909
+ const formattedCount = `<strong>${count}</strong> ${pluralize(
1910
+ token,
1911
+ count
1912
+ )}`;
1913
+ switch (outcome) {
1914
+ case "positive":
1915
+ return `\u{1F44D} ${formattedCount} improved`;
1916
+ case "negative":
1917
+ return `\u{1F44E} ${formattedCount} regressed`;
1918
+ case "mixed":
1919
+ return `${formattedCount} changed without impacting score`;
1920
+ }
1921
+ }).join(", ");
1922
+ }
1923
+ function sortChanges(changes) {
1924
+ return [...changes].sort(
1925
+ (a, b) => Math.abs(b.scores.diff) - Math.abs(a.scores.diff) || Math.abs(b.values?.diff ?? 0) - Math.abs(a.values?.diff ?? 0)
1926
+ );
1927
+ }
1928
+ function changesToDiffOutcomes(changes) {
1929
+ return changes.map((change) => {
1930
+ if (change.scores.diff > 0) {
1931
+ return "positive";
1932
+ }
1933
+ if (change.scores.diff < 0) {
1934
+ return "negative";
1935
+ }
1936
+ if (change.values != null && change.values.diff !== 0) {
1937
+ return "mixed";
1938
+ }
1939
+ return "unchanged";
1940
+ });
1941
+ }
1942
+ function mergeDiffOutcomes(outcomes) {
1943
+ if (outcomes.every((outcome) => outcome === "unchanged")) {
1944
+ return "unchanged";
1945
+ }
1946
+ if (outcomes.includes("positive") && !outcomes.includes("negative")) {
1947
+ return "positive";
1948
+ }
1949
+ if (outcomes.includes("negative") && !outcomes.includes("positive")) {
1950
+ return "negative";
1951
+ }
1952
+ return "mixed";
1953
+ }
1954
+ function countDiffOutcomes(outcomes) {
1955
+ return {
1956
+ positive: outcomes.filter((outcome) => outcome === "positive").length,
1957
+ negative: outcomes.filter((outcome) => outcome === "negative").length,
1958
+ mixed: outcomes.filter((outcome) => outcome === "mixed").length,
1959
+ unchanged: outcomes.filter((outcome) => outcome === "unchanged").length
1960
+ };
1961
+ }
1962
+
1963
+ // packages/utils/src/lib/reports/log-stdout-summary.ts
1964
+ import chalk4 from "chalk";
1965
+ function log(msg = "") {
1966
+ ui().logger.log(msg);
1967
+ }
1968
+ function logStdoutSummary(report) {
1969
+ const printCategories = report.categories.length > 0;
1970
+ log(reportToHeaderSection2(report));
1971
+ log();
1972
+ logPlugins(report);
1973
+ if (printCategories) {
1974
+ logCategories(report);
1975
+ }
1976
+ log(`${FOOTER_PREFIX} ${CODE_PUSHUP_DOMAIN}`);
1977
+ log();
1978
+ }
1979
+ function reportToHeaderSection2(report) {
1980
+ const { packageName, version } = report;
1981
+ return `${chalk4.bold(reportHeadlineText)} - ${packageName}@${version}`;
1982
+ }
1983
+ function logPlugins(report) {
1984
+ const { plugins } = report;
1985
+ plugins.forEach((plugin) => {
1986
+ const { title, audits } = plugin;
1987
+ log();
1988
+ log(chalk4.magentaBright.bold(`${title} audits`));
1989
+ log();
1990
+ audits.forEach((audit) => {
1991
+ ui().row([
1992
+ {
1993
+ text: applyScoreColor({ score: audit.score, text: "\u25CF" }),
1994
+ width: 2,
1995
+ padding: [0, 1, 0, 0]
1996
+ },
1997
+ {
1998
+ text: audit.title,
1999
+ // eslint-disable-next-line no-magic-numbers
2000
+ padding: [0, 3, 0, 0]
2001
+ },
2002
+ {
2003
+ text: chalk4.cyanBright(audit.displayValue || `${audit.value}`),
2004
+ width: 10,
2005
+ padding: [0, 0, 0, 0]
2006
+ }
2007
+ ]);
2008
+ });
2009
+ log();
2010
+ });
2011
+ }
2012
+ function logCategories({ categories, plugins }) {
2013
+ const hAlign = (idx) => idx === 0 ? "left" : "right";
2014
+ const rows = categories.map(({ title, score, refs }) => [
2015
+ title,
2016
+ applyScoreColor({ score }),
2017
+ countCategoryAudits(refs, plugins)
2018
+ ]);
2019
+ const table = ui().table();
2020
+ table.columnWidths([TERMINAL_WIDTH - 9 - 10 - 4, 9, 10]);
2021
+ table.head(
2022
+ reportRawOverviewTableHeaders.map((heading, idx) => ({
2023
+ content: chalk4.cyan(heading),
2024
+ hAlign: hAlign(idx)
2025
+ }))
2026
+ );
2027
+ rows.forEach(
2028
+ (row) => table.row(
2029
+ row.map((content, idx) => ({
2030
+ content: content.toString(),
2031
+ hAlign: hAlign(idx)
2032
+ }))
2033
+ )
2034
+ );
2035
+ log(chalk4.magentaBright.bold("Categories"));
2036
+ log();
2037
+ table.render();
2038
+ log();
2039
+ }
2040
+ function applyScoreColor({ score, text }) {
2041
+ const formattedScore = text ?? formatReportScore(score);
2042
+ const style2 = text ? chalk4 : chalk4.bold;
2043
+ if (score >= SCORE_COLOR_RANGE.GREEN_MIN) {
2044
+ return style2.green(formattedScore);
2045
+ }
2046
+ if (score >= SCORE_COLOR_RANGE.YELLOW_MIN) {
2047
+ return style2.yellow(formattedScore);
2048
+ }
2049
+ return style2.red(formattedScore);
2050
+ }
2051
+
1787
2052
  // packages/utils/src/lib/reports/scoring.ts
1788
2053
  var GroupRefInvalidError = class extends Error {
1789
2054
  constructor(auditSlug, pluginSlug) {
@@ -1965,6 +2230,7 @@ export {
1965
2230
  formatDuration,
1966
2231
  formatGitPath,
1967
2232
  generateMdReport,
2233
+ generateMdReportsDiff,
1968
2234
  getCurrentBranchOrTag,
1969
2235
  getGitRoot,
1970
2236
  getLatestCommit,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-pushup/utils",
3
- "version": "0.27.1",
3
+ "version": "0.28.0",
4
4
  "dependencies": {
5
5
  "@code-pushup/models": "*",
6
6
  "bundle-require": "^4.0.1",
package/src/index.d.ts CHANGED
@@ -1,22 +1,23 @@
1
1
  export { exists } from '@code-pushup/models';
2
- export { Diff, matchArrayItemsByKey, comparePairs } from './lib/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, toGitPath, getCurrentBranchOrTag, safeCheckout, } from './lib/git';
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';