@code-pushup/core
Advanced tools
Comparing version 0.8.14 to 0.8.15
242
index.js
// packages/core/src/lib/implementation/persist.ts | ||
import { existsSync, mkdirSync } from "node:fs"; | ||
import { stat as stat2, writeFile } from "node:fs/promises"; | ||
import { mkdir as mkdir2, stat as stat2, writeFile } from "node:fs/promises"; | ||
import { join as join2 } from "node:path"; | ||
@@ -651,2 +650,10 @@ | ||
} | ||
async function directoryExists(path) { | ||
try { | ||
const stats = await stat(path); | ||
return stats.isDirectory(); | ||
} catch { | ||
return false; | ||
} | ||
} | ||
async function ensureDirectoryExists(baseDir) { | ||
@@ -1383,2 +1390,5 @@ try { | ||
// packages/utils/src/lib/transform.ts | ||
function toArray(val) { | ||
return Array.isArray(val) ? val : [val]; | ||
} | ||
function deepClone(obj) { | ||
@@ -1550,22 +1560,25 @@ if (obj == null || typeof obj !== "object") { | ||
console.info(generateStdoutSummary(sortedScoredReport)); | ||
const results = []; | ||
if (format.includes("json")) { | ||
results.push({ | ||
format: "json", | ||
content: JSON.stringify(report, null, 2) | ||
}); | ||
} | ||
if (format.includes("md")) { | ||
const commitData = await getLatestCommit(); | ||
validateCommitData(commitData); | ||
results.push({ | ||
format: "md", | ||
content: generateMdReport(sortedScoredReport, commitData) | ||
}); | ||
} | ||
if (!existsSync(outputDir)) { | ||
const results = await Promise.all( | ||
format.map(async (reportType) => { | ||
switch (reportType) { | ||
case "json": | ||
return { | ||
format: "json", | ||
content: JSON.stringify(report, null, 2) | ||
}; | ||
case "md": | ||
const commitData = await getLatestCommit(); | ||
validateCommitData(commitData); | ||
return { | ||
format: "md", | ||
content: generateMdReport(sortedScoredReport, commitData) | ||
}; | ||
} | ||
}) | ||
); | ||
if (!await directoryExists(outputDir)) { | ||
try { | ||
mkdirSync(outputDir, { recursive: true }); | ||
} catch (e) { | ||
console.warn(e); | ||
await mkdir2(outputDir, { recursive: true }); | ||
} catch (error) { | ||
console.warn(error); | ||
throw new PersistDirError(outputDir); | ||
@@ -1575,14 +1588,10 @@ } | ||
return Promise.allSettled( | ||
results.map(({ format: format2, content }) => { | ||
const reportPath = join2(outputDir, `${filename}.${format2}`); | ||
return writeFile(reportPath, content).then(() => stat2(reportPath)).then((stats) => [reportPath, stats.size]).catch((e) => { | ||
console.warn(e); | ||
throw new PersistError(reportPath); | ||
}); | ||
}) | ||
results.map( | ||
(result) => persistResult( | ||
join2(outputDir, `${filename}.${result.format}`), | ||
result.content | ||
) | ||
) | ||
); | ||
} | ||
function logPersistedResults(persistResults) { | ||
logMultipleFileResults(persistResults, "Generated reports"); | ||
} | ||
function validateCommitData(commitData) { | ||
@@ -1593,2 +1602,11 @@ if (!commitData) { | ||
} | ||
async function persistResult(reportPath, content) { | ||
return writeFile(reportPath, content).then(() => stat2(reportPath)).then((stats) => [reportPath, stats.size]).catch((error) => { | ||
console.warn(error); | ||
throw new PersistError(reportPath); | ||
}); | ||
} | ||
function logPersistedResults(persistResults) { | ||
logMultipleFileResults(persistResults, "Generated reports"); | ||
} | ||
@@ -1607,8 +1625,4 @@ // packages/core/src/lib/implementation/execute-plugin.ts | ||
}); | ||
let audits = await readJsonFile( | ||
join3(process.cwd(), outputFile) | ||
); | ||
if (outputTransform) { | ||
audits = await outputTransform(audits); | ||
} | ||
const outputs = await readJsonFile(join3(process.cwd(), outputFile)); | ||
const audits = outputTransform ? await outputTransform(outputs) : outputs; | ||
return { | ||
@@ -1668,26 +1682,27 @@ duration, | ||
async function executePlugins(plugins, options) { | ||
const { progress = false } = options || {}; | ||
const progressName = "Run Plugins"; | ||
const progressBar = progress ? getProgressBar(progressName) : null; | ||
const { progress = false } = options ?? {}; | ||
const progressBar = progress ? getProgressBar("Run plugins") : null; | ||
const pluginsResult = await plugins.reduce(async (acc, pluginCfg) => { | ||
const outputs = await acc; | ||
progressBar?.updateTitle(`Executing ${chalk4.bold(pluginCfg.title)}`); | ||
progressBar?.updateTitle(`Executing ${chalk4.bold(pluginCfg.title)}`); | ||
try { | ||
const pluginReport = await executePlugin(pluginCfg); | ||
progressBar?.incrementInSteps(plugins.length); | ||
return outputs.concat(Promise.resolve(pluginReport)); | ||
} catch (e) { | ||
return [...await acc, Promise.resolve(pluginReport)]; | ||
} catch (error) { | ||
progressBar?.incrementInSteps(plugins.length); | ||
return outputs.concat( | ||
Promise.reject(e instanceof Error ? e.message : String(e)) | ||
); | ||
return [ | ||
...await acc, | ||
Promise.reject(error instanceof Error ? error.message : String(error)) | ||
]; | ||
} | ||
}, Promise.resolve([])); | ||
progressBar?.endProgress("Done running plugins"); | ||
const errorsCallback = ({ reason }) => console.error(reason); | ||
const errorsCallback = ({ reason }) => { | ||
console.error(reason); | ||
}; | ||
const results = await Promise.allSettled(pluginsResult); | ||
logMultipleResults(results, "Plugins", void 0, errorsCallback); | ||
const { fulfilled, rejected } = groupByStatus(results); | ||
if (rejected.length) { | ||
const errorMessages = rejected.map(({ reason }) => reason).join(", "); | ||
if (rejected.length > 0) { | ||
const errorMessages = rejected.map(({ reason }) => String(reason)).join(", "); | ||
throw new Error( | ||
@@ -1712,3 +1727,3 @@ `Plugins failed: ${rejected.length} errors: ${errorMessages}` | ||
var name = "@code-pushup/core"; | ||
var version = "0.8.14"; | ||
var version = "0.8.15"; | ||
@@ -1718,5 +1733,2 @@ // packages/core/src/lib/implementation/collect.ts | ||
const { plugins, categories } = options; | ||
if (!plugins?.length) { | ||
throw new Error("No plugins registered"); | ||
} | ||
const date = (/* @__PURE__ */ new Date()).toISOString(); | ||
@@ -1744,3 +1756,3 @@ const start = performance.now(); | ||
} from "@code-pushup/portal-client"; | ||
function jsonToGql(report) { | ||
function jsonReportToGql(report) { | ||
return { | ||
@@ -1751,52 +1763,64 @@ packageName: report.packageName, | ||
commandDuration: report.duration, | ||
plugins: report.plugins.map((plugin) => ({ | ||
audits: plugin.audits.map((audit) => ({ | ||
description: audit.description, | ||
details: { | ||
issues: audit.details?.issues.map((issue) => ({ | ||
message: issue.message, | ||
severity: transformSeverity(issue.severity), | ||
sourceEndColumn: issue.source?.position?.endColumn, | ||
sourceEndLine: issue.source?.position?.endLine, | ||
sourceFilePath: issue.source?.file, | ||
sourceStartColumn: issue.source?.position?.startColumn, | ||
sourceStartLine: issue.source?.position?.startLine, | ||
sourceType: IssueSourceType.SourceCode | ||
})) || [] | ||
}, | ||
docsUrl: audit.docsUrl, | ||
formattedValue: audit.displayValue, | ||
score: audit.score, | ||
slug: audit.slug, | ||
title: audit.title, | ||
value: audit.value | ||
})), | ||
description: plugin.description, | ||
docsUrl: plugin.docsUrl, | ||
groups: plugin.groups?.map((group) => ({ | ||
slug: group.slug, | ||
title: group.title, | ||
description: group.description, | ||
refs: group.refs.map((ref) => ({ slug: ref.slug, weight: ref.weight })) | ||
})), | ||
icon: plugin.icon, | ||
slug: plugin.slug, | ||
title: plugin.title, | ||
packageName: plugin.packageName, | ||
packageVersion: plugin.version, | ||
runnerDuration: plugin.duration, | ||
runnerStartDate: plugin.date | ||
plugins: pluginReportsToGql(report.plugins), | ||
categories: categoryConfigsToGql(toArray(report.categories)) | ||
}; | ||
} | ||
function pluginReportsToGql(plugins) { | ||
return plugins.map((plugin) => ({ | ||
audits: auditReportsToGql(plugin.audits), | ||
description: plugin.description, | ||
docsUrl: plugin.docsUrl, | ||
groups: plugin.groups?.map((group) => ({ | ||
slug: group.slug, | ||
title: group.title, | ||
description: group.description, | ||
refs: group.refs.map((ref) => ({ slug: ref.slug, weight: ref.weight })) | ||
})), | ||
categories: report.categories.map((category) => ({ | ||
slug: category.slug, | ||
title: category.title, | ||
description: category.description, | ||
refs: category.refs.map((ref) => ({ | ||
plugin: ref.plugin, | ||
type: ref.type === "audit" ? CategoryConfigRefType.Audit : CategoryConfigRefType.Group, | ||
weight: ref.weight, | ||
slug: ref.slug | ||
})) | ||
icon: plugin.icon, | ||
slug: plugin.slug, | ||
title: plugin.title, | ||
packageName: plugin.packageName, | ||
packageVersion: plugin.version, | ||
runnerDuration: plugin.duration, | ||
runnerStartDate: plugin.date | ||
})); | ||
} | ||
function auditReportsToGql(audits) { | ||
return audits.map((audit) => ({ | ||
description: audit.description, | ||
details: { | ||
issues: issuesToGql(audit.details?.issues) | ||
}, | ||
docsUrl: audit.docsUrl, | ||
formattedValue: audit.displayValue, | ||
score: audit.score, | ||
slug: audit.slug, | ||
title: audit.title, | ||
value: audit.value | ||
})); | ||
} | ||
function issuesToGql(issues) { | ||
return issues?.map((issue) => ({ | ||
message: issue.message, | ||
severity: transformSeverity(issue.severity), | ||
sourceEndColumn: issue.source?.position?.endColumn, | ||
sourceEndLine: issue.source?.position?.endLine, | ||
sourceFilePath: issue.source?.file, | ||
sourceStartColumn: issue.source?.position?.startColumn, | ||
sourceStartLine: issue.source?.position?.startLine, | ||
sourceType: IssueSourceType.SourceCode | ||
})) ?? []; | ||
} | ||
function categoryConfigsToGql(categories) { | ||
return categories.map((category) => ({ | ||
slug: category.slug, | ||
title: category.title, | ||
description: category.description, | ||
refs: category.refs.map((ref) => ({ | ||
plugin: ref.plugin, | ||
type: ref.type === "audit" ? CategoryConfigRefType.Audit : CategoryConfigRefType.Group, | ||
weight: ref.weight, | ||
slug: ref.slug | ||
})) | ||
}; | ||
})); | ||
} | ||
@@ -1824,4 +1848,4 @@ function transformSeverity(severity) { | ||
async function upload(options, uploadFn = uploadToPortal) { | ||
const persist = normalizePersistConfig(options?.persist); | ||
if (!options?.upload) { | ||
const persist = normalizePersistConfig(options.persist); | ||
if (!options.upload) { | ||
throw new Error("upload config must be set"); | ||
@@ -1842,3 +1866,3 @@ } | ||
commit: commitData.hash, | ||
...jsonToGql(report) | ||
...jsonReportToGql(report) | ||
}; | ||
@@ -1852,5 +1876,7 @@ return uploadFn({ apiKey, server, data }); | ||
const report = await collect(options); | ||
const persist = normalizePersistConfig(options?.persist); | ||
const persist = normalizePersistConfig(options.persist); | ||
const persistResults = await persistReport(report, persist); | ||
exec(() => logPersistedResults(persistResults)); | ||
exec(() => { | ||
logPersistedResults(persistResults); | ||
}); | ||
report.plugins.forEach((plugin) => { | ||
@@ -1857,0 +1883,0 @@ pluginReportSchema.parse(plugin); |
{ | ||
"name": "@code-pushup/core", | ||
"version": "0.8.14", | ||
"version": "0.8.15", | ||
"dependencies": { | ||
@@ -5,0 +5,0 @@ "@code-pushup/models": "*", |
import { CategoryConfigRefType, IssueSourceType, IssueSeverity as PortalIssueSeverity } from '@code-pushup/portal-client'; | ||
import { Report } from '@code-pushup/models'; | ||
export declare function jsonToGql(report: Report): { | ||
import { Issue, Report } from '@code-pushup/models'; | ||
export declare function jsonReportToGql(report: Report): { | ||
packageName: string; | ||
@@ -61,1 +61,11 @@ packageVersion: string; | ||
}; | ||
export declare function issuesToGql(issues: Issue[] | undefined): { | ||
message: string; | ||
severity: PortalIssueSeverity; | ||
sourceEndColumn: number | undefined; | ||
sourceEndLine: number | undefined; | ||
sourceFilePath: string | undefined; | ||
sourceStartColumn: number | undefined; | ||
sourceStartLine: number | undefined; | ||
sourceType: IssueSourceType; | ||
}[]; |
@@ -1,8 +0,8 @@ | ||
import { AuditOutputs, OnProgress, RunnerConfig, RunnerFunction } from '@code-pushup/models'; | ||
import { OnProgress, RunnerConfig, RunnerFunction } from '@code-pushup/models'; | ||
export type RunnerResult = { | ||
date: string; | ||
duration: number; | ||
audits: AuditOutputs; | ||
audits: unknown; | ||
}; | ||
export declare function executeRunnerConfig(cfg: RunnerConfig, onProgress?: OnProgress): Promise<RunnerResult>; | ||
export declare function executeRunnerFunction(runner: RunnerFunction, onProgress?: OnProgress): Promise<RunnerResult>; |
80314
2071