@code-pushup/core 0.8.13 → 0.8.15
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 +134 -108
- package/package.json +1 -1
- package/src/lib/implementation/json-to-gql.d.ts +12 -2
- package/src/lib/implementation/runner.d.ts +2 -2
package/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// packages/core/src/lib/implementation/persist.ts
|
|
2
|
-
import {
|
|
3
|
-
import { stat as stat2, writeFile } from "node:fs/promises";
|
|
2
|
+
import { mkdir as mkdir2, stat as stat2, writeFile } from "node:fs/promises";
|
|
4
3
|
import { join as join2 } from "node:path";
|
|
5
4
|
|
|
6
5
|
// packages/utils/src/lib/execute-process.ts
|
|
@@ -648,6 +647,14 @@ async function fileExists(path) {
|
|
|
648
647
|
return false;
|
|
649
648
|
}
|
|
650
649
|
}
|
|
650
|
+
async function directoryExists(path) {
|
|
651
|
+
try {
|
|
652
|
+
const stats = await stat(path);
|
|
653
|
+
return stats.isDirectory();
|
|
654
|
+
} catch {
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
651
658
|
async function ensureDirectoryExists(baseDir) {
|
|
652
659
|
try {
|
|
653
660
|
await mkdir(baseDir, { recursive: true });
|
|
@@ -1379,6 +1386,9 @@ function withColor({ score, text }) {
|
|
|
1379
1386
|
}
|
|
1380
1387
|
|
|
1381
1388
|
// packages/utils/src/lib/transform.ts
|
|
1389
|
+
function toArray(val) {
|
|
1390
|
+
return Array.isArray(val) ? val : [val];
|
|
1391
|
+
}
|
|
1382
1392
|
function deepClone(obj) {
|
|
1383
1393
|
if (obj == null || typeof obj !== "object") {
|
|
1384
1394
|
return obj;
|
|
@@ -1545,47 +1555,55 @@ async function persistReport(report, options) {
|
|
|
1545
1555
|
const { outputDir, filename, format } = options;
|
|
1546
1556
|
const sortedScoredReport = sortReport(scoreReport(report));
|
|
1547
1557
|
console.info(generateStdoutSummary(sortedScoredReport));
|
|
1548
|
-
const results =
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1558
|
+
const results = await Promise.all(
|
|
1559
|
+
format.map(async (reportType) => {
|
|
1560
|
+
switch (reportType) {
|
|
1561
|
+
case "json":
|
|
1562
|
+
return {
|
|
1563
|
+
format: "json",
|
|
1564
|
+
content: JSON.stringify(report, null, 2)
|
|
1565
|
+
};
|
|
1566
|
+
case "md":
|
|
1567
|
+
const commitData = await getLatestCommit();
|
|
1568
|
+
validateCommitData(commitData);
|
|
1569
|
+
return {
|
|
1570
|
+
format: "md",
|
|
1571
|
+
content: generateMdReport(sortedScoredReport, commitData)
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1574
|
+
})
|
|
1575
|
+
);
|
|
1576
|
+
if (!await directoryExists(outputDir)) {
|
|
1564
1577
|
try {
|
|
1565
|
-
|
|
1566
|
-
} catch (
|
|
1567
|
-
console.warn(
|
|
1578
|
+
await mkdir2(outputDir, { recursive: true });
|
|
1579
|
+
} catch (error) {
|
|
1580
|
+
console.warn(error);
|
|
1568
1581
|
throw new PersistDirError(outputDir);
|
|
1569
1582
|
}
|
|
1570
1583
|
}
|
|
1571
1584
|
return Promise.allSettled(
|
|
1572
|
-
results.map(
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
})
|
|
1585
|
+
results.map(
|
|
1586
|
+
(result) => persistResult(
|
|
1587
|
+
join2(outputDir, `${filename}.${result.format}`),
|
|
1588
|
+
result.content
|
|
1589
|
+
)
|
|
1590
|
+
)
|
|
1579
1591
|
);
|
|
1580
1592
|
}
|
|
1581
|
-
function logPersistedResults(persistResults) {
|
|
1582
|
-
logMultipleFileResults(persistResults, "Generated reports");
|
|
1583
|
-
}
|
|
1584
1593
|
function validateCommitData(commitData) {
|
|
1585
1594
|
if (!commitData) {
|
|
1586
1595
|
console.warn("no commit data available");
|
|
1587
1596
|
}
|
|
1588
1597
|
}
|
|
1598
|
+
async function persistResult(reportPath, content) {
|
|
1599
|
+
return writeFile(reportPath, content).then(() => stat2(reportPath)).then((stats) => [reportPath, stats.size]).catch((error) => {
|
|
1600
|
+
console.warn(error);
|
|
1601
|
+
throw new PersistError(reportPath);
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
function logPersistedResults(persistResults) {
|
|
1605
|
+
logMultipleFileResults(persistResults, "Generated reports");
|
|
1606
|
+
}
|
|
1589
1607
|
|
|
1590
1608
|
// packages/core/src/lib/implementation/execute-plugin.ts
|
|
1591
1609
|
import chalk4 from "chalk";
|
|
@@ -1599,12 +1617,8 @@ async function executeRunnerConfig(cfg, onProgress) {
|
|
|
1599
1617
|
args,
|
|
1600
1618
|
observer: { onStdout: onProgress }
|
|
1601
1619
|
});
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
);
|
|
1605
|
-
if (outputTransform) {
|
|
1606
|
-
audits = await outputTransform(audits);
|
|
1607
|
-
}
|
|
1620
|
+
const outputs = await readJsonFile(join3(process.cwd(), outputFile));
|
|
1621
|
+
const audits = outputTransform ? await outputTransform(outputs) : outputs;
|
|
1608
1622
|
return {
|
|
1609
1623
|
duration,
|
|
1610
1624
|
date,
|
|
@@ -1659,30 +1673,31 @@ async function executePlugin(pluginConfig, onProgress) {
|
|
|
1659
1673
|
};
|
|
1660
1674
|
}
|
|
1661
1675
|
async function executePlugins(plugins, options) {
|
|
1662
|
-
const { progress = false } = options
|
|
1663
|
-
const
|
|
1664
|
-
const progressBar = progress ? getProgressBar(progressName) : null;
|
|
1676
|
+
const { progress = false } = options ?? {};
|
|
1677
|
+
const progressBar = progress ? getProgressBar("Run plugins") : null;
|
|
1665
1678
|
const pluginsResult = await plugins.reduce(async (acc, pluginCfg) => {
|
|
1666
|
-
|
|
1667
|
-
progressBar?.updateTitle(`Executing ${chalk4.bold(pluginCfg.title)}`);
|
|
1679
|
+
progressBar?.updateTitle(`Executing ${chalk4.bold(pluginCfg.title)}`);
|
|
1668
1680
|
try {
|
|
1669
1681
|
const pluginReport = await executePlugin(pluginCfg);
|
|
1670
1682
|
progressBar?.incrementInSteps(plugins.length);
|
|
1671
|
-
return
|
|
1672
|
-
} catch (
|
|
1683
|
+
return [...await acc, Promise.resolve(pluginReport)];
|
|
1684
|
+
} catch (error) {
|
|
1673
1685
|
progressBar?.incrementInSteps(plugins.length);
|
|
1674
|
-
return
|
|
1675
|
-
|
|
1676
|
-
|
|
1686
|
+
return [
|
|
1687
|
+
...await acc,
|
|
1688
|
+
Promise.reject(error instanceof Error ? error.message : String(error))
|
|
1689
|
+
];
|
|
1677
1690
|
}
|
|
1678
1691
|
}, Promise.resolve([]));
|
|
1679
1692
|
progressBar?.endProgress("Done running plugins");
|
|
1680
|
-
const errorsCallback = ({ reason }) =>
|
|
1693
|
+
const errorsCallback = ({ reason }) => {
|
|
1694
|
+
console.error(reason);
|
|
1695
|
+
};
|
|
1681
1696
|
const results = await Promise.allSettled(pluginsResult);
|
|
1682
1697
|
logMultipleResults(results, "Plugins", void 0, errorsCallback);
|
|
1683
1698
|
const { fulfilled, rejected } = groupByStatus(results);
|
|
1684
|
-
if (rejected.length) {
|
|
1685
|
-
const errorMessages = rejected.map(({ reason }) => reason).join(", ");
|
|
1699
|
+
if (rejected.length > 0) {
|
|
1700
|
+
const errorMessages = rejected.map(({ reason }) => String(reason)).join(", ");
|
|
1686
1701
|
throw new Error(
|
|
1687
1702
|
`Plugins failed: ${rejected.length} errors: ${errorMessages}`
|
|
1688
1703
|
);
|
|
@@ -1702,14 +1717,11 @@ function auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits)
|
|
|
1702
1717
|
|
|
1703
1718
|
// packages/core/package.json
|
|
1704
1719
|
var name = "@code-pushup/core";
|
|
1705
|
-
var version = "0.8.
|
|
1720
|
+
var version = "0.8.15";
|
|
1706
1721
|
|
|
1707
1722
|
// packages/core/src/lib/implementation/collect.ts
|
|
1708
1723
|
async function collect(options) {
|
|
1709
1724
|
const { plugins, categories } = options;
|
|
1710
|
-
if (!plugins?.length) {
|
|
1711
|
-
throw new Error("No plugins registered");
|
|
1712
|
-
}
|
|
1713
1725
|
const date = (/* @__PURE__ */ new Date()).toISOString();
|
|
1714
1726
|
const start = performance.now();
|
|
1715
1727
|
const pluginOutputs = await executePlugins(plugins, options);
|
|
@@ -1732,62 +1744,74 @@ import {
|
|
|
1732
1744
|
IssueSourceType,
|
|
1733
1745
|
IssueSeverity as PortalIssueSeverity
|
|
1734
1746
|
} from "@code-pushup/portal-client";
|
|
1735
|
-
function
|
|
1747
|
+
function jsonReportToGql(report) {
|
|
1736
1748
|
return {
|
|
1737
1749
|
packageName: report.packageName,
|
|
1738
1750
|
packageVersion: report.version,
|
|
1739
1751
|
commandStartDate: report.date,
|
|
1740
1752
|
commandDuration: report.duration,
|
|
1741
|
-
plugins: report.plugins
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
},
|
|
1756
|
-
docsUrl: audit.docsUrl,
|
|
1757
|
-
formattedValue: audit.displayValue,
|
|
1758
|
-
score: audit.score,
|
|
1759
|
-
slug: audit.slug,
|
|
1760
|
-
title: audit.title,
|
|
1761
|
-
value: audit.value
|
|
1762
|
-
})),
|
|
1763
|
-
description: plugin.description,
|
|
1764
|
-
docsUrl: plugin.docsUrl,
|
|
1765
|
-
groups: plugin.groups?.map((group) => ({
|
|
1766
|
-
slug: group.slug,
|
|
1767
|
-
title: group.title,
|
|
1768
|
-
description: group.description,
|
|
1769
|
-
refs: group.refs.map((ref) => ({ slug: ref.slug, weight: ref.weight }))
|
|
1770
|
-
})),
|
|
1771
|
-
icon: plugin.icon,
|
|
1772
|
-
slug: plugin.slug,
|
|
1773
|
-
title: plugin.title,
|
|
1774
|
-
packageName: plugin.packageName,
|
|
1775
|
-
packageVersion: plugin.version,
|
|
1776
|
-
runnerDuration: plugin.duration,
|
|
1777
|
-
runnerStartDate: plugin.date
|
|
1753
|
+
plugins: pluginReportsToGql(report.plugins),
|
|
1754
|
+
categories: categoryConfigsToGql(toArray(report.categories))
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
function pluginReportsToGql(plugins) {
|
|
1758
|
+
return plugins.map((plugin) => ({
|
|
1759
|
+
audits: auditReportsToGql(plugin.audits),
|
|
1760
|
+
description: plugin.description,
|
|
1761
|
+
docsUrl: plugin.docsUrl,
|
|
1762
|
+
groups: plugin.groups?.map((group) => ({
|
|
1763
|
+
slug: group.slug,
|
|
1764
|
+
title: group.title,
|
|
1765
|
+
description: group.description,
|
|
1766
|
+
refs: group.refs.map((ref) => ({ slug: ref.slug, weight: ref.weight }))
|
|
1778
1767
|
})),
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1768
|
+
icon: plugin.icon,
|
|
1769
|
+
slug: plugin.slug,
|
|
1770
|
+
title: plugin.title,
|
|
1771
|
+
packageName: plugin.packageName,
|
|
1772
|
+
packageVersion: plugin.version,
|
|
1773
|
+
runnerDuration: plugin.duration,
|
|
1774
|
+
runnerStartDate: plugin.date
|
|
1775
|
+
}));
|
|
1776
|
+
}
|
|
1777
|
+
function auditReportsToGql(audits) {
|
|
1778
|
+
return audits.map((audit) => ({
|
|
1779
|
+
description: audit.description,
|
|
1780
|
+
details: {
|
|
1781
|
+
issues: issuesToGql(audit.details?.issues)
|
|
1782
|
+
},
|
|
1783
|
+
docsUrl: audit.docsUrl,
|
|
1784
|
+
formattedValue: audit.displayValue,
|
|
1785
|
+
score: audit.score,
|
|
1786
|
+
slug: audit.slug,
|
|
1787
|
+
title: audit.title,
|
|
1788
|
+
value: audit.value
|
|
1789
|
+
}));
|
|
1790
|
+
}
|
|
1791
|
+
function issuesToGql(issues) {
|
|
1792
|
+
return issues?.map((issue) => ({
|
|
1793
|
+
message: issue.message,
|
|
1794
|
+
severity: transformSeverity(issue.severity),
|
|
1795
|
+
sourceEndColumn: issue.source?.position?.endColumn,
|
|
1796
|
+
sourceEndLine: issue.source?.position?.endLine,
|
|
1797
|
+
sourceFilePath: issue.source?.file,
|
|
1798
|
+
sourceStartColumn: issue.source?.position?.startColumn,
|
|
1799
|
+
sourceStartLine: issue.source?.position?.startLine,
|
|
1800
|
+
sourceType: IssueSourceType.SourceCode
|
|
1801
|
+
})) ?? [];
|
|
1802
|
+
}
|
|
1803
|
+
function categoryConfigsToGql(categories) {
|
|
1804
|
+
return categories.map((category) => ({
|
|
1805
|
+
slug: category.slug,
|
|
1806
|
+
title: category.title,
|
|
1807
|
+
description: category.description,
|
|
1808
|
+
refs: category.refs.map((ref) => ({
|
|
1809
|
+
plugin: ref.plugin,
|
|
1810
|
+
type: ref.type === "audit" ? CategoryConfigRefType.Audit : CategoryConfigRefType.Group,
|
|
1811
|
+
weight: ref.weight,
|
|
1812
|
+
slug: ref.slug
|
|
1789
1813
|
}))
|
|
1790
|
-
};
|
|
1814
|
+
}));
|
|
1791
1815
|
}
|
|
1792
1816
|
function transformSeverity(severity) {
|
|
1793
1817
|
switch (severity) {
|
|
@@ -1810,8 +1834,8 @@ var normalizePersistConfig = (cfg) => ({
|
|
|
1810
1834
|
|
|
1811
1835
|
// packages/core/src/lib/upload.ts
|
|
1812
1836
|
async function upload(options, uploadFn = uploadToPortal) {
|
|
1813
|
-
const persist = normalizePersistConfig(options
|
|
1814
|
-
if (!options
|
|
1837
|
+
const persist = normalizePersistConfig(options.persist);
|
|
1838
|
+
if (!options.upload) {
|
|
1815
1839
|
throw new Error("upload config must be set");
|
|
1816
1840
|
}
|
|
1817
1841
|
const { apiKey, server, organization, project } = options.upload;
|
|
@@ -1827,7 +1851,7 @@ async function upload(options, uploadFn = uploadToPortal) {
|
|
|
1827
1851
|
organization,
|
|
1828
1852
|
project,
|
|
1829
1853
|
commit: commitData.hash,
|
|
1830
|
-
...
|
|
1854
|
+
...jsonReportToGql(report)
|
|
1831
1855
|
};
|
|
1832
1856
|
return uploadFn({ apiKey, server, data });
|
|
1833
1857
|
}
|
|
@@ -1836,9 +1860,11 @@ async function upload(options, uploadFn = uploadToPortal) {
|
|
|
1836
1860
|
async function collectAndPersistReports(options) {
|
|
1837
1861
|
const { exec } = verboseUtils(options.verbose);
|
|
1838
1862
|
const report = await collect(options);
|
|
1839
|
-
const persist = normalizePersistConfig(options
|
|
1863
|
+
const persist = normalizePersistConfig(options.persist);
|
|
1840
1864
|
const persistResults = await persistReport(report, persist);
|
|
1841
|
-
exec(() =>
|
|
1865
|
+
exec(() => {
|
|
1866
|
+
logPersistedResults(persistResults);
|
|
1867
|
+
});
|
|
1842
1868
|
report.plugins.forEach((plugin) => {
|
|
1843
1869
|
pluginReportSchema.parse(plugin);
|
|
1844
1870
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CategoryConfigRefType, IssueSourceType, IssueSeverity as PortalIssueSeverity } from '@code-pushup/portal-client';
|
|
2
|
-
import { Report } from '@code-pushup/models';
|
|
3
|
-
export declare function
|
|
2
|
+
import { Issue, Report } from '@code-pushup/models';
|
|
3
|
+
export declare function jsonReportToGql(report: Report): {
|
|
4
4
|
packageName: string;
|
|
5
5
|
packageVersion: string;
|
|
6
6
|
commandStartDate: string;
|
|
@@ -58,3 +58,13 @@ export declare function jsonToGql(report: Report): {
|
|
|
58
58
|
}[];
|
|
59
59
|
}[];
|
|
60
60
|
};
|
|
61
|
+
export declare function issuesToGql(issues: Issue[] | undefined): {
|
|
62
|
+
message: string;
|
|
63
|
+
severity: PortalIssueSeverity;
|
|
64
|
+
sourceEndColumn: number | undefined;
|
|
65
|
+
sourceEndLine: number | undefined;
|
|
66
|
+
sourceFilePath: string | undefined;
|
|
67
|
+
sourceStartColumn: number | undefined;
|
|
68
|
+
sourceStartLine: number | undefined;
|
|
69
|
+
sourceType: IssueSourceType;
|
|
70
|
+
}[];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OnProgress, RunnerConfig, RunnerFunction } from '@code-pushup/models';
|
|
2
2
|
export type RunnerResult = {
|
|
3
3
|
date: string;
|
|
4
4
|
duration: number;
|
|
5
|
-
audits:
|
|
5
|
+
audits: unknown;
|
|
6
6
|
};
|
|
7
7
|
export declare function executeRunnerConfig(cfg: RunnerConfig, onProgress?: OnProgress): Promise<RunnerResult>;
|
|
8
8
|
export declare function executeRunnerFunction(runner: RunnerFunction, onProgress?: OnProgress): Promise<RunnerResult>;
|