Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/plugin-coverage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
"@code-pushup/models": "0.96.1",
"@code-pushup/utils": "0.96.1",
"parse-lcov": "^1.0.4",
"yargs": "^17.7.2",
"zod": "^4.0.5"
},
"peerDependencies": {
Expand Down
7 changes: 0 additions & 7 deletions packages/plugin-coverage/src/bin.ts

This file was deleted.

12 changes: 2 additions & 10 deletions packages/plugin-coverage/src/lib/coverage-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { createRequire } from 'node:module';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import {
type Audit,
type Group,
Expand All @@ -13,7 +11,7 @@ import {
type CoverageType,
coveragePluginConfigSchema,
} from './config.js';
import { createRunnerConfig } from './runner/index.js';
import { createRunnerFunction } from './runner/index.js';
import { coverageDescription, coverageTypeWeightMapper } from './utils.js';

/**
Expand Down Expand Up @@ -60,12 +58,6 @@ export async function coveragePlugin(
})),
};

const runnerScriptPath = path.join(
fileURLToPath(path.dirname(import.meta.url)),
'..',
'bin.js',
);

const packageJson = createRequire(import.meta.url)(
'../../package.json',
) as typeof import('../../package.json');
Expand All @@ -82,7 +74,7 @@ export async function coveragePlugin(
version: packageJson.version,
audits,
groups: [group],
runner: await createRunnerConfig(runnerScriptPath, coverageConfig),
runner: createRunnerFunction(coverageConfig),
...(scoreTargets && { scoreTargets }),
};
}
11 changes: 2 additions & 9 deletions packages/plugin-coverage/src/lib/coverage-plugin.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import path from 'node:path';
import { describe, expect, it } from 'vitest';
import { type RunnerConfig, pluginConfigSchema } from '@code-pushup/models';
import { pluginConfigSchema } from '@code-pushup/models';
import { coveragePlugin } from './coverage-plugin.js';

vi.mock('./runner/index.ts', () => ({
createRunnerConfig: vi.fn().mockReturnValue({
command: 'node',
outputFile: 'runner-output.json',
} satisfies RunnerConfig),
}));

describe('coveragePlugin', () => {
const LCOV_PATH = path.join(
'packages',
Expand All @@ -30,7 +23,7 @@ describe('coveragePlugin', () => {
title: 'Code coverage',
audits: expect.any(Array),
groups: expect.any(Array),
runner: expect.any(Object),
runner: expect.any(Function),
}),
);
});
Expand Down
78 changes: 25 additions & 53 deletions packages/plugin-coverage/src/lib/runner/index.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,34 @@
import { writeFile } from 'node:fs/promises';
import path from 'node:path';
import type { RunnerConfig, RunnerFilesPaths } from '@code-pushup/models';
import {
createRunnerFiles,
ensureDirectoryExists,
executeProcess,
filePathToCliArg,
objectToCliArgs,
readJsonFile,
} from '@code-pushup/utils';
import type { RunnerFunction } from '@code-pushup/models';
import { executeProcess } from '@code-pushup/utils';
import type { FinalCoveragePluginConfig } from '../config.js';
import { lcovResultsToAuditOutputs } from './lcov/lcov-runner.js';

export async function executeRunner({
runnerConfigPath,
runnerOutputPath,
}: RunnerFilesPaths): Promise<void> {
const { reports, coverageToolCommand, continueOnCommandFail, coverageTypes } =
await readJsonFile<FinalCoveragePluginConfig>(runnerConfigPath);
export function createRunnerFunction(
config: FinalCoveragePluginConfig,
): RunnerFunction {
return async () => {
const {
reports,
coverageToolCommand,
continueOnCommandFail,
coverageTypes,
} = config;

// Run coverage tool if provided
if (coverageToolCommand != null) {
const { command, args } = coverageToolCommand;
try {
await executeProcess({ command, args });
} catch {
if (!continueOnCommandFail) {
throw new Error(
'Coverage plugin: Running coverage tool failed. Make sure all your provided tests are passing.',
);
// Run coverage tool if provided
if (coverageToolCommand != null) {
const { command, args } = coverageToolCommand;
try {
await executeProcess({ command, args });
} catch {
if (!continueOnCommandFail) {
throw new Error(
'Coverage plugin: Running coverage tool failed. Make sure all your provided tests are passing.',
);
}
}
}
}

// Calculate coverage from LCOV results
const auditOutputs = await lcovResultsToAuditOutputs(reports, coverageTypes);

await ensureDirectoryExists(path.dirname(runnerOutputPath));
await writeFile(runnerOutputPath, JSON.stringify(auditOutputs));
}

export async function createRunnerConfig(
scriptPath: string,
config: FinalCoveragePluginConfig,
): Promise<RunnerConfig> {
// Create JSON config for executeRunner
const { runnerConfigPath, runnerOutputPath } = await createRunnerFiles(
'coverage',
JSON.stringify(config),
);

return {
command: 'node',
args: [
filePathToCliArg(scriptPath),
...objectToCliArgs({ runnerConfigPath, runnerOutputPath }),
],
configFile: runnerConfigPath,
outputFile: runnerOutputPath,
// Calculate coverage from LCOV results
return lcovResultsToAuditOutputs(reports, coverageTypes);
};
}
67 changes: 9 additions & 58 deletions packages/plugin-coverage/src/lib/runner/runner.int.test.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,12 @@
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { expect } from 'vitest';
import type { AuditOutputs, RunnerConfig } from '@code-pushup/models';
import { createRunnerFiles, readJsonFile } from '@code-pushup/utils';
import type { FinalCoveragePluginConfig } from '../config.js';
import { createRunnerConfig, executeRunner } from './index.js';
import { type AuditOutputs, DEFAULT_PERSIST_CONFIG } from '@code-pushup/models';
import { createRunnerFunction } from './index.js';

describe('createRunnerConfig', () => {
it('should create a valid runner config', async () => {
const runnerConfig = await createRunnerConfig('executeRunner.ts', {
reports: ['coverage/lcov.info'],
coverageTypes: ['branch'],
scoreTargets: 0.85,
continueOnCommandFail: true,
});
expect(runnerConfig).toStrictEqual<RunnerConfig>({
command: 'node',
args: [
'"executeRunner.ts"',
expect.stringContaining('plugin-config.json'),
expect.stringContaining('runner-output.json'),
],
outputFile: expect.stringContaining('runner-output.json'),
configFile: expect.stringContaining('plugin-config.json'),
});
});

it('should provide plugin config to runner in JSON file', async () => {
const pluginConfig: FinalCoveragePluginConfig = {
coverageTypes: ['line'],
reports: ['coverage/lcov.info'],
coverageToolCommand: { command: 'npm', args: ['run', 'test'] },
scoreTargets: 0.85,
continueOnCommandFail: true,
};

const { configFile } = await createRunnerConfig(
'executeRunner.ts',
pluginConfig,
);

expect(configFile).toMatch(/.*plugin-config\.json$/);
const config = await readJsonFile<FinalCoveragePluginConfig>(configFile!);
expect(config).toStrictEqual(pluginConfig);
});
});

describe('executeRunner', () => {
describe('createRunnerFunction', () => {

Check failure on line 7 in packages/plugin-coverage/src/lib/runner/runner.int.test.ts

View workflow job for this annotation

GitHub Actions / Standalone mode

<✓> TypeScript | Semantic errors

TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.
it('should successfully execute runner', async () => {

Check failure on line 8 in packages/plugin-coverage/src/lib/runner/runner.int.test.ts

View workflow job for this annotation

GitHub Actions / Standalone mode

<✓> TypeScript | Semantic errors

TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.
const config: FinalCoveragePluginConfig = {
const runner = createRunnerFunction({
reports: [
path.join(
fileURLToPath(path.dirname(import.meta.url)),
Expand All @@ -61,18 +19,11 @@
],
coverageTypes: ['line'],
continueOnCommandFail: true,
};

const runnerFiles = await createRunnerFiles(
'coverage',
JSON.stringify(config),
);
await executeRunner(runnerFiles);
});

const results = await readJsonFile<AuditOutputs>(
runnerFiles.runnerOutputPath,
);
expect(results).toStrictEqual<AuditOutputs>([
await expect(
runner({ persist: DEFAULT_PERSIST_CONFIG }),
).resolves.toStrictEqual([
{
slug: 'line-coverage',
score: 0.7,
Expand Down Expand Up @@ -112,6 +63,6 @@
],
},
},
]);
] satisfies AuditOutputs);
});
});
1 change: 0 additions & 1 deletion packages/plugin-js-packages/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"@code-pushup/utils": "0.96.1",
"build-md": "^0.4.1",
"semver": "^7.6.0",
"yargs": "^17.7.2",
"zod": "^4.0.5"
},
"files": [
Expand Down
1 change: 0 additions & 1 deletion packages/plugin-js-packages/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"build": {},
"lint": {},
"unit-test": {},
"int-test": {},
"code-pushup": {},
"code-pushup-eslint": {},
"code-pushup-coverage": {},
Expand Down
7 changes: 0 additions & 7 deletions packages/plugin-js-packages/src/bin.ts

This file was deleted.

12 changes: 2 additions & 10 deletions packages/plugin-js-packages/src/lib/js-packages-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { createRequire } from 'node:module';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import type { Audit, Group, PluginConfig } from '@code-pushup/models';
import {
type DependencyGroup,
Expand All @@ -11,7 +9,7 @@ import {
} from './config.js';
import { dependencyDocs, dependencyGroupWeights } from './constants.js';
import { packageManagers } from './package-managers/package-managers.js';
import { createRunnerConfig } from './runner/index.js';
import { createRunnerFunction } from './runner/index.js';
import { normalizeConfig } from './utils.js';

/**
Expand Down Expand Up @@ -42,12 +40,6 @@ export async function jsPackagesPlugin(
...jsPackagesPluginConfigRest
} = await normalizeConfig(config);

const runnerScriptPath = path.join(
fileURLToPath(path.dirname(import.meta.url)),
'..',
'bin.js',
);

const packageJson = createRequire(import.meta.url)(
'../../package.json',
) as typeof import('../../package.json');
Expand All @@ -63,7 +55,7 @@ export async function jsPackagesPlugin(
version: packageJson.version,
audits: createAudits(packageManager.slug, checks, depGroups),
groups: createGroups(packageManager.slug, checks, depGroups),
runner: await createRunnerConfig(runnerScriptPath, {
runner: createRunnerFunction({
...jsPackagesPluginConfigRest,
checks,
packageManager: packageManager.slug,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,11 @@ import { describe, expect, it } from 'vitest';
import {
type Group,
type PluginConfig,
type RunnerConfig,
pluginConfigSchema,
} from '@code-pushup/models';
import { MEMFS_VOLUME } from '@code-pushup/test-utils';
import { jsPackagesPlugin } from './js-packages-plugin.js';

vi.mock('./runner/index.ts', () => ({
createRunnerConfig: vi.fn().mockReturnValue({
command: 'node',
outputFile: 'runner-output.json',
} satisfies RunnerConfig),
}));

describe('jsPackagesPlugin', () => {
it('should initialise the plugin without a given config for NPM', async () => {
vol.fromJSON(
Expand Down Expand Up @@ -60,7 +52,7 @@ describe('jsPackagesPlugin', () => {
title: 'JS Packages',
audits: expect.any(Array),
groups: expect.any(Array),
runner: expect.any(Object),
runner: expect.any(Function),
}),
);
});
Expand Down
Loading