vitest-sonar-reporter
Version:
SonarQube reporter for Vitest
77 lines (76 loc) • 2.62 kB
JavaScript
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
import { dirname, relative, resolve } from 'node:path';
import { generateXml } from './xml.js';
/**
* Reporter used by `vitest`
*/
export default class SonarReporter {
constructor(options) {
this.options = {
silent: options?.silent ?? false,
onWritePath: options?.onWritePath ?? defaultOnWritePath,
// @ts-expect-error -- Can also be initialized during onInit()
outputFile: options?.outputFile,
};
}
onInit(ctx) {
this.ctx = ctx;
if (!this.ctx.config.outputFile && !this.options.outputFile) {
throw new Error('SonarReporter requires outputFile to be defined in config');
}
this.options.outputFile =
this.options.outputFile ?? resolveOutputfile(this.ctx.config);
if (existsSync(this.options.outputFile)) {
rmSync(this.options.outputFile);
}
}
onFinished(rawFiles) {
const reportFile = resolve(this.ctx.config.root, this.options.outputFile);
// Map filepaths to be relative to root for workspace support
const files = rawFiles?.map((file) => ({
...file,
name: this.options.onWritePath(relative(process.cwd(), file.filepath)),
}));
const outputDirectory = dirname(reportFile);
if (!existsSync(outputDirectory)) {
mkdirSync(outputDirectory, { recursive: true });
}
const sorted = files?.sort(sortByFilename);
writeFileSync(reportFile, generateXml(sorted), 'utf-8');
if (!this.options.silent) {
this.ctx.logger.log(`SonarQube report written to ${reportFile}`);
}
}
}
function defaultOnWritePath(path) {
return path;
}
function resolveOutputfile(config) {
if (typeof config.outputFile === 'string') {
return config.outputFile;
}
if (config.outputFile['vitest-sonar-reporter']) {
return config.outputFile['vitest-sonar-reporter'];
}
throw new Error([
'Unable to resolve outputFile for vitest-sonar-reporter.',
'Define outputFile in reporter options:',
JSON.stringify({
test: {
reporters: [
[
'vitest-sonar-reporter',
{ outputFile: 'sonar-report.xml' },
],
],
},
}, null, 2),
].join('\n'));
}
function sortByFilename(a, b) {
if (a.name < b.name)
return -1;
if (a.name > b.name)
return 1;
return 0;
}