Skip to content

Commit 6876789

Browse files
committed
feat(plugin-coverage): add setup wizard binding
1 parent 28ccfcb commit 6876789

File tree

13 files changed

+717
-22
lines changed

13 files changed

+717
-22
lines changed

package-lock.json

Lines changed: 13 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"glob": "^11.0.1",
3333
"lighthouse": "^12.0.0",
3434
"lighthouse-logger": "2.0.1",
35+
"magicast": "^0.3.5",
3536
"nx": "22.3.3",
3637
"ora": "^9.0.0",
3738
"parse-lcov": "^1.0.4",

packages/create-cli/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ Each plugin exposes its own configuration keys that can be passed as CLI argumen
3737
| **`--eslint.patterns`** | `string` | `src` or `.` | File patterns to lint |
3838
| **`--eslint.categories`** | `boolean` | `true` | Add recommended categories |
3939

40+
#### Coverage
41+
42+
| Option | Type | Default | Description |
43+
| ------------------------------- | -------------------------------------- | -------------------- | ------------------------------ |
44+
| **`--coverage.framework`** | `'jest'` \| `'vitest'` \| `'other'` | auto-detected | Test framework |
45+
| **`--coverage.configFile`** | `string` | auto-detected | Path to test config file |
46+
| **`--coverage.reportPath`** | `string` | `coverage/lcov.info` | Path to LCOV report file |
47+
| **`--coverage.testCommand`** | `string` | auto-detected | Command to run tests |
48+
| **`--coverage.types`** | `'function'` \| `'branch'` \| `'line'` | all | Coverage types to measure |
49+
| **`--coverage.continueOnFail`** | `boolean` | `true` | Continue if test command fails |
50+
| **`--coverage.categories`** | `boolean` | `true` | Add code coverage category |
51+
4052
### Examples
4153

4254
Run interactively (default):

packages/create-cli/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
},
2727
"type": "module",
2828
"dependencies": {
29+
"@code-pushup/coverage-plugin": "0.120.1",
2930
"@code-pushup/eslint-plugin": "0.120.1",
3031
"@code-pushup/models": "0.120.1",
3132
"@code-pushup/utils": "0.120.1",

packages/create-cli/src/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#! /usr/bin/env node
22
import yargs from 'yargs';
33
import { hideBin } from 'yargs/helpers';
4+
import { coverageSetupBinding } from '@code-pushup/coverage-plugin';
45
import { eslintSetupBinding } from '@code-pushup/eslint-plugin';
56
import { parsePluginSlugs, validatePluginSlugs } from './lib/setup/plugins.js';
67
import {
@@ -11,8 +12,11 @@ import {
1112
} from './lib/setup/types.js';
1213
import { runSetupWizard } from './lib/setup/wizard.js';
1314

14-
// TODO: create, import and pass remaining plugin bindings (coverage, lighthouse, typescript, js-packages, jsdocs, axe)
15-
const bindings: PluginSetupBinding[] = [eslintSetupBinding];
15+
// TODO: create, import and pass remaining plugin bindings (lighthouse, typescript, js-packages, jsdocs, axe)
16+
const bindings: PluginSetupBinding[] = [
17+
eslintSetupBinding,
18+
coverageSetupBinding,
19+
];
1620

1721
const argv = await yargs(hideBin(process.argv))
1822
.option('dry-run', {

packages/create-cli/src/lib/setup/wizard.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import type {
3232
PluginCodegenResult,
3333
PluginSetupBinding,
3434
ScopedPluginResult,
35+
Tree,
3536
WriteContext,
3637
} from './types.js';
3738
import { createTree } from './virtual-fs.js';
@@ -57,6 +58,8 @@ export async function runSetupWizard(
5758
const format = await promptConfigFormat(targetDir, cliArgs);
5859
const ciProvider = await promptCiProvider(cliArgs);
5960

61+
const tree = createTree(await getGitRoot());
62+
6063
const resolved: ScopedPluginResult[] = await asyncSequential(
6164
selectedBindings,
6265
async binding => ({
@@ -65,11 +68,11 @@ export async function runSetupWizard(
6568
}),
6669
);
6770

71+
await applyAdjustments(tree, resolved);
72+
6873
const packageJson = await readPackageJson(targetDir);
6974
const isEsm = packageJson.type === 'module';
7075
const configFilename = resolveFilename('code-pushup.config', format, isEsm);
71-
72-
const tree = createTree(await getGitRoot());
7376
const writeContext: WriteContext = { tree, format, configFilename, isEsm };
7477

7578
await (context.mode === 'monorepo' && context.tool != null
@@ -112,6 +115,21 @@ async function resolveBinding(
112115
return binding.generateConfig(answers);
113116
}
114117

118+
async function applyAdjustments(
119+
tree: Pick<Tree, 'read' | 'write'>,
120+
resolved: ScopedPluginResult[],
121+
): Promise<void> {
122+
await asyncSequential(
123+
resolved.flatMap(({ result }) => result.adjustments ?? []),
124+
async ({ path: filePath, transform }) => {
125+
const content = await tree.read(filePath);
126+
if (content != null) {
127+
await tree.write(filePath, transform(content));
128+
}
129+
},
130+
);
131+
}
132+
115133
async function writeStandaloneConfig(
116134
{ tree, format, configFilename }: WriteContext,
117135
results: PluginCodegenResult[],

packages/models/src/lib/plugin-setup.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,15 @@ export type ImportDeclarationStructure = {
4747
/** A single value in the answers record produced by plugin prompts. */
4848
export type PluginAnswer = string | string[] | boolean;
4949

50-
/** Import declarations and plugin initialization code produced by `generateConfig`. */
50+
/** Code and file changes a plugin binding contributes to the generated config. */
5151
export type PluginCodegenResult = {
5252
imports: ImportDeclarationStructure[];
5353
pluginInit: string;
5454
categories?: CategoryConfig[];
55+
adjustments?: {
56+
path: string;
57+
transform: (content: string) => string;
58+
}[];
5559
};
5660

5761
/**

packages/plugin-coverage/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"dependencies": {
3737
"@code-pushup/models": "0.120.1",
3838
"@code-pushup/utils": "0.120.1",
39+
"magicast": "^0.3.5",
3940
"parse-lcov": "^1.0.4",
4041
"zod": "^4.2.1"
4142
},
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { coveragePlugin } from './lib/coverage-plugin.js';
22

33
export default coveragePlugin;
4+
export { coverageSetupBinding } from './lib/binding.js';
45
export type { CoveragePluginConfig } from './lib/config.js';
56
export { getNxCoveragePaths } from './lib/nx/coverage-paths.js';

0 commit comments

Comments
 (0)