UNPKG

vitest-sonar-reporter

Version:
77 lines (76 loc) 2.62 kB
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; }