From 22d25a27459070b2b509710bdc44212962a6578a Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 12 Dec 2023 23:23:01 +0100 Subject: [PATCH 01/17] refactor(cli): adjust persist.format options --- e2e/cli-e2e/tests/print-config.e2e.test.ts | 4 ++-- packages/cli/src/lib/implementation/core-config-options.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index e94af5e44..836798631 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -14,7 +14,7 @@ describe('print-config', () => { '--no-progress', `--config=${configFile(ext)}`, '--persist.outputDir=my-dir', - '--persist.format=md', + '--persist.format=md,json', '--persist.filename=my-report', ], }); @@ -32,7 +32,7 @@ describe('print-config', () => { }, persist: { outputDir: 'my-dir', - format: ['md'], + format: ['md', 'json'], filename: 'my-report', }, plugins: expect.arrayContaining([ diff --git a/packages/cli/src/lib/implementation/core-config-options.ts b/packages/cli/src/lib/implementation/core-config-options.ts index ad8bce16c..35394a028 100644 --- a/packages/cli/src/lib/implementation/core-config-options.ts +++ b/packages/cli/src/lib/implementation/core-config-options.ts @@ -16,6 +16,8 @@ export function yargsCoreConfigOptionsDefinition(): Record { 'persist.format': { describe: 'Format of the report output. e.g. `md`, `json`', type: 'array', + default: [], + coerce: (arg: string[]) => arg.flatMap(v => v.split(',')), }, // upload 'upload.organization': { From b60b831a3413b6dcca4a5c3ed5fca81d519f852a Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Dec 2023 22:30:33 +0100 Subject: [PATCH 02/17] feat(cli): support comma seperated formats --- .../tests/__snapshots__/help.e2e.test.ts.snap | 2 +- e2e/cli-e2e/tests/print-config.e2e.test.ts | 97 +++++++++++++++++-- examples/plugins/project.json | 4 + packages/cli/package.json | 3 +- .../cli/src/lib/collect/collect-command.ts | 6 ++ .../lib/implementation/config-middleware.ts | 6 +- .../lib/implementation/core-config-options.ts | 1 - .../lib/implementation/only-plugins-utils.ts | 10 +- .../only-plugins-utils.unit.test.ts | 10 +- packages/cli/src/lib/implementation/utils.ts | 6 ++ .../lib/print-config/print-config-command.ts | 8 +- 11 files changed, 126 insertions(+), 27 deletions(-) diff --git a/e2e/cli-e2e/tests/__snapshots__/help.e2e.test.ts.snap b/e2e/cli-e2e/tests/__snapshots__/help.e2e.test.ts.snap index d3ecea32c..068b158d5 100644 --- a/e2e/cli-e2e/tests/__snapshots__/help.e2e.test.ts.snap +++ b/e2e/cli-e2e/tests/__snapshots__/help.e2e.test.ts.snap @@ -21,7 +21,7 @@ Options: --persist.outputDir Directory for the produced reports [string] --persist.filename Filename for the produced reports. [string] --persist.format Format of the report output. e.g. \`md\`, \`json\` - [array] + [array] [default: []] --upload.organization Organization slug from portal [string] --upload.project Project slug from portal [string] --upload.server URL to your portal server [string] diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 836798631..fb6d1f4ac 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -1,5 +1,5 @@ import { expect } from 'vitest'; -import { executeProcess } from '@code-pushup/utils'; +import {executeProcess, objectToCliArgs} from '@code-pushup/utils'; import { configFile, extensions } from '../mocks/utils'; describe('print-config', () => { @@ -13,9 +13,6 @@ describe('print-config', () => { '--verbose', '--no-progress', `--config=${configFile(ext)}`, - '--persist.outputDir=my-dir', - '--persist.format=md,json', - '--persist.filename=my-report', ], }); @@ -31,12 +28,12 @@ describe('print-config', () => { server: 'https://e2e.com/api', }, persist: { - outputDir: 'my-dir', - format: ['md', 'json'], - filename: 'my-report', + filename: "report", + format: [], + outputDir: `tmp/${ext}`, }, plugins: expect.arrayContaining([ - expect.objectContaining({ slug: 'eslint', title: 'ESLint' }), + expect.objectContaining({slug: 'eslint', title: 'ESLint'}), expect.objectContaining({ slug: 'lighthouse', title: 'ChromeDevTools Lighthouse', @@ -50,4 +47,88 @@ describe('print-config', () => { }, 120000, ); + + it.each([ + // defaults + [{}, []], + [{onlyPlugins: 'lighthouse'}, ['lighthouse']], + [{onlyPlugins: ['lighthouse', 'eslint']}, ['lighthouse', 'eslint']], + [{onlyPlugins: 'lighthouse,eslint'}, ['lighthouse', 'eslint']], + ])('should parse onlyPlugins options correctly', + async (options, result) => { + const {code, stderr, stdout} = await executeProcess({ + command: 'code-pushup', + args: [ + 'print-config', + '--no-verbose', + '--no-progress', + `--config=${configFile('ts')}`, + ...objectToCliArgs(options) + ], + }); + + expect(JSON.parse(stdout)?.onlyPlugins).toEqual(result); + }, + 120000, + ); + + it.each([ + // defaults + [{}, { + format: [], + filename: 'report', + }], + // persist.outputDir + [{'persist.outputDir': 'my-dir'}, {outputDir: 'my-dir'}], + // persist.filename + [{'persist.filename': 'my-report'}, {filename: 'my-report'}], + // persist.format + [{'persist.format': 'md'}, {format: ['md']}], + [{'persist.format': ['md', 'json']}, {format: ['md', 'json']}], + [{'persist.format': 'md,json'}, {format: ['md', 'json']}] + ])('should parse persist options correctly', + async (options, result) => { + const {code, stderr, stdout} = await executeProcess({ + command: 'code-pushup', + args: [ + 'print-config', + '--verbose', + '--no-progress', + `--config=${configFile('ts')}`, + ...objectToCliArgs(options) + ], + }); + + expect(JSON.parse(stdout)?.persist).toEqual( + expect.objectContaining(result), + ); + }, + 120000, + ); + + it('should load .ts config file with overloads arguments', + async () => { + const {code, stderr, stdout} = await executeProcess({ + command: 'code-pushup', + args: [ + 'print-config', + '--verbose', + '--no-progress', + `--config=${configFile('ts')}`, + '--persist.outputDir=my-dir', + '--persist.format=md', + '--persist.filename=my-report', + ], + }); + + expect(JSON.parse(stdout)?.persist).toEqual( + expect.objectContaining({ + outputDir: 'my-dir', + format: ['md'], + filename: 'my-report', + }), + ); + }, + 120000, + ); }); diff --git a/examples/plugins/project.json b/examples/plugins/project.json index 9ad93a38b..dea0ce09e 100644 --- a/examples/plugins/project.json +++ b/examples/plugins/project.json @@ -34,6 +34,10 @@ "run-collect": { "command": "npx dist/packages/cli collect --config=examples/plugins/code-pushup.config.ts --persist.format=md", "dependsOn": ["^build"] + }, + "run-print-config": { + "command": "npx dist/packages/cli print-config --config=examples/plugins/code-pushup.config.ts", + "dependsOn": ["^build"] } }, "tags": [] diff --git a/packages/cli/package.json b/packages/cli/package.json index 1c839699f..fd906068d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -8,6 +8,7 @@ "@code-pushup/models": "*", "@code-pushup/core": "*", "yargs": "^17.7.2", - "chalk": "^5.3.0" + "chalk": "^5.3.0", + "@code-pushup/utils": "*" } } diff --git a/packages/cli/src/lib/collect/collect-command.ts b/packages/cli/src/lib/collect/collect-command.ts index e4cf839b1..0102e50d8 100644 --- a/packages/cli/src/lib/collect/collect-command.ts +++ b/packages/cli/src/lib/collect/collect-command.ts @@ -14,6 +14,12 @@ export function yargsCollectCommandObject(): CommandModule { describe: 'Run Plugins and collect results', builder: { onlyPlugins: onlyPluginsOption, + 'persist.format': { + describe: 'Format of the report output. e.g. `md`, `json`', + type: 'array', + default: [], + coerce: (arg: string[]) => arg.flatMap(v => v.split(',')), + }, }, handler: async (args: ArgumentsCamelCase) => { const options = args as unknown as CollectAndPersistReportsOptions; diff --git a/packages/cli/src/lib/implementation/config-middleware.ts b/packages/cli/src/lib/implementation/config-middleware.ts index e63d05f6b..ad2aa6578 100644 --- a/packages/cli/src/lib/implementation/config-middleware.ts +++ b/packages/cli/src/lib/implementation/config-middleware.ts @@ -1,11 +1,12 @@ import { readCodePushupConfig } from '@code-pushup/core'; -import { CoreConfig } from '@code-pushup/models'; +import { CoreConfig, Format } from '@code-pushup/models'; import { GeneralCliOptions, OnlyPluginsOptions } from './model'; import { filterCategoryByOnlyPluginsOption, filterPluginsByOnlyPluginsOption, validateOnlyPluginsOption, } from './only-plugins-utils'; +import {coerceArray} from "./utils"; export async function configMiddleware< T extends Partial, @@ -28,8 +29,9 @@ export async function configMiddleware< ...cliOptions.upload, }, persist: { - ...importedRc.persist, + ...importedRc?.persist, ...cliOptions.persist, + format: coerceArray(cliOptions?.persist?.format) }, plugins: filterPluginsByOnlyPluginsOption(importedRc.plugins, cliOptions), categories: filterCategoryByOnlyPluginsOption( diff --git a/packages/cli/src/lib/implementation/core-config-options.ts b/packages/cli/src/lib/implementation/core-config-options.ts index 35394a028..4ec35ab04 100644 --- a/packages/cli/src/lib/implementation/core-config-options.ts +++ b/packages/cli/src/lib/implementation/core-config-options.ts @@ -17,7 +17,6 @@ export function yargsCoreConfigOptionsDefinition(): Record { describe: 'Format of the report output. e.g. `md`, `json`', type: 'array', default: [], - coerce: (arg: string[]) => arg.flatMap(v => v.split(',')), }, // upload 'upload.organization': { diff --git a/packages/cli/src/lib/implementation/only-plugins-utils.ts b/packages/cli/src/lib/implementation/only-plugins-utils.ts index 3dab3fc51..130fd3a4b 100644 --- a/packages/cli/src/lib/implementation/only-plugins-utils.ts +++ b/packages/cli/src/lib/implementation/only-plugins-utils.ts @@ -1,5 +1,5 @@ import chalk from 'chalk'; -import { CoreConfig } from '@code-pushup/models'; +import {CoreConfig} from '@code-pushup/models'; export function filterPluginsByOnlyPluginsOption( plugins: CoreConfig['plugins'], @@ -15,7 +15,7 @@ export function filterPluginsByOnlyPluginsOption( // see https://github.com/code-pushup/cli/pull/246#discussion_r1392274281 export function filterCategoryByOnlyPluginsOption( categories: CoreConfig['categories'], - { onlyPlugins }: { onlyPlugins?: string[] }, + { onlyPlugins, verbose = false }: { onlyPlugins?: string[], verbose?:boolean }, ): CoreConfig['categories'] { if (!onlyPlugins?.length) { return categories; @@ -26,7 +26,7 @@ export function filterCategoryByOnlyPluginsOption( const isNotSkipped = onlyPlugins.includes(ref.slug); if (!isNotSkipped) { - console.info( + verbose && console.info( `${chalk.yellow('⚠')} Category "${ category.title }" is ignored because it references audits from skipped plugin "${ @@ -42,14 +42,14 @@ export function filterCategoryByOnlyPluginsOption( export function validateOnlyPluginsOption( plugins: CoreConfig['plugins'], - { onlyPlugins }: { onlyPlugins?: string[] }, + { onlyPlugins, verbose = false }: { onlyPlugins?: string[], verbose?: boolean }, ): void { const missingPlugins = onlyPlugins?.length ? onlyPlugins.filter(plugin => !plugins.some(({ slug }) => slug === plugin)) : []; if (missingPlugins.length > 0) { - console.warn( + verbose && console.warn( `${chalk.yellow( '⚠', )} The --onlyPlugin argument references plugins with "${missingPlugins.join( diff --git a/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts b/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts index 3b655f4be..6d8c2db3b 100644 --- a/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts +++ b/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts @@ -28,7 +28,7 @@ describe('filterPluginsByOnlyPluginsOption', () => { { slug: 'plugin2' }, { slug: 'plugin3' }, ] as CoreConfig['plugins'], - { onlyPlugins: ['plugin1', 'plugin3'] }, + { onlyPlugins: ['plugin1', 'plugin3']}, ), ).toEqual([{ slug: 'plugin1' }, { slug: 'plugin3' }]); }); @@ -74,7 +74,7 @@ describe('filterCategoryByOnlyPluginsOption', () => { { title: 'category2', refs: [{ slug: 'plugin3' }] }, ] as CoreConfig['categories'], { - onlyPlugins: ['plugin1', 'plugin3'], + onlyPlugins: ['plugin1', 'plugin3'], verbose: true }, ); expect(console.info).toHaveBeenCalledWith( @@ -91,7 +91,7 @@ describe('validateOnlyPluginsOption', () => { validateOnlyPluginsOption( [{ slug: 'plugin1' }, { slug: 'plugin2' }] as CoreConfig['plugins'], { - onlyPlugins: ['plugin1', 'plugin3', 'plugin4'], + onlyPlugins: ['plugin1', 'plugin3', 'plugin4'], verbose: true }, ); expect(console.warn).toHaveBeenCalledWith( @@ -105,9 +105,9 @@ describe('validateOnlyPluginsOption', () => { validateOnlyPluginsOption( [{ slug: 'plugin1' }, { slug: 'plugin2' }] as CoreConfig['plugins'], { - onlyPlugins: ['plugin1'], + onlyPlugins: ['plugin1'], verbose: true }, ); - expect(console.warn).not.toHaveBeenCalled(); + expect(console.info).not.toHaveBeenCalled(); }); }); diff --git a/packages/cli/src/lib/implementation/utils.ts b/packages/cli/src/lib/implementation/utils.ts index 5e409257c..f8c3e13a6 100644 --- a/packages/cli/src/lib/implementation/utils.ts +++ b/packages/cli/src/lib/implementation/utils.ts @@ -1,5 +1,7 @@ // log error and flush stdout so that Yargs doesn't suppress it // related issue: https://github.com/yargs/yargs/issues/2118 +import {toArray} from "@code-pushup/utils"; + export function logErrorBeforeThrow< // eslint-disable-next-line @typescript-eslint/no-explicit-any T extends (...args: any[]) => any, @@ -15,3 +17,7 @@ export function logErrorBeforeThrow< } }) as T; } + +export function coerceArray(param: T | T[] = []): T[] { + return [...new Set(toArray(param).flatMap((f: T) => f.split(',') as T[]) || [])] +} diff --git a/packages/cli/src/lib/print-config/print-config-command.ts b/packages/cli/src/lib/print-config/print-config-command.ts index 6f646ddf3..d0df98a63 100644 --- a/packages/cli/src/lib/print-config/print-config-command.ts +++ b/packages/cli/src/lib/print-config/print-config-command.ts @@ -1,6 +1,6 @@ -import { CommandModule } from 'yargs'; -import { filterKebabCaseKeys } from '../implementation/filter-kebab-case-keys'; -import { onlyPluginsOption } from '../implementation/only-plugins-options'; +import {CommandModule} from 'yargs'; +import {filterKebabCaseKeys} from '../implementation/filter-kebab-case-keys'; +import {onlyPluginsOption} from '../implementation/only-plugins-options'; export function yargsConfigCommandObject() { const command = 'print-config'; @@ -8,7 +8,7 @@ export function yargsConfigCommandObject() { command, describe: 'Print config', builder: { - onlyPlugins: onlyPluginsOption, + onlyPlugins: onlyPluginsOption }, handler: yargsArgs => { // eslint-disable-next-line @typescript-eslint/no-unused-vars From 05d482ff6653f29544a82e57cbb488cdb6817556 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Dec 2023 22:32:21 +0100 Subject: [PATCH 03/17] refactor(cli): format --- e2e/cli-e2e/tests/print-config.e2e.test.ts | 92 ++++++++++--------- .../lib/implementation/config-middleware.ts | 4 +- .../lib/implementation/only-plugins-utils.ts | 46 ++++++---- .../only-plugins-utils.unit.test.ts | 11 ++- packages/cli/src/lib/implementation/utils.ts | 6 +- .../lib/print-config/print-config-command.ts | 8 +- 6 files changed, 91 insertions(+), 76 deletions(-) diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index fb6d1f4ac..0c1320dc6 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -1,5 +1,5 @@ import { expect } from 'vitest'; -import {executeProcess, objectToCliArgs} from '@code-pushup/utils'; +import { executeProcess, objectToCliArgs } from '@code-pushup/utils'; import { configFile, extensions } from '../mocks/utils'; describe('print-config', () => { @@ -28,12 +28,12 @@ describe('print-config', () => { server: 'https://e2e.com/api', }, persist: { - filename: "report", + filename: 'report', format: [], outputDir: `tmp/${ext}`, }, plugins: expect.arrayContaining([ - expect.objectContaining({slug: 'eslint', title: 'ESLint'}), + expect.objectContaining({ slug: 'eslint', title: 'ESLint' }), expect.objectContaining({ slug: 'lighthouse', title: 'ChromeDevTools Lighthouse', @@ -51,19 +51,20 @@ describe('print-config', () => { it.each([ // defaults [{}, []], - [{onlyPlugins: 'lighthouse'}, ['lighthouse']], - [{onlyPlugins: ['lighthouse', 'eslint']}, ['lighthouse', 'eslint']], - [{onlyPlugins: 'lighthouse,eslint'}, ['lighthouse', 'eslint']], - ])('should parse onlyPlugins options correctly', + [{ onlyPlugins: 'lighthouse' }, ['lighthouse']], + [{ onlyPlugins: ['lighthouse', 'eslint'] }, ['lighthouse', 'eslint']], + [{ onlyPlugins: 'lighthouse,eslint' }, ['lighthouse', 'eslint']], + ])( + 'should parse onlyPlugins options correctly', async (options, result) => { - const {code, stderr, stdout} = await executeProcess({ + const { code, stderr, stdout } = await executeProcess({ command: 'code-pushup', args: [ 'print-config', '--no-verbose', '--no-progress', `--config=${configFile('ts')}`, - ...objectToCliArgs(options) + ...objectToCliArgs(options), ], }); @@ -74,28 +75,32 @@ describe('print-config', () => { it.each([ // defaults - [{}, { - format: [], - filename: 'report', - }], + [ + {}, + { + format: [], + filename: 'report', + }, + ], // persist.outputDir - [{'persist.outputDir': 'my-dir'}, {outputDir: 'my-dir'}], + [{ 'persist.outputDir': 'my-dir' }, { outputDir: 'my-dir' }], // persist.filename - [{'persist.filename': 'my-report'}, {filename: 'my-report'}], + [{ 'persist.filename': 'my-report' }, { filename: 'my-report' }], // persist.format - [{'persist.format': 'md'}, {format: ['md']}], - [{'persist.format': ['md', 'json']}, {format: ['md', 'json']}], - [{'persist.format': 'md,json'}, {format: ['md', 'json']}] - ])('should parse persist options correctly', + [{ 'persist.format': 'md' }, { format: ['md'] }], + [{ 'persist.format': ['md', 'json'] }, { format: ['md', 'json'] }], + [{ 'persist.format': 'md,json' }, { format: ['md', 'json'] }], + ])( + 'should parse persist options correctly', async (options, result) => { - const {code, stderr, stdout} = await executeProcess({ + const { code, stderr, stdout } = await executeProcess({ command: 'code-pushup', args: [ 'print-config', '--verbose', '--no-progress', `--config=${configFile('ts')}`, - ...objectToCliArgs(options) + ...objectToCliArgs(options), ], }); @@ -106,29 +111,26 @@ describe('print-config', () => { 120000, ); - it('should load .ts config file with overloads arguments', - async () => { - const {code, stderr, stdout} = await executeProcess({ - command: 'code-pushup', - args: [ - 'print-config', - '--verbose', - '--no-progress', - `--config=${configFile('ts')}`, - '--persist.outputDir=my-dir', - '--persist.format=md', - '--persist.filename=my-report', - ], - }); + it('should load .ts config file with overloads arguments', async () => { + const { code, stderr, stdout } = await executeProcess({ + command: 'code-pushup', + args: [ + 'print-config', + '--verbose', + '--no-progress', + `--config=${configFile('ts')}`, + '--persist.outputDir=my-dir', + '--persist.format=md', + '--persist.filename=my-report', + ], + }); - expect(JSON.parse(stdout)?.persist).toEqual( - expect.objectContaining({ - outputDir: 'my-dir', - format: ['md'], - filename: 'my-report', - }), - ); - }, - 120000, - ); + expect(JSON.parse(stdout)?.persist).toEqual( + expect.objectContaining({ + outputDir: 'my-dir', + format: ['md'], + filename: 'my-report', + }), + ); + }, 120000); }); diff --git a/packages/cli/src/lib/implementation/config-middleware.ts b/packages/cli/src/lib/implementation/config-middleware.ts index ad2aa6578..53cd068cf 100644 --- a/packages/cli/src/lib/implementation/config-middleware.ts +++ b/packages/cli/src/lib/implementation/config-middleware.ts @@ -6,7 +6,7 @@ import { filterPluginsByOnlyPluginsOption, validateOnlyPluginsOption, } from './only-plugins-utils'; -import {coerceArray} from "./utils"; +import { coerceArray } from './utils'; export async function configMiddleware< T extends Partial, @@ -31,7 +31,7 @@ export async function configMiddleware< persist: { ...importedRc?.persist, ...cliOptions.persist, - format: coerceArray(cliOptions?.persist?.format) + format: coerceArray(cliOptions?.persist?.format), }, plugins: filterPluginsByOnlyPluginsOption(importedRc.plugins, cliOptions), categories: filterCategoryByOnlyPluginsOption( diff --git a/packages/cli/src/lib/implementation/only-plugins-utils.ts b/packages/cli/src/lib/implementation/only-plugins-utils.ts index 130fd3a4b..48e779c06 100644 --- a/packages/cli/src/lib/implementation/only-plugins-utils.ts +++ b/packages/cli/src/lib/implementation/only-plugins-utils.ts @@ -1,5 +1,5 @@ import chalk from 'chalk'; -import {CoreConfig} from '@code-pushup/models'; +import { CoreConfig } from '@code-pushup/models'; export function filterPluginsByOnlyPluginsOption( plugins: CoreConfig['plugins'], @@ -15,7 +15,10 @@ export function filterPluginsByOnlyPluginsOption( // see https://github.com/code-pushup/cli/pull/246#discussion_r1392274281 export function filterCategoryByOnlyPluginsOption( categories: CoreConfig['categories'], - { onlyPlugins, verbose = false }: { onlyPlugins?: string[], verbose?:boolean }, + { + onlyPlugins, + verbose = false, + }: { onlyPlugins?: string[]; verbose?: boolean }, ): CoreConfig['categories'] { if (!onlyPlugins?.length) { return categories; @@ -26,13 +29,14 @@ export function filterCategoryByOnlyPluginsOption( const isNotSkipped = onlyPlugins.includes(ref.slug); if (!isNotSkipped) { - verbose && console.info( - `${chalk.yellow('⚠')} Category "${ - category.title - }" is ignored because it references audits from skipped plugin "${ - ref.slug - }"`, - ); + verbose && + console.info( + `${chalk.yellow('⚠')} Category "${ + category.title + }" is ignored because it references audits from skipped plugin "${ + ref.slug + }"`, + ); } return isNotSkipped; @@ -42,21 +46,25 @@ export function filterCategoryByOnlyPluginsOption( export function validateOnlyPluginsOption( plugins: CoreConfig['plugins'], - { onlyPlugins, verbose = false }: { onlyPlugins?: string[], verbose?: boolean }, + { + onlyPlugins, + verbose = false, + }: { onlyPlugins?: string[]; verbose?: boolean }, ): void { const missingPlugins = onlyPlugins?.length ? onlyPlugins.filter(plugin => !plugins.some(({ slug }) => slug === plugin)) : []; if (missingPlugins.length > 0) { - verbose && console.warn( - `${chalk.yellow( - '⚠', - )} The --onlyPlugin argument references plugins with "${missingPlugins.join( - '", "', - )}" slugs, but no such plugins are present in the configuration. Expected one of the following plugin slugs: "${plugins - .map(({ slug }) => slug) - .join('", "')}".`, - ); + verbose && + console.warn( + `${chalk.yellow( + '⚠', + )} The --onlyPlugin argument references plugins with "${missingPlugins.join( + '", "', + )}" slugs, but no such plugins are present in the configuration. Expected one of the following plugin slugs: "${plugins + .map(({ slug }) => slug) + .join('", "')}".`, + ); } } diff --git a/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts b/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts index 6d8c2db3b..bbc762d4f 100644 --- a/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts +++ b/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts @@ -28,7 +28,7 @@ describe('filterPluginsByOnlyPluginsOption', () => { { slug: 'plugin2' }, { slug: 'plugin3' }, ] as CoreConfig['plugins'], - { onlyPlugins: ['plugin1', 'plugin3']}, + { onlyPlugins: ['plugin1', 'plugin3'] }, ), ).toEqual([{ slug: 'plugin1' }, { slug: 'plugin3' }]); }); @@ -74,7 +74,8 @@ describe('filterCategoryByOnlyPluginsOption', () => { { title: 'category2', refs: [{ slug: 'plugin3' }] }, ] as CoreConfig['categories'], { - onlyPlugins: ['plugin1', 'plugin3'], verbose: true + onlyPlugins: ['plugin1', 'plugin3'], + verbose: true, }, ); expect(console.info).toHaveBeenCalledWith( @@ -91,7 +92,8 @@ describe('validateOnlyPluginsOption', () => { validateOnlyPluginsOption( [{ slug: 'plugin1' }, { slug: 'plugin2' }] as CoreConfig['plugins'], { - onlyPlugins: ['plugin1', 'plugin3', 'plugin4'], verbose: true + onlyPlugins: ['plugin1', 'plugin3', 'plugin4'], + verbose: true, }, ); expect(console.warn).toHaveBeenCalledWith( @@ -105,7 +107,8 @@ describe('validateOnlyPluginsOption', () => { validateOnlyPluginsOption( [{ slug: 'plugin1' }, { slug: 'plugin2' }] as CoreConfig['plugins'], { - onlyPlugins: ['plugin1'], verbose: true + onlyPlugins: ['plugin1'], + verbose: true, }, ); expect(console.info).not.toHaveBeenCalled(); diff --git a/packages/cli/src/lib/implementation/utils.ts b/packages/cli/src/lib/implementation/utils.ts index f8c3e13a6..fe966e829 100644 --- a/packages/cli/src/lib/implementation/utils.ts +++ b/packages/cli/src/lib/implementation/utils.ts @@ -1,6 +1,6 @@ // log error and flush stdout so that Yargs doesn't suppress it // related issue: https://github.com/yargs/yargs/issues/2118 -import {toArray} from "@code-pushup/utils"; +import { toArray } from '@code-pushup/utils'; export function logErrorBeforeThrow< // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -19,5 +19,7 @@ export function logErrorBeforeThrow< } export function coerceArray(param: T | T[] = []): T[] { - return [...new Set(toArray(param).flatMap((f: T) => f.split(',') as T[]) || [])] + return [ + ...new Set(toArray(param).flatMap((f: T) => f.split(',') as T[]) || []), + ]; } diff --git a/packages/cli/src/lib/print-config/print-config-command.ts b/packages/cli/src/lib/print-config/print-config-command.ts index d0df98a63..6f646ddf3 100644 --- a/packages/cli/src/lib/print-config/print-config-command.ts +++ b/packages/cli/src/lib/print-config/print-config-command.ts @@ -1,6 +1,6 @@ -import {CommandModule} from 'yargs'; -import {filterKebabCaseKeys} from '../implementation/filter-kebab-case-keys'; -import {onlyPluginsOption} from '../implementation/only-plugins-options'; +import { CommandModule } from 'yargs'; +import { filterKebabCaseKeys } from '../implementation/filter-kebab-case-keys'; +import { onlyPluginsOption } from '../implementation/only-plugins-options'; export function yargsConfigCommandObject() { const command = 'print-config'; @@ -8,7 +8,7 @@ export function yargsConfigCommandObject() { command, describe: 'Print config', builder: { - onlyPlugins: onlyPluginsOption + onlyPlugins: onlyPluginsOption, }, handler: yargsArgs => { // eslint-disable-next-line @typescript-eslint/no-unused-vars From cb68f56565fe5202f6fe74af0d08bc4b2396290f Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 Dec 2023 22:59:11 +0100 Subject: [PATCH 04/17] refactor(cli): fix windows test --- e2e/cli-e2e/tests/print-config.e2e.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 0c1320dc6..308b975ae 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -30,7 +30,7 @@ describe('print-config', () => { persist: { filename: 'report', format: [], - outputDir: `tmp/${ext}`, + outputDir: expect.stringContaining(ext), }, plugins: expect.arrayContaining([ expect.objectContaining({ slug: 'eslint', title: 'ESLint' }), From ad940391b085e1f26059ff55e6fe98b9bd2432cf Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 18 Dec 2023 18:52:32 +0100 Subject: [PATCH 05/17] merge main --- e2e/cli-e2e/tests/__snapshots__/help.e2e.test.ts.snap | 2 +- e2e/cli-e2e/tests/print-config.e2e.test.ts | 2 +- packages/cli/src/lib/implementation/core-config-options.ts | 1 - packages/models/src/lib/implementation/constants.ts | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/e2e/cli-e2e/tests/__snapshots__/help.e2e.test.ts.snap b/e2e/cli-e2e/tests/__snapshots__/help.e2e.test.ts.snap index 068b158d5..d3ecea32c 100644 --- a/e2e/cli-e2e/tests/__snapshots__/help.e2e.test.ts.snap +++ b/e2e/cli-e2e/tests/__snapshots__/help.e2e.test.ts.snap @@ -21,7 +21,7 @@ Options: --persist.outputDir Directory for the produced reports [string] --persist.filename Filename for the produced reports. [string] --persist.format Format of the report output. e.g. \`md\`, \`json\` - [array] [default: []] + [array] --upload.organization Organization slug from portal [string] --upload.project Project slug from portal [string] --upload.server URL to your portal server [string] diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 7d1b19588..786d84083 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -84,7 +84,7 @@ describe('print-config', () => { [ {}, { - format: [], + format: PERSIST_FORMAT, filename: 'report', }, ], diff --git a/packages/cli/src/lib/implementation/core-config-options.ts b/packages/cli/src/lib/implementation/core-config-options.ts index d8aeb4225..34fb6000b 100644 --- a/packages/cli/src/lib/implementation/core-config-options.ts +++ b/packages/cli/src/lib/implementation/core-config-options.ts @@ -34,7 +34,6 @@ export function yargsPersistConfigOptionsDefinition(): Record< 'persist.format': { describe: 'Format of the report output. e.g. `md`, `json`', type: 'array', - default: [], }, }; } diff --git a/packages/models/src/lib/implementation/constants.ts b/packages/models/src/lib/implementation/constants.ts index bc30840c9..20173535b 100644 --- a/packages/models/src/lib/implementation/constants.ts +++ b/packages/models/src/lib/implementation/constants.ts @@ -1,5 +1,5 @@ import { Format } from '../persist-config'; export const PERSIST_OUTPUT_DIR = '.code-pushup'; -export const PERSIST_FORMAT = ['json'] satisfies Format[]; +export const PERSIST_FORMAT: Format[] = ['json']; export const PERSIST_FILENAME = 'report'; From cb3213b033d89b7558283240c9d57693c54bf2fc Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 19 Dec 2023 01:03:11 +0100 Subject: [PATCH 06/17] refactor(cli): revert changes --- packages/cli/src/lib/collect/collect-command.ts | 6 ------ packages/cli/src/lib/collect/collect-command.unit.test.ts | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/cli/src/lib/collect/collect-command.ts b/packages/cli/src/lib/collect/collect-command.ts index 0102e50d8..e4cf839b1 100644 --- a/packages/cli/src/lib/collect/collect-command.ts +++ b/packages/cli/src/lib/collect/collect-command.ts @@ -14,12 +14,6 @@ export function yargsCollectCommandObject(): CommandModule { describe: 'Run Plugins and collect results', builder: { onlyPlugins: onlyPluginsOption, - 'persist.format': { - describe: 'Format of the report output. e.g. `md`, `json`', - type: 'array', - default: [], - coerce: (arg: string[]) => arg.flatMap(v => v.split(',')), - }, }, handler: async (args: ArgumentsCamelCase) => { const options = args as unknown as CollectAndPersistReportsOptions; diff --git a/packages/cli/src/lib/collect/collect-command.unit.test.ts b/packages/cli/src/lib/collect/collect-command.unit.test.ts index fcada62e1..ba0017dad 100644 --- a/packages/cli/src/lib/collect/collect-command.unit.test.ts +++ b/packages/cli/src/lib/collect/collect-command.unit.test.ts @@ -43,7 +43,7 @@ describe('collect-command', () => { persist: expect.objectContaining({ filename: 'report', outputDir: '.code-pushup', - format: [], + format: ['json'], }), }), ); From c43c5d4f3a60b05332315ef40a777f4cd90da2bf Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:05:07 +0100 Subject: [PATCH 07/17] Update packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts --- .../cli/src/lib/implementation/only-plugins-utils.unit.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts b/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts index bbc762d4f..804f57df3 100644 --- a/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts +++ b/packages/cli/src/lib/implementation/only-plugins-utils.unit.test.ts @@ -111,6 +111,6 @@ describe('validateOnlyPluginsOption', () => { verbose: true, }, ); - expect(console.info).not.toHaveBeenCalled(); + expect(console.warn).not.toHaveBeenCalled(); }); }); From 0757f0ddc8514b9249813408841b7581102085b6 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Tue, 19 Dec 2023 15:58:00 +0100 Subject: [PATCH 08/17] Update packages/cli/src/lib/implementation/utils.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- packages/cli/src/lib/implementation/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lib/implementation/utils.ts b/packages/cli/src/lib/implementation/utils.ts index fe966e829..5148ca4e7 100644 --- a/packages/cli/src/lib/implementation/utils.ts +++ b/packages/cli/src/lib/implementation/utils.ts @@ -1,7 +1,7 @@ -// log error and flush stdout so that Yargs doesn't suppress it -// related issue: https://github.com/yargs/yargs/issues/2118 import { toArray } from '@code-pushup/utils'; +// log error and flush stdout so that Yargs doesn't suppress it +// related issue: https://github.com/yargs/yargs/issues/2118 export function logErrorBeforeThrow< // eslint-disable-next-line @typescript-eslint/no-explicit-any T extends (...args: any[]) => any, From 38f8a9973b938ab6bdb892ada0a90800e7852742 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 19 Dec 2023 16:57:02 +0100 Subject: [PATCH 09/17] test(cli): move tests --- e2e/cli-e2e/tests/print-config.e2e.test.ts | 63 ------------------- .../core-config-options.integration.test.ts | 48 +++++++++++--- .../only-plugin-options.integration.test.ts | 35 +++++++++++ .../implementation/only-plugins-options.ts | 10 +++ 4 files changed, 84 insertions(+), 72 deletions(-) create mode 100644 packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 786d84083..3e58c3062 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -54,69 +54,6 @@ describe('print-config', () => { 120000, ); - it.each([ - // defaults - [{}, []], - [{ onlyPlugins: 'lighthouse' }, ['lighthouse']], - [{ onlyPlugins: ['lighthouse', 'eslint'] }, ['lighthouse', 'eslint']], - [{ onlyPlugins: 'lighthouse,eslint' }, ['lighthouse', 'eslint']], - ])( - 'should parse onlyPlugins options correctly', - async (options, result) => { - const { code, stderr, stdout } = await executeProcess({ - command: 'code-pushup', - args: [ - 'print-config', - '--no-verbose', - '--no-progress', - `--config=${configFile('ts')}`, - ...objectToCliArgs(options), - ], - }); - - expect(JSON.parse(stdout)?.onlyPlugins).toEqual(result); - }, - 120000, - ); - - it.each([ - // defaults - [ - {}, - { - format: PERSIST_FORMAT, - filename: 'report', - }, - ], - // persist.outputDir - [{ 'persist.outputDir': 'my-dir' }, { outputDir: 'my-dir' }], - // persist.filename - [{ 'persist.filename': 'my-report' }, { filename: 'my-report' }], - // persist.format - [{ 'persist.format': 'md' }, { format: ['md'] }], - [{ 'persist.format': ['md', 'json'] }, { format: ['md', 'json'] }], - [{ 'persist.format': 'md,json' }, { format: ['md', 'json'] }], - ])( - 'should parse persist options correctly', - async (options, result) => { - const { code, stderr, stdout } = await executeProcess({ - command: 'code-pushup', - args: [ - 'print-config', - '--verbose', - '--no-progress', - `--config=${configFile('ts')}`, - ...objectToCliArgs(options), - ], - }); - - expect(JSON.parse(stdout)?.persist).toEqual( - expect.objectContaining(result), - ); - }, - 120000, - ); - it('should load .ts config file with overloads arguments', async () => { const { code, stderr, stdout } = await executeProcess({ command: 'code-pushup', diff --git a/packages/cli/src/lib/implementation/core-config-options.integration.test.ts b/packages/cli/src/lib/implementation/core-config-options.integration.test.ts index 3c7a4b875..daefe52c4 100644 --- a/packages/cli/src/lib/implementation/core-config-options.integration.test.ts +++ b/packages/cli/src/lib/implementation/core-config-options.integration.test.ts @@ -1,20 +1,50 @@ -import { describe, expect } from 'vitest'; -import { CoreConfig } from '@code-pushup/models'; -import { objectToCliArgs } from '@code-pushup/utils'; -import { yargsCli } from '../yargs-cli'; -import { yargsCoreConfigOptionsDefinition } from './core-config-options'; +import {describe, expect} from 'vitest'; +import {join} from "node:path"; +import {CoreConfig} from '@code-pushup/models'; +import {objectToCliArgs} from '@code-pushup/utils'; +import {yargsCli} from '../yargs-cli'; +import {yargsCoreConfigOptionsDefinition} from './core-config-options'; describe('configOptions', () => { - function cli(args: Record): Promise { - return yargsCli(objectToCliArgs(args), { + function argsFromCli(args: Record): Promise { + return yargsCli(objectToCliArgs({ + ...args, + config: join('code-pushup.config.ts') + }), { options: yargsCoreConfigOptionsDefinition(), }).parseAsync() as unknown as Promise; } it('should fill defaults', async () => { - const config = await cli({}); + const config = await argsFromCli({config: 'code-pushup.config.ts'}); expect(config).toBeDefined(); // only _ and $0 - expect(Object.keys(config)).toHaveLength(2); + expect(Object.keys(config)).toHaveLength(3); }); + + it.each([ + // defaults + [ + {}, + {}, + ], + // persist.outputDir + [{'persist.outputDir': 'my-dir'}, {outputDir: 'my-dir'}], + // persist.filename + [{'persist.filename': 'my-report'}, {filename: 'my-report'}], + // persist.format + [{'persist.format': 'md'}, {format: ['md']}], + [{'persist.format': ['md', 'json']}, {format: ['md', 'json']}], + // [{ 'persist.format': 'md,json' }, { format: ['md', 'json'] }], @TODO comment in when config auto-loading is implemented + ])( + 'should parse persist options %s correctly as %j', + async (options, result) => { + const args = await argsFromCli(options); + + expect(args?.persist).toEqual( + expect.objectContaining(result), + ); + }, + ); + }); diff --git a/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts b/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts new file mode 100644 index 000000000..2623af78c --- /dev/null +++ b/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts @@ -0,0 +1,35 @@ +import {describe, expect} from 'vitest'; +import {objectToCliArgs} from '@code-pushup/utils'; +import {yargsCli} from '../yargs-cli'; +import {yargsOnlyPluginsOptionsDefinition} from './only-plugins-options'; + + +describe('onlyPlugin option', () => { + type OnlyPluginsOptions = { onlyPlugins?: string | string[] } + function argsFromCli(args: Record) { + return yargsCli(objectToCliArgs(args), { + options: yargsOnlyPluginsOptionsDefinition(), + }).parseAsync() as unknown as Promise; + } + + it('should fill defaults', async () => { + const args = await argsFromCli({}); + expect(args).toBeDefined(); + // "_" and "$0" are in by default + expect(Object.keys(args)).toHaveLength(4); + }); + it.each([ + // defaults + [{}, []], + [{ onlyPlugins: 'lighthouse' }, ['lighthouse']], + [{ onlyPlugins: ['lighthouse', 'eslint'] }, ['lighthouse', 'eslint']], + [{ onlyPlugins: 'lighthouse,eslint' }, ['lighthouse', 'eslint']], + ])( + 'should parse onlyPlugins options %s correctly as %j correctly', + async (options, result) => { + const parsedArgs = await argsFromCli(options); + expect(parsedArgs?.onlyPlugins).toEqual(result); + } + ); + +}); diff --git a/packages/cli/src/lib/implementation/only-plugins-options.ts b/packages/cli/src/lib/implementation/only-plugins-options.ts index ff1789d14..125b6f912 100644 --- a/packages/cli/src/lib/implementation/only-plugins-options.ts +++ b/packages/cli/src/lib/implementation/only-plugins-options.ts @@ -6,3 +6,13 @@ export const onlyPluginsOption: Options = { default: [], coerce: (arg: string[]) => arg.flatMap(v => v.split(',')), }; + + +export function yargsOnlyPluginsOptionsDefinition(): Record< + 'onlyPlugins', + Options +> { + return { + onlyPlugins: onlyPluginsOption + } +} From 590a5e6c60487f0c73195b79daf85a8602a256f0 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 19 Dec 2023 16:57:34 +0100 Subject: [PATCH 10/17] refactor(cli): format --- .../core-config-options.integration.test.ts | 47 +++++++++---------- .../only-plugin-options.integration.test.ts | 18 +++---- .../implementation/only-plugins-options.ts | 5 +- 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/packages/cli/src/lib/implementation/core-config-options.integration.test.ts b/packages/cli/src/lib/implementation/core-config-options.integration.test.ts index daefe52c4..92d0ec41c 100644 --- a/packages/cli/src/lib/implementation/core-config-options.integration.test.ts +++ b/packages/cli/src/lib/implementation/core-config-options.integration.test.ts @@ -1,22 +1,25 @@ -import {describe, expect} from 'vitest'; -import {join} from "node:path"; -import {CoreConfig} from '@code-pushup/models'; -import {objectToCliArgs} from '@code-pushup/utils'; -import {yargsCli} from '../yargs-cli'; -import {yargsCoreConfigOptionsDefinition} from './core-config-options'; +import { join } from 'node:path'; +import { describe, expect } from 'vitest'; +import { CoreConfig } from '@code-pushup/models'; +import { objectToCliArgs } from '@code-pushup/utils'; +import { yargsCli } from '../yargs-cli'; +import { yargsCoreConfigOptionsDefinition } from './core-config-options'; describe('configOptions', () => { function argsFromCli(args: Record): Promise { - return yargsCli(objectToCliArgs({ - ...args, - config: join('code-pushup.config.ts') - }), { - options: yargsCoreConfigOptionsDefinition(), - }).parseAsync() as unknown as Promise; + return yargsCli( + objectToCliArgs({ + ...args, + config: join('code-pushup.config.ts'), + }), + { + options: yargsCoreConfigOptionsDefinition(), + }, + ).parseAsync() as unknown as Promise; } it('should fill defaults', async () => { - const config = await argsFromCli({config: 'code-pushup.config.ts'}); + const config = await argsFromCli({ config: 'code-pushup.config.ts' }); expect(config).toBeDefined(); // only _ and $0 expect(Object.keys(config)).toHaveLength(3); @@ -24,27 +27,21 @@ describe('configOptions', () => { it.each([ // defaults - [ - {}, - {}, - ], + [{}, {}], // persist.outputDir - [{'persist.outputDir': 'my-dir'}, {outputDir: 'my-dir'}], + [{ 'persist.outputDir': 'my-dir' }, { outputDir: 'my-dir' }], // persist.filename - [{'persist.filename': 'my-report'}, {filename: 'my-report'}], + [{ 'persist.filename': 'my-report' }, { filename: 'my-report' }], // persist.format - [{'persist.format': 'md'}, {format: ['md']}], - [{'persist.format': ['md', 'json']}, {format: ['md', 'json']}], + [{ 'persist.format': 'md' }, { format: ['md'] }], + [{ 'persist.format': ['md', 'json'] }, { format: ['md', 'json'] }], // [{ 'persist.format': 'md,json' }, { format: ['md', 'json'] }], @TODO comment in when config auto-loading is implemented ])( 'should parse persist options %s correctly as %j', async (options, result) => { const args = await argsFromCli(options); - expect(args?.persist).toEqual( - expect.objectContaining(result), - ); + expect(args?.persist).toEqual(expect.objectContaining(result)); }, ); - }); diff --git a/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts b/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts index 2623af78c..9a574cbba 100644 --- a/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts +++ b/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts @@ -1,12 +1,13 @@ -import {describe, expect} from 'vitest'; -import {objectToCliArgs} from '@code-pushup/utils'; -import {yargsCli} from '../yargs-cli'; -import {yargsOnlyPluginsOptionsDefinition} from './only-plugins-options'; - +import { describe, expect } from 'vitest'; +import { objectToCliArgs } from '@code-pushup/utils'; +import { yargsCli } from '../yargs-cli'; +import { yargsOnlyPluginsOptionsDefinition } from './only-plugins-options'; describe('onlyPlugin option', () => { - type OnlyPluginsOptions = { onlyPlugins?: string | string[] } - function argsFromCli(args: Record) { + type OnlyPluginsOptions = { onlyPlugins?: string | string[] }; + function argsFromCli( + args: Record, + ) { return yargsCli(objectToCliArgs(args), { options: yargsOnlyPluginsOptionsDefinition(), }).parseAsync() as unknown as Promise; @@ -29,7 +30,6 @@ describe('onlyPlugin option', () => { async (options, result) => { const parsedArgs = await argsFromCli(options); expect(parsedArgs?.onlyPlugins).toEqual(result); - } + }, ); - }); diff --git a/packages/cli/src/lib/implementation/only-plugins-options.ts b/packages/cli/src/lib/implementation/only-plugins-options.ts index 125b6f912..ec3152801 100644 --- a/packages/cli/src/lib/implementation/only-plugins-options.ts +++ b/packages/cli/src/lib/implementation/only-plugins-options.ts @@ -7,12 +7,11 @@ export const onlyPluginsOption: Options = { coerce: (arg: string[]) => arg.flatMap(v => v.split(',')), }; - export function yargsOnlyPluginsOptionsDefinition(): Record< 'onlyPlugins', Options > { return { - onlyPlugins: onlyPluginsOption - } + onlyPlugins: onlyPluginsOption, + }; } From 7048e63e7975ad10ca22b9808e37deeb51cd031b Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 19 Dec 2023 17:02:43 +0100 Subject: [PATCH 11/17] refactor(cli): adjust only plugin utils login --- .../lib/implementation/only-plugins-utils.ts | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/packages/cli/src/lib/implementation/only-plugins-utils.ts b/packages/cli/src/lib/implementation/only-plugins-utils.ts index 48e779c06..1d97a2f4f 100644 --- a/packages/cli/src/lib/implementation/only-plugins-utils.ts +++ b/packages/cli/src/lib/implementation/only-plugins-utils.ts @@ -28,15 +28,14 @@ export function filterCategoryByOnlyPluginsOption( category.refs.every(ref => { const isNotSkipped = onlyPlugins.includes(ref.slug); - if (!isNotSkipped) { - verbose && - console.info( - `${chalk.yellow('⚠')} Category "${ - category.title - }" is ignored because it references audits from skipped plugin "${ - ref.slug - }"`, - ); + if (!isNotSkipped && verbose) { + console.info( + `${chalk.yellow('⚠')} Category "${ + category.title + }" is ignored because it references audits from skipped plugin "${ + ref.slug + }"`, + ); } return isNotSkipped; @@ -55,16 +54,15 @@ export function validateOnlyPluginsOption( ? onlyPlugins.filter(plugin => !plugins.some(({ slug }) => slug === plugin)) : []; - if (missingPlugins.length > 0) { - verbose && - console.warn( - `${chalk.yellow( - '⚠', - )} The --onlyPlugin argument references plugins with "${missingPlugins.join( - '", "', - )}" slugs, but no such plugins are present in the configuration. Expected one of the following plugin slugs: "${plugins - .map(({ slug }) => slug) - .join('", "')}".`, - ); + if (missingPlugins.length > 0 && verbose) { + console.warn( + `${chalk.yellow( + '⚠', + )} The --onlyPlugin argument references plugins with "${missingPlugins.join( + '", "', + )}" slugs, but no such plugins are present in the configuration. Expected one of the following plugin slugs: "${plugins + .map(({ slug }) => slug) + .join('", "')}".`, + ); } } From fa11b7da54f32492eab008528b221b8d00c20072 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Tue, 19 Dec 2023 18:58:26 +0100 Subject: [PATCH 12/17] Update e2e/cli-e2e/tests/print-config.e2e.test.ts --- e2e/cli-e2e/tests/print-config.e2e.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 3e58c3062..be74e0af6 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -54,7 +54,7 @@ describe('print-config', () => { 120000, ); - it('should load .ts config file with overloads arguments', async () => { + it('should load .ts config file and overload it with arguments', async () => { const { code, stderr, stdout } = await executeProcess({ command: 'code-pushup', args: [ From 05a5266a03bb9ab39e53b466feaa6309106f169b Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:02:11 +0100 Subject: [PATCH 13/17] Update packages/cli/src/lib/implementation/core-config-options.integration.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- .../lib/implementation/core-config-options.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/lib/implementation/core-config-options.integration.test.ts b/packages/cli/src/lib/implementation/core-config-options.integration.test.ts index 92d0ec41c..712c86b80 100644 --- a/packages/cli/src/lib/implementation/core-config-options.integration.test.ts +++ b/packages/cli/src/lib/implementation/core-config-options.integration.test.ts @@ -37,7 +37,7 @@ describe('configOptions', () => { [{ 'persist.format': ['md', 'json'] }, { format: ['md', 'json'] }], // [{ 'persist.format': 'md,json' }, { format: ['md', 'json'] }], @TODO comment in when config auto-loading is implemented ])( - 'should parse persist options %s correctly as %j', + 'should parse persist options %j correctly as %j', async (options, result) => { const args = await argsFromCli(options); From 6e2c93ea846ffe1a5b345be53124d567ab2aa4dd Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:04:14 +0100 Subject: [PATCH 14/17] Update packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- .../lib/implementation/only-plugin-options.integration.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts b/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts index 9a574cbba..7445c18ec 100644 --- a/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts +++ b/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts @@ -19,6 +19,7 @@ describe('onlyPlugin option', () => { // "_" and "$0" are in by default expect(Object.keys(args)).toHaveLength(4); }); + it.each([ // defaults [{}, []], From 16a4d3ea8cb5a2371c593789b8141fb33dc14ca8 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:04:23 +0100 Subject: [PATCH 15/17] Update packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- .../lib/implementation/only-plugin-options.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts b/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts index 7445c18ec..fee3a3c2f 100644 --- a/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts +++ b/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts @@ -27,7 +27,7 @@ describe('onlyPlugin option', () => { [{ onlyPlugins: ['lighthouse', 'eslint'] }, ['lighthouse', 'eslint']], [{ onlyPlugins: 'lighthouse,eslint' }, ['lighthouse', 'eslint']], ])( - 'should parse onlyPlugins options %s correctly as %j correctly', + 'should parse onlyPlugins options %j correctly as %j correctly', async (options, result) => { const parsedArgs = await argsFromCli(options); expect(parsedArgs?.onlyPlugins).toEqual(result); From 6f2f9b6e9e16df47e9b9ca57e546b58b8728575d Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:05:36 +0100 Subject: [PATCH 16/17] Update packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts --- .../lib/implementation/only-plugin-options.integration.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts b/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts index fee3a3c2f..4eb3d14ce 100644 --- a/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts +++ b/packages/cli/src/lib/implementation/only-plugin-options.integration.test.ts @@ -17,6 +17,7 @@ describe('onlyPlugin option', () => { const args = await argsFromCli({}); expect(args).toBeDefined(); // "_" and "$0" are in by default + // camelCase and kebab-case of each option value expect(Object.keys(args)).toHaveLength(4); }); From 4f03a1224c3c48cba62c40026e78346081b9ac4c Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 19 Dec 2023 19:46:43 +0100 Subject: [PATCH 17/17] test: adjust timeout --- packages/plugin-eslint/src/lib/runner.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-eslint/src/lib/runner.integration.test.ts b/packages/plugin-eslint/src/lib/runner.integration.test.ts index 7d461c8bc..f79682521 100644 --- a/packages/plugin-eslint/src/lib/runner.integration.test.ts +++ b/packages/plugin-eslint/src/lib/runner.integration.test.ts @@ -93,5 +93,5 @@ describe('executeRunner', () => { }, } satisfies Partial), ); - }); + }, 7000); });