From 64f45dabe5b1fae51996d074428da761acd90dda Mon Sep 17 00:00:00 2001
From: Nacho Vazquez <nacho.vazquez.dev@gmail.com>
Date: Sat, 29 Jun 2024 16:20:03 -0300
Subject: [PATCH] feat: add skipPlugin options to global configs

---
 packages/cli/src/lib/cli.ts                          |  4 ++++
 .../core-config.middleware.integration.test.ts       |  1 +
 .../src/lib/implementation/core-config.middleware.ts | 10 ++++++++--
 .../core-config.middleware.unit.test.ts              | 12 ++++++++----
 .../only-plugins.middleware.unit.test.ts             |  4 ++--
 packages/cli/src/lib/middlewares.ts                  |  5 +++++
 packages/cli/src/lib/options.ts                      |  3 +++
 7 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/packages/cli/src/lib/cli.ts b/packages/cli/src/lib/cli.ts
index 4e6d55bac..68e633a3c 100644
--- a/packages/cli/src/lib/cli.ts
+++ b/packages/cli/src/lib/cli.ts
@@ -23,6 +23,10 @@ export const cli = (args: string[]) =>
         'code-pushup collect --onlyPlugins=coverage',
         'Run collect with only coverage plugin, other plugins from config file will be skipped.',
       ],
+      [
+        'code-pushup collect --skipPlugins=coverage',
+        'Run collect skiping the coverage plugin, other plugins from config file will be included.',
+      ],
       [
         'code-pushup upload --persist.outputDir=dist --persist.filename=cp-report --upload.apiKey=$CP_API_KEY',
         'Upload dist/cp-report.json to portal using API key from environment variable',
diff --git a/packages/cli/src/lib/implementation/core-config.middleware.integration.test.ts b/packages/cli/src/lib/implementation/core-config.middleware.integration.test.ts
index 661898c76..2d592fc3f 100644
--- a/packages/cli/src/lib/implementation/core-config.middleware.integration.test.ts
+++ b/packages/cli/src/lib/implementation/core-config.middleware.integration.test.ts
@@ -23,6 +23,7 @@ describe('coreConfigMiddleware', () => {
     progress: true,
     verbose: false,
     onlyPlugins: [],
+    skipPlugins: [],
   };
 
   it.each(['ts', 'mjs', 'js'])(
diff --git a/packages/cli/src/lib/implementation/core-config.middleware.ts b/packages/cli/src/lib/implementation/core-config.middleware.ts
index a138605e1..baeb6fc0d 100644
--- a/packages/cli/src/lib/implementation/core-config.middleware.ts
+++ b/packages/cli/src/lib/implementation/core-config.middleware.ts
@@ -9,12 +9,18 @@ import {
 import { CoreConfigCliOptions } from './core-config.model';
 import { GeneralCliOptions } from './global.model';
 import { OnlyPluginsOptions } from './only-plugins.model';
+import { SkipPluginsOptions } from './skip-plugins.model';
 
 export async function coreConfigMiddleware<
-  T extends GeneralCliOptions & CoreConfigCliOptions & OnlyPluginsOptions,
+  T extends GeneralCliOptions &
+    CoreConfigCliOptions &
+    OnlyPluginsOptions &
+    SkipPluginsOptions,
 >(
   processArgs: T,
-): Promise<GeneralCliOptions & CoreConfig & OnlyPluginsOptions> {
+): Promise<
+  GeneralCliOptions & CoreConfig & OnlyPluginsOptions & SkipPluginsOptions
+> {
   const {
     config,
     tsconfig,
diff --git a/packages/cli/src/lib/implementation/core-config.middleware.unit.test.ts b/packages/cli/src/lib/implementation/core-config.middleware.unit.test.ts
index 1e439868c..0c3346fde 100644
--- a/packages/cli/src/lib/implementation/core-config.middleware.unit.test.ts
+++ b/packages/cli/src/lib/implementation/core-config.middleware.unit.test.ts
@@ -4,6 +4,7 @@ import { coreConfigMiddleware } from './core-config.middleware';
 import { CoreConfigCliOptions } from './core-config.model';
 import { GeneralCliOptions } from './global.model';
 import { OnlyPluginsOptions } from './only-plugins.model';
+import { SkipPluginsOptions } from './skip-plugins.model';
 
 vi.mock('@code-pushup/core', async () => {
   const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-utils') =
@@ -19,7 +20,10 @@ vi.mock('@code-pushup/core', async () => {
 describe('coreConfigMiddleware', () => {
   it('should attempt to load code-pushup.config.(ts|mjs|js) by default', async () => {
     await coreConfigMiddleware(
-      {} as GeneralCliOptions & CoreConfigCliOptions & OnlyPluginsOptions,
+      {} as GeneralCliOptions &
+        CoreConfigCliOptions &
+        OnlyPluginsOptions &
+        SkipPluginsOptions,
     );
     expect(autoloadRc).toHaveBeenCalled();
   });
@@ -27,7 +31,7 @@ describe('coreConfigMiddleware', () => {
   it('should directly attempt to load passed config', async () => {
     await coreConfigMiddleware({
       config: 'cli/custom-config.mjs',
-    } as GeneralCliOptions & CoreConfigCliOptions & OnlyPluginsOptions);
+    } as GeneralCliOptions & CoreConfigCliOptions & OnlyPluginsOptions & SkipPluginsOptions);
     expect(autoloadRc).not.toHaveBeenCalled();
     expect(readRcByPath).toHaveBeenCalledWith(
       'cli/custom-config.mjs',
@@ -38,7 +42,7 @@ describe('coreConfigMiddleware', () => {
   it('should forward --tsconfig option to config autoload', async () => {
     await coreConfigMiddleware({
       tsconfig: 'tsconfig.base.json',
-    } as GeneralCliOptions & CoreConfigCliOptions & OnlyPluginsOptions);
+    } as GeneralCliOptions & CoreConfigCliOptions & OnlyPluginsOptions & SkipPluginsOptions);
     expect(autoloadRc).toHaveBeenCalledWith('tsconfig.base.json');
   });
 
@@ -46,7 +50,7 @@ describe('coreConfigMiddleware', () => {
     await coreConfigMiddleware({
       config: 'apps/website/code-pushup.config.ts',
       tsconfig: 'apps/website/tsconfig.json',
-    } as GeneralCliOptions & CoreConfigCliOptions & OnlyPluginsOptions);
+    } as GeneralCliOptions & CoreConfigCliOptions & OnlyPluginsOptions & SkipPluginsOptions);
     expect(readRcByPath).toHaveBeenCalledWith(
       'apps/website/code-pushup.config.ts',
       'apps/website/tsconfig.json',
diff --git a/packages/cli/src/lib/implementation/only-plugins.middleware.unit.test.ts b/packages/cli/src/lib/implementation/only-plugins.middleware.unit.test.ts
index ee2ea66d5..2ab351bc5 100644
--- a/packages/cli/src/lib/implementation/only-plugins.middleware.unit.test.ts
+++ b/packages/cli/src/lib/implementation/only-plugins.middleware.unit.test.ts
@@ -48,7 +48,7 @@ describe('onlyPluginsMiddleware', () => {
     expect(plugins).toStrictEqual([expect.objectContaining({ slug: 'p1' })]);
   });
 
-  it('should filter categories for slug "p1"', () => {
+  it('should forward plugins and categories for a slug not present in plugins', () => {
     const originalCategories = [
       {
         slug: 'c1',
@@ -69,7 +69,7 @@ describe('onlyPluginsMiddleware', () => {
     expect(plugins).toBe(originalPlugins);
   });
 
-  it('should forward plugins and categories for a slug not present in plugins', () => {
+  it('should filter categories for slug "p1"', () => {
     const { categories } = onlyPluginsMiddleware({
       onlyPlugins: ['p1'],
       plugins: [{ slug: 'p1' }, { slug: 'p2' }] as PluginConfig[],
diff --git a/packages/cli/src/lib/middlewares.ts b/packages/cli/src/lib/middlewares.ts
index 35e385501..53b21a8b5 100644
--- a/packages/cli/src/lib/middlewares.ts
+++ b/packages/cli/src/lib/middlewares.ts
@@ -1,6 +1,7 @@
 import { MiddlewareFunction } from 'yargs';
 import { coreConfigMiddleware } from './implementation/core-config.middleware';
 import { onlyPluginsMiddleware } from './implementation/only-plugins.middleware';
+import { skipPluginsMiddleware } from './implementation/skip-plugins.middleware';
 
 export const middlewares = [
   {
@@ -11,4 +12,8 @@ export const middlewares = [
     middlewareFunction: onlyPluginsMiddleware as unknown as MiddlewareFunction,
     applyBeforeValidation: false,
   },
+  {
+    middlewareFunction: skipPluginsMiddleware as unknown as MiddlewareFunction,
+    applyBeforeValidation: false,
+  },
 ];
diff --git a/packages/cli/src/lib/options.ts b/packages/cli/src/lib/options.ts
index 2a11f5275..edf86f020 100644
--- a/packages/cli/src/lib/options.ts
+++ b/packages/cli/src/lib/options.ts
@@ -5,17 +5,20 @@ import {
 } from './implementation/core-config.options';
 import { yargsGlobalOptionsDefinition } from './implementation/global.options';
 import { yargsOnlyPluginsOptionsDefinition } from './implementation/only-plugins.options';
+import { yargsSkipPluginsOptionsDefinition } from './implementation/skip-plugins.options';
 
 export const options = {
   ...yargsGlobalOptionsDefinition(),
   ...yargsCoreConfigOptionsDefinition(),
   ...yargsOnlyPluginsOptionsDefinition(),
+  ...yargsSkipPluginsOptionsDefinition(),
 };
 
 export const groups = {
   'Global Options:': [
     ...Object.keys(yargsGlobalOptionsDefinition()),
     ...Object.keys(yargsOnlyPluginsOptionsDefinition()),
+    ...Object.keys(yargsSkipPluginsOptionsDefinition()),
   ],
   'Persist Options:': Object.keys(yargsPersistConfigOptionsDefinition()),
   'Upload Options:': Object.keys(yargsUploadConfigOptionsDefinition()),