Skip to content
Open
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
21 changes: 15 additions & 6 deletions packages/create-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ Each plugin exposes its own configuration keys that can be passed as CLI argumen

#### ESLint

| Option | Type | Default | Description |
| ------------------------- | --------- | ------------- | -------------------------- |
| **`--eslint.eslintrc`** | `string` | auto-detected | Path to ESLint config |
| **`--eslint.patterns`** | `string` | `src` or `.` | File patterns to lint |
| **`--eslint.categories`** | `boolean` | `true` | Add recommended categories |
| Option | Type | Default | Description |
| ------------------------- | --------- | ------------- | --------------------- |
| **`--eslint.eslintrc`** | `string` | auto-detected | Path to ESLint config |
| **`--eslint.patterns`** | `string` | `src` or `.` | File patterns to lint |
| **`--eslint.categories`** | `boolean` | `true` | Add ESLint categories |

#### Coverage

Expand All @@ -47,7 +47,16 @@ Each plugin exposes its own configuration keys that can be passed as CLI argumen
| **`--coverage.testCommand`** | `string` | auto-detected | Command to run tests |
| **`--coverage.types`** | `('function'` \| `'branch'` \| `'line')[]` | all | Coverage types to measure |
| **`--coverage.continueOnFail`** | `boolean` | `true` | Continue if test command fails |
| **`--coverage.categories`** | `boolean` | `true` | Add code coverage category |
| **`--coverage.categories`** | `boolean` | `true` | Add Code coverage categories |

#### JS Packages

| Option | Type | Default | Description |
| ------------------------------------ | ---------------------------------------------------------- | ------------- | -------------------------- |
| **`--js-packages.packageManager`** | `'npm'` \| `'yarn-classic'` \| `'yarn-modern'` \| `'pnpm'` | auto-detected | Package manager |
| **`--js-packages.checks`** | `('audit'` \| `'outdated')[]` | both | Checks to run |
| **`--js-packages.dependencyGroups`** | `('prod'` \| `'dev'` \| `'optional')[]` | `prod`, `dev` | Dependency groups |
| **`--js-packages.categories`** | `boolean` | `true` | Add JS packages categories |

### Examples

Expand Down
1 change: 1 addition & 0 deletions packages/create-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"dependencies": {
"@code-pushup/coverage-plugin": "0.121.0",
"@code-pushup/eslint-plugin": "0.121.0",
"@code-pushup/js-packages-plugin": "0.121.0",
"@code-pushup/models": "0.121.0",
"@code-pushup/utils": "0.121.0",
"@inquirer/prompts": "^8.0.0",
Expand Down
4 changes: 3 additions & 1 deletion packages/create-cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import { coverageSetupBinding } from '@code-pushup/coverage-plugin';
import { eslintSetupBinding } from '@code-pushup/eslint-plugin';
import { jsPackagesSetupBinding } from '@code-pushup/js-packages-plugin';
import { parsePluginSlugs, validatePluginSlugs } from './lib/setup/plugins.js';
import {
CI_PROVIDERS,
Expand All @@ -12,10 +13,11 @@ import {
} from './lib/setup/types.js';
import { runSetupWizard } from './lib/setup/wizard.js';

// TODO: create, import and pass remaining plugin bindings (lighthouse, typescript, js-packages, jsdocs, axe)
// TODO: create, import and pass remaining plugin bindings (lighthouse, typescript, jsdocs, axe)
const bindings: PluginSetupBinding[] = [
eslintSetupBinding,
coverageSetupBinding,
jsPackagesSetupBinding,
];

const argv = await yargs(hideBin(process.argv))
Expand Down
2 changes: 1 addition & 1 deletion packages/create-cli/src/lib/setup/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ function addPlugins(
builder.addLine('// TODO: register some plugins', depth + 1);
} else {
builder.addLines(
plugins.map(({ pluginInit }) => `${pluginInit},`),
plugins.flatMap(({ pluginInit }) => pluginInit),
depth + 1,
);
}
Expand Down
35 changes: 21 additions & 14 deletions packages/create-cli/src/lib/setup/codegen.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const ESLINT_PLUGIN: PluginCodegenResult = {
defaultImport: 'eslintPlugin',
},
],
pluginInit: "await eslintPlugin({ patterns: '.' })",
pluginInit: ["await eslintPlugin({ patterns: '.' }),"],
};

const ESLINT_CATEGORIES: CategoryConfig[] = [
Expand Down Expand Up @@ -58,7 +58,7 @@ describe('generateConfigSource', () => {
defaultImport: 'eslintPlugin',
},
],
pluginInit: 'await eslintPlugin()',
pluginInit: ['await eslintPlugin(),'],
};

expect(generateConfigSource([plugin], 'ts')).toMatchInlineSnapshot(`
Expand All @@ -83,8 +83,9 @@ describe('generateConfigSource', () => {
namedImports: ['eslintConfigFromAllNxProjects'],
},
],
pluginInit:
'await eslintPlugin({ eslintrc: eslintConfigFromAllNxProjects() })',
pluginInit: [
'await eslintPlugin({ eslintrc: eslintConfigFromAllNxProjects() }),',
],
};

expect(generateConfigSource([plugin], 'ts')).toMatchInlineSnapshot(`
Expand All @@ -100,7 +101,7 @@ describe('generateConfigSource', () => {
`);
});

it('should generate config with multiple plugins', () => {
it('should generate config with multiple plugins including multiline', () => {
const plugins: PluginCodegenResult[] = [
{
imports: [
Expand All @@ -109,7 +110,7 @@ describe('generateConfigSource', () => {
defaultImport: 'eslintPlugin',
},
],
pluginInit: 'await eslintPlugin()',
pluginInit: ['await eslintPlugin(),'],
},
{
imports: [
Expand All @@ -118,8 +119,11 @@ describe('generateConfigSource', () => {
defaultImport: 'coveragePlugin',
},
],
pluginInit:
"await coveragePlugin({ reports: [{ resultsPath: 'coverage/lcov.info', pathToProject: '' }] })",
pluginInit: [
'await coveragePlugin({',
" reports: ['coverage/lcov.info'],",
'}),',
],
},
];

Expand All @@ -131,7 +135,9 @@ describe('generateConfigSource', () => {
export default {
plugins: [
await eslintPlugin(),
await coveragePlugin({ reports: [{ resultsPath: 'coverage/lcov.info', pathToProject: '' }] }),
await coveragePlugin({
reports: ['coverage/lcov.info'],
}),
],
} satisfies CoreConfig;
"
Expand Down Expand Up @@ -160,7 +166,7 @@ describe('generateConfigSource', () => {
defaultImport: 'eslintPlugin',
},
],
pluginInit: 'await eslintPlugin()',
pluginInit: ['await eslintPlugin(),'],
};

expect(generateConfigSource([plugin], 'js')).toMatchInlineSnapshot(`
Expand All @@ -185,7 +191,7 @@ describe('generateConfigSource', () => {
defaultImport: 'eslintPlugin',
},
],
pluginInit: 'await eslintPlugin()',
pluginInit: ['await eslintPlugin(),'],
},
{
imports: [
Expand All @@ -194,8 +200,9 @@ describe('generateConfigSource', () => {
defaultImport: 'coveragePlugin',
},
],
pluginInit:
"await coveragePlugin({ reports: [{ resultsPath: 'coverage/lcov.info', pathToProject: '' }] })",
pluginInit: [
"await coveragePlugin({ reports: [{ resultsPath: 'coverage/lcov.info', pathToProject: '' }] }),",
],
},
];

Expand Down Expand Up @@ -266,7 +273,7 @@ describe('generateConfigSource', () => {
defaultImport: 'coveragePlugin',
},
],
pluginInit: 'await coveragePlugin()',
pluginInit: ['await coveragePlugin(),'],
categories: [
{
slug: 'code-coverage',
Expand Down
4 changes: 2 additions & 2 deletions packages/create-cli/src/lib/setup/plugins.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ describe('validatePluginSlugs', () => {
slug: 'eslint',
title: 'ESLint',
packageName: '@code-pushup/eslint-plugin',
generateConfig: () => ({ imports: [], pluginInit: '' }),
generateConfig: () => ({ imports: [], pluginInit: [] }),
},
{
slug: 'coverage',
title: 'Code Coverage',
packageName: '@code-pushup/coverage-plugin',
generateConfig: () => ({ imports: [], pluginInit: '' }),
generateConfig: () => ({ imports: [], pluginInit: [] }),
},
];

Expand Down
6 changes: 3 additions & 3 deletions packages/create-cli/src/lib/setup/prompts.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,19 @@ describe('promptPluginSelection', () => {
slug: 'eslint',
title: 'ESLint',
packageName: '@code-pushup/eslint-plugin',
generateConfig: () => ({ imports: [], pluginInit: '' }),
generateConfig: () => ({ imports: [], pluginInit: [] }),
},
{
slug: 'coverage',
title: 'Code Coverage',
packageName: '@code-pushup/coverage-plugin',
generateConfig: () => ({ imports: [], pluginInit: '' }),
generateConfig: () => ({ imports: [], pluginInit: [] }),
},
{
slug: 'lighthouse',
title: 'Lighthouse',
packageName: '@code-pushup/lighthouse-plugin',
generateConfig: () => ({ imports: [], pluginInit: '' }),
generateConfig: () => ({ imports: [], pluginInit: [] }),
},
];

Expand Down
4 changes: 2 additions & 2 deletions packages/create-cli/src/lib/setup/wizard.int.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const TEST_BINDINGS: PluginSetupBinding[] = [
defaultImport: 'alphaPlugin',
},
],
pluginInit: `alphaPlugin(${JSON.stringify(configPath)})`,
pluginInit: [`alphaPlugin(${JSON.stringify(configPath)}),`],
};
},
},
Expand All @@ -53,7 +53,7 @@ const TEST_BINDINGS: PluginSetupBinding[] = [
defaultImport: 'betaPlugin',
},
],
pluginInit: 'betaPlugin()',
pluginInit: ['betaPlugin(),'],
}),
},
];
Expand Down
6 changes: 3 additions & 3 deletions packages/create-cli/src/lib/setup/wizard.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const TEST_BINDING: PluginSetupBinding = {
defaultImport: 'testPlugin',
},
],
pluginInit: 'testPlugin()',
pluginInit: ['testPlugin(),'],
}),
};

Expand Down Expand Up @@ -172,7 +172,7 @@ describe('runSetupWizard', () => {
defaultImport: 'testPlugin',
},
],
pluginInit: 'testPlugin()',
pluginInit: ['testPlugin(),'],
}),
};

Expand All @@ -189,7 +189,7 @@ describe('runSetupWizard', () => {
defaultImport: 'rootPlugin',
},
],
pluginInit: 'rootPlugin()',
pluginInit: ['rootPlugin(),'],
}),
};

Expand Down
2 changes: 1 addition & 1 deletion packages/models/src/lib/plugin-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export type PluginAnswer = string | string[] | boolean;
/** Code a plugin binding contributes to the generated config. */
export type PluginCodegenResult = {
imports: ImportDeclarationStructure[];
pluginInit: string;
pluginInit: string[];
categories?: CategoryConfig[];
};

Expand Down
60 changes: 28 additions & 32 deletions packages/plugin-coverage/src/lib/binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import type {
PluginSetupTree,
} from '@code-pushup/models';
import {
answerArray,
answerBoolean,
answerString,
hasDependency,
pluralize,
readJsonFile,
Expand Down Expand Up @@ -119,7 +122,7 @@ export const coverageSetupBinding = {
},
{
key: 'coverage.categories',
message: 'Add code coverage category?',
message: 'Add Code coverage categories?',
type: 'confirm',
default: true,
},
Expand All @@ -129,37 +132,28 @@ export const coverageSetupBinding = {
answers: Record<string, PluginAnswer>,
tree?: PluginSetupTree,
) => {
const args = parseAnswers(answers);
const lcovConfigured = await configureLcovReporter(args, tree);
const options = parseAnswers(answers);
const lcovConfigured = await configureLcovReporter(options, tree);
return {
imports: [
{ moduleSpecifier: PACKAGE_NAME, defaultImport: 'coveragePlugin' },
],
pluginInit: formatPluginInit(args, lcovConfigured),
...(args.categories ? { categories: CATEGORIES } : {}),
pluginInit: formatPluginInit(options, lcovConfigured),
...(options.categories ? { categories: CATEGORIES } : {}),
};
},
} satisfies PluginSetupBinding;

function parseAnswers(answers: Record<string, PluginAnswer>): CoverageOptions {
const string = (key: string) => {
const value = answers[key];
return typeof value === 'string' ? value : '';
};
const types = answers['coverage.types'];
return {
framework: string('coverage.framework'),
configFile: string('coverage.configFile'),
reportPath: string('coverage.reportPath') || DEFAULT_REPORT_PATH,
testCommand: string('coverage.testCommand'),
types: Array.isArray(types)
? types
: (typeof types === 'string' ? types : '')
.split(',')
.map(item => item.trim())
.filter(Boolean),
continueOnFail: answers['coverage.continueOnFail'] !== false,
categories: answers['coverage.categories'] !== false,
framework: answerString(answers, 'coverage.framework'),
configFile: answerString(answers, 'coverage.configFile'),
reportPath:
answerString(answers, 'coverage.reportPath') || DEFAULT_REPORT_PATH,
testCommand: answerString(answers, 'coverage.testCommand'),
types: answerArray(answers, 'coverage.types'),
continueOnFail: answerBoolean(answers, 'coverage.continueOnFail'),
categories: answerBoolean(answers, 'coverage.categories'),
};
}

Expand Down Expand Up @@ -190,27 +184,29 @@ async function configureLcovReporter(
function formatPluginInit(
options: CoverageOptions,
lcovConfigured: boolean,
): string {
): string[] {
const { reportPath, testCommand, types, continueOnFail } = options;

const hasCustomTypes =
types.length > 0 && types.length < ALL_COVERAGE_TYPES.length;

const body = [
`reports: [${singleQuote(reportPath)}]`,
`reports: [${singleQuote(reportPath)}],`,
testCommand
? `coverageToolCommand: { command: ${singleQuote(testCommand)} }`
? `coverageToolCommand: { command: ${singleQuote(testCommand)} },`
: '',
hasCustomTypes
? `coverageTypes: [${types.map(singleQuote).join(', ')}]`
? `coverageTypes: [${types.map(singleQuote).join(', ')}],`
: '',
continueOnFail ? '' : 'continueOnCommandFail: false',
]
.filter(Boolean)
.join(',\n ');
continueOnFail ? '' : 'continueOnCommandFail: false,',
].filter(Boolean);

const init = `await coveragePlugin({\n ${body},\n })`;
return lcovConfigured ? init : `${LCOV_COMMENT}\n ${init}`;
const init = [
'await coveragePlugin({',
...body.map(line => ` ${line}`),
'}),',
];
return lcovConfigured ? init : [LCOV_COMMENT, ...init];
}

async function isRecommended(targetDir: string): Promise<boolean> {
Expand Down
Loading
Loading