From f653376e2ae1ca4d3905cc14df9c013ce220b417 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 14 Feb 2025 14:03:03 +0100 Subject: [PATCH 01/30] fix(nx-plugin): adjust upload config handling --- .../src/executors/cli/executor.unit.test.ts | 18 ++++++++++++++++-- packages/nx-plugin/src/executors/cli/utils.ts | 9 ++++++--- .../src/executors/cli/utils.unit.test.ts | 5 ++--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/nx-plugin/src/executors/cli/executor.unit.test.ts b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts index 416ff91ab..0ea036141 100644 --- a/packages/nx-plugin/src/executors/cli/executor.unit.test.ts +++ b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts @@ -69,8 +69,8 @@ describe('runAutorunExecutor', () => { expect(output.command).toMatch('--persist.filename="REPORT"'); }); - it('should create command from context, options and arguments', async () => { - envSpy.mockReturnValue({ CP_PROJECT: 'CLI' }); + it('should create command from context, options and arguments if APIkey is set', async () => { + envSpy.mockReturnValue({ CP_PROJECT: 'CLI', CP_API_KEY: '123456789' }); const output = await runAutorunExecutor( { persist: { filename: 'REPORT', format: ['md', 'json'] } }, executorContext('core'), @@ -80,6 +80,20 @@ describe('runAutorunExecutor', () => { '--persist.format="md" --persist.format="json"', ); expect(output.command).toMatch('--upload.project="CLI"'); + expect(output.command).toMatch('--upload.apiKey="123456789"'); + }); + + it('should create command from context, options and arguments without upload if APIkey is not set', async () => { + envSpy.mockReturnValue({ CP_PROJECT: 'CLI' }); + const output = await runAutorunExecutor( + { persist: { filename: 'REPORT', format: ['md', 'json'] } }, + executorContext('core'), + ); + expect(output.command).toMatch('--persist.filename="REPORT"'); + expect(output.command).toMatch( + '--persist.format="md" --persist.format="json"', + ); + expect(output.command).not.toMatch('--upload.project="CLI"'); }); it('should log information if verbose is set', async () => { diff --git a/packages/nx-plugin/src/executors/cli/utils.ts b/packages/nx-plugin/src/executors/cli/utils.ts index 61fccf0e9..afcca4542 100644 --- a/packages/nx-plugin/src/executors/cli/utils.ts +++ b/packages/nx-plugin/src/executors/cli/utils.ts @@ -27,6 +27,11 @@ export function parseAutorunExecutorOptions( const { projectPrefix, persist, upload, command } = options; const needsUploadParams = command === 'upload' || command === 'autorun' || command === undefined; + const uploadCfg = uploadConfig( + { projectPrefix, ...upload }, + normalizedContext, + ); + const hasApiToken = uploadCfg?.apiKey != null; return { ...parseAutorunExecutorOnlyOptions(options), ...globalConfig(options, normalizedContext), @@ -34,9 +39,7 @@ export function parseAutorunExecutorOptions( // @TODO This is a hack to avoid validation errors of upload config for commands that dont need it. // Fix: use utils and execute the core logic directly // Blocked by Nx plugins can't compile to es6 - upload: needsUploadParams - ? uploadConfig({ projectPrefix, ...upload }, normalizedContext) - : undefined, + ...(needsUploadParams && hasApiToken ? { upload: uploadCfg } : {}), }; } diff --git a/packages/nx-plugin/src/executors/cli/utils.unit.test.ts b/packages/nx-plugin/src/executors/cli/utils.unit.test.ts index 5626375bd..623d0512e 100644 --- a/packages/nx-plugin/src/executors/cli/utils.unit.test.ts +++ b/packages/nx-plugin/src/executors/cli/utils.unit.test.ts @@ -80,7 +80,6 @@ describe('parseAutorunExecutorOptions', () => { expect.objectContaining({ progress: false, verbose: false, - upload: { project: projectName }, }), ); @@ -98,14 +97,14 @@ describe('parseAutorunExecutorOptions', () => { }); it.each(['upload', 'autorun', undefined])( - 'should include upload config for command %s', + 'should include upload config for command %s if API key is provided', command => { const projectName = 'my-app'; const executorOptions = parseAutorunExecutorOptions( { command, upload: { - organization: 'code-pushup', + apiKey: '123456789', }, }, { From ccce7b1383126bb95bff7dcb06c193bcb701530e Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 22 Feb 2025 13:36:37 +0100 Subject: [PATCH 02/30] fix(nx-plugin): remove file extensions in imports --- nx.json | 3 +++ .../nx-plugin/src/executors/cli/executor.ts | 8 +++---- .../src/executors/cli/executor.unit.test.ts | 2 +- .../nx-plugin/src/executors/cli/schema.ts | 2 +- .../executors/cli/utils.integration.test.ts | 6 ++--- packages/nx-plugin/src/executors/cli/utils.ts | 10 +++----- .../src/executors/cli/utils.unit.test.ts | 4 ++-- .../src/executors/internal/cli.unit.test.ts | 2 +- .../internal/config.integration.test.ts | 2 +- .../src/executors/internal/config.ts | 4 ++-- .../src/executors/internal/context.ts | 2 +- .../executors/internal/context.unit.test.ts | 2 +- .../src/executors/internal/env.unit.test.ts | 2 +- .../code-pushup-config.integration.test.ts | 2 +- .../configuration/code-pushup-config.ts | 4 ++-- .../generator.integration.test.ts | 4 ++-- .../src/generators/configuration/generator.ts | 6 ++--- .../src/generators/configuration/schema.d.ts | 2 +- .../src/generators/configuration/utils.ts | 2 +- .../init/generator.integration.test.ts | 2 +- .../src/generators/init/generator.ts | 6 ++--- packages/nx-plugin/src/index.ts | 23 ++++++++----------- packages/nx-plugin/src/internal/constants.ts | 5 ++-- .../nx-plugin/src/internal/execute-process.ts | 2 +- .../src/internal/execute-process.unit.test.ts | 2 +- packages/nx-plugin/src/plugin/index.ts | 4 ++-- .../nx-plugin/src/plugin/plugin.unit.test.ts | 6 ++--- .../src/plugin/target/configuration-target.ts | 6 ++--- .../target/configuration.target.unit.test.ts | 4 ++-- .../src/plugin/target/executor-target.ts | 4 ++-- .../target/executor.target.unit.test.ts | 2 +- .../nx-plugin/src/plugin/target/targets.ts | 22 +++++++++++------- .../src/plugin/target/targets.unit.test.ts | 8 +++---- packages/nx-plugin/src/plugin/types.ts | 19 +++++++++------ .../nx-plugin/src/plugin/utils.unit.test.ts | 2 +- 35 files changed, 96 insertions(+), 90 deletions(-) diff --git a/nx.json b/nx.json index 84fbf0790..c217cad19 100644 --- a/nx.json +++ b/nx.json @@ -83,6 +83,9 @@ "releaseTagPattern": "v{version}" }, "plugins": [ + { + "plugin": "./dist/packages/nx-plugin" + }, { "plugin": "@push-based/nx-verdaccio", "options": { diff --git a/packages/nx-plugin/src/executors/cli/executor.ts b/packages/nx-plugin/src/executors/cli/executor.ts index 2ff27ed74..5db5e5e98 100644 --- a/packages/nx-plugin/src/executors/cli/executor.ts +++ b/packages/nx-plugin/src/executors/cli/executor.ts @@ -1,9 +1,9 @@ import { type ExecutorContext, logger } from '@nx/devkit'; import { execSync } from 'node:child_process'; -import { createCliCommand } from '../internal/cli.js'; -import { normalizeContext } from '../internal/context.js'; -import type { AutorunCommandExecutorOptions } from './schema.js'; -import { mergeExecutorOptions, parseAutorunExecutorOptions } from './utils.js'; +import { createCliCommand } from '../internal/cli'; +import { normalizeContext } from '../internal/context'; +import type { AutorunCommandExecutorOptions } from './schema'; +import { mergeExecutorOptions, parseAutorunExecutorOptions } from './utils'; export type ExecutorOutput = { success: boolean; diff --git a/packages/nx-plugin/src/executors/cli/executor.unit.test.ts b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts index 0ea036141..f1f6dab47 100644 --- a/packages/nx-plugin/src/executors/cli/executor.unit.test.ts +++ b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts @@ -3,7 +3,7 @@ import { execSync } from 'node:child_process'; import { afterEach, beforeEach, expect, vi } from 'vitest'; import { executorContext } from '@code-pushup/test-nx-utils'; import { MEMFS_VOLUME } from '@code-pushup/test-utils'; -import runAutorunExecutor from './executor.js'; +import runAutorunExecutor from './executor'; vi.mock('node:child_process', async () => { const actual = await vi.importActual('node:child_process'); diff --git a/packages/nx-plugin/src/executors/cli/schema.ts b/packages/nx-plugin/src/executors/cli/schema.ts index d73a394b6..d610483cb 100644 --- a/packages/nx-plugin/src/executors/cli/schema.ts +++ b/packages/nx-plugin/src/executors/cli/schema.ts @@ -4,7 +4,7 @@ import type { GeneralExecutorOnlyOptions, GlobalExecutorOptions, ProjectExecutorOnlyOptions, -} from '../internal/types.js'; +} from '../internal/types'; export type AutorunCommandExecutorOnlyOptions = ProjectExecutorOnlyOptions & CollectExecutorOnlyOptions & diff --git a/packages/nx-plugin/src/executors/cli/utils.integration.test.ts b/packages/nx-plugin/src/executors/cli/utils.integration.test.ts index 180f22af1..d15f9961d 100644 --- a/packages/nx-plugin/src/executors/cli/utils.integration.test.ts +++ b/packages/nx-plugin/src/executors/cli/utils.integration.test.ts @@ -1,8 +1,8 @@ import { expect, vi } from 'vitest'; import type { UploadConfig } from '@code-pushup/models'; -import { normalizedExecutorContext } from '../../../mock/utils/executor.js'; -import * as config from '../internal/config.js'; -import { parseAutorunExecutorOptions } from './utils.js'; +import { normalizedExecutorContext } from '../../../mock/utils/executor'; +import * as config from '../internal/config'; +import { parseAutorunExecutorOptions } from './utils'; describe('parseAutorunExecutorOptions', () => { const persistConfigSpy = vi.spyOn(config, 'persistConfig'); diff --git a/packages/nx-plugin/src/executors/cli/utils.ts b/packages/nx-plugin/src/executors/cli/utils.ts index afcca4542..cc121c958 100644 --- a/packages/nx-plugin/src/executors/cli/utils.ts +++ b/packages/nx-plugin/src/executors/cli/utils.ts @@ -1,13 +1,9 @@ -import { - globalConfig, - persistConfig, - uploadConfig, -} from '../internal/config.js'; -import type { NormalizedExecutorContext } from '../internal/context.js'; +import { globalConfig, persistConfig, uploadConfig } from '../internal/config'; +import type { NormalizedExecutorContext } from '../internal/context'; import type { AutorunCommandExecutorOnlyOptions, AutorunCommandExecutorOptions, -} from './schema.js'; +} from './schema'; export function parseAutorunExecutorOnlyOptions( options: Partial, diff --git a/packages/nx-plugin/src/executors/cli/utils.unit.test.ts b/packages/nx-plugin/src/executors/cli/utils.unit.test.ts index 623d0512e..4702b4dff 100644 --- a/packages/nx-plugin/src/executors/cli/utils.unit.test.ts +++ b/packages/nx-plugin/src/executors/cli/utils.unit.test.ts @@ -1,11 +1,11 @@ import { type MockInstance, expect, vi } from 'vitest'; import { osAgnosticPath } from '@code-pushup/test-utils'; -import type { Command } from '../internal/types.js'; +import type { Command } from '../internal/types'; import { mergeExecutorOptions, parseAutorunExecutorOnlyOptions, parseAutorunExecutorOptions, -} from './utils.js'; +} from './utils'; describe('parseAutorunExecutorOnlyOptions', () => { it('should provide NO default projectPrefix', () => { diff --git a/packages/nx-plugin/src/executors/internal/cli.unit.test.ts b/packages/nx-plugin/src/executors/internal/cli.unit.test.ts index e65cb0ec0..ab39b876b 100644 --- a/packages/nx-plugin/src/executors/internal/cli.unit.test.ts +++ b/packages/nx-plugin/src/executors/internal/cli.unit.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createCliCommand, objectToCliArgs } from './cli.js'; +import { createCliCommand, objectToCliArgs } from './cli'; describe('objectToCliArgs', () => { it('should empty params', () => { diff --git a/packages/nx-plugin/src/executors/internal/config.integration.test.ts b/packages/nx-plugin/src/executors/internal/config.integration.test.ts index 54b2e32dc..4e7d91517 100644 --- a/packages/nx-plugin/src/executors/internal/config.integration.test.ts +++ b/packages/nx-plugin/src/executors/internal/config.integration.test.ts @@ -1,5 +1,5 @@ import { describe, expect } from 'vitest'; -import { ENV } from '../../../mock/fixtures/env.js'; +import { ENV } from '../../../mock/fixtures/env'; import { uploadConfig } from './config.js'; import * as env from './env.js'; diff --git a/packages/nx-plugin/src/executors/internal/config.ts b/packages/nx-plugin/src/executors/internal/config.ts index 0eb13f8a8..e083c3824 100644 --- a/packages/nx-plugin/src/executors/internal/config.ts +++ b/packages/nx-plugin/src/executors/internal/config.ts @@ -1,11 +1,11 @@ import * as path from 'node:path'; import type { PersistConfig, UploadConfig } from '@code-pushup/models'; -import { parseEnv } from './env.js'; +import { parseEnv } from './env'; import type { BaseNormalizedExecutorContext, GlobalExecutorOptions, ProjectExecutorOnlyOptions, -} from './types.js'; +} from './types'; export function globalConfig( options: Partial>, diff --git a/packages/nx-plugin/src/executors/internal/context.ts b/packages/nx-plugin/src/executors/internal/context.ts index 38ca33416..33fd4ca14 100644 --- a/packages/nx-plugin/src/executors/internal/context.ts +++ b/packages/nx-plugin/src/executors/internal/context.ts @@ -1,5 +1,5 @@ import type { ExecutorContext } from 'nx/src/config/misc-interfaces'; -import type { BaseNormalizedExecutorContext } from './types.js'; +import type { BaseNormalizedExecutorContext } from './types'; export type NormalizedExecutorContext = BaseNormalizedExecutorContext & { projectName: string; diff --git a/packages/nx-plugin/src/executors/internal/context.unit.test.ts b/packages/nx-plugin/src/executors/internal/context.unit.test.ts index 9be17d2a9..fbd43a733 100644 --- a/packages/nx-plugin/src/executors/internal/context.unit.test.ts +++ b/packages/nx-plugin/src/executors/internal/context.unit.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { normalizeContext } from './context.js'; +import { normalizeContext } from './context'; describe('normalizeContext', () => { it('should normalizeContext', () => { diff --git a/packages/nx-plugin/src/executors/internal/env.unit.test.ts b/packages/nx-plugin/src/executors/internal/env.unit.test.ts index 548ef1e3b..eca10b8c5 100644 --- a/packages/nx-plugin/src/executors/internal/env.unit.test.ts +++ b/packages/nx-plugin/src/executors/internal/env.unit.test.ts @@ -1,5 +1,5 @@ import { describe, expect } from 'vitest'; -import { parseEnv } from './env.js'; +import { parseEnv } from './env'; describe('parseEnv', () => { it('should parse empty env vars', () => { diff --git a/packages/nx-plugin/src/generators/configuration/code-pushup-config.integration.test.ts b/packages/nx-plugin/src/generators/configuration/code-pushup-config.integration.test.ts index 38238ff50..b07bd4e18 100644 --- a/packages/nx-plugin/src/generators/configuration/code-pushup-config.integration.test.ts +++ b/packages/nx-plugin/src/generators/configuration/code-pushup-config.integration.test.ts @@ -3,7 +3,7 @@ import { formatFiles } from '@nx/devkit'; import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import * as path from 'node:path'; import { describe, expect, it } from 'vitest'; -import { generateCodePushupConfig } from './code-pushup-config.js'; +import { generateCodePushupConfig } from './code-pushup-config'; describe('generateCodePushupConfig options', () => { let tree: devKit.Tree; diff --git a/packages/nx-plugin/src/generators/configuration/code-pushup-config.ts b/packages/nx-plugin/src/generators/configuration/code-pushup-config.ts index 6854797fb..671196971 100644 --- a/packages/nx-plugin/src/generators/configuration/code-pushup-config.ts +++ b/packages/nx-plugin/src/generators/configuration/code-pushup-config.ts @@ -2,13 +2,13 @@ import { type Tree, generateFiles, logger } from '@nx/devkit'; import * as path from 'node:path'; import type { PersistConfig, UploadConfig } from '@code-pushup/models'; import type { ItemOrArray } from '@code-pushup/utils'; -import type { ExecutableCode } from './types.js'; +import type { ExecutableCode } from './types'; import { formatArrayToLinesOfJsString, formatObjectToFormattedJsString, normalizeExecutableCode, normalizeItemOrArray, -} from './utils.js'; +} from './utils'; export const DEFAULT_IMPORTS = [ "import type { CoreConfig } from '@code-pushup/models';", diff --git a/packages/nx-plugin/src/generators/configuration/generator.integration.test.ts b/packages/nx-plugin/src/generators/configuration/generator.integration.test.ts index c98d60064..dc3ce206e 100644 --- a/packages/nx-plugin/src/generators/configuration/generator.integration.test.ts +++ b/packages/nx-plugin/src/generators/configuration/generator.integration.test.ts @@ -7,8 +7,8 @@ import { import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import * as path from 'node:path'; import { afterEach, describe, expect, it, vi } from 'vitest'; -import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants.js'; -import { addTargetToProject, configurationGenerator } from './generator.js'; +import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants'; +import { addTargetToProject, configurationGenerator } from './generator'; describe('addTargetToProject', () => { let tree: Tree; diff --git a/packages/nx-plugin/src/generators/configuration/generator.ts b/packages/nx-plugin/src/generators/configuration/generator.ts index 4b71b60a2..dc0d49913 100644 --- a/packages/nx-plugin/src/generators/configuration/generator.ts +++ b/packages/nx-plugin/src/generators/configuration/generator.ts @@ -6,9 +6,9 @@ import { updateProjectConfiguration, } from '@nx/devkit'; import type { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json'; -import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants.js'; -import { generateCodePushupConfig } from './code-pushup-config.js'; -import type { ConfigurationGeneratorOptions } from './schema.js'; +import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants'; +import { generateCodePushupConfig } from './code-pushup-config'; +import type { ConfigurationGeneratorOptions } from './schema'; export async function configurationGenerator( tree: Tree, diff --git a/packages/nx-plugin/src/generators/configuration/schema.d.ts b/packages/nx-plugin/src/generators/configuration/schema.d.ts index b105270c6..d7b700308 100644 --- a/packages/nx-plugin/src/generators/configuration/schema.d.ts +++ b/packages/nx-plugin/src/generators/configuration/schema.d.ts @@ -1,4 +1,4 @@ -import type { DynamicTargetOptions } from '../../internal/types.js'; +import type { DynamicTargetOptions } from '../../internal/types'; export type ConfigurationGeneratorOptions = { project: string; diff --git a/packages/nx-plugin/src/generators/configuration/utils.ts b/packages/nx-plugin/src/generators/configuration/utils.ts index 36464358a..5063a7aef 100644 --- a/packages/nx-plugin/src/generators/configuration/utils.ts +++ b/packages/nx-plugin/src/generators/configuration/utils.ts @@ -1,5 +1,5 @@ import type { ExtractArrays } from '@code-pushup/utils'; -import type { ExecutableCode } from './types.js'; +import type { ExecutableCode } from './types'; export function normalizeExecutableCode( executableCode: ExecutableCode, diff --git a/packages/nx-plugin/src/generators/init/generator.integration.test.ts b/packages/nx-plugin/src/generators/init/generator.integration.test.ts index 5ab890bd1..05fe14511 100644 --- a/packages/nx-plugin/src/generators/init/generator.integration.test.ts +++ b/packages/nx-plugin/src/generators/init/generator.integration.test.ts @@ -1,7 +1,7 @@ import { type Tree, logger, readJson, readNxJson } from '@nx/devkit'; import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import { describe, expect, it, vi } from 'vitest'; -import { initGenerator } from './generator.js'; +import { initGenerator } from './generator'; type PackageJson = { devDependencies: Record; diff --git a/packages/nx-plugin/src/generators/init/generator.ts b/packages/nx-plugin/src/generators/init/generator.ts index 265298fb0..12f058751 100644 --- a/packages/nx-plugin/src/generators/init/generator.ts +++ b/packages/nx-plugin/src/generators/init/generator.ts @@ -12,14 +12,14 @@ import { updateNxJson, } from '@nx/devkit'; import type { PackageJson } from 'nx/src/utils/package-json'; -import { PACKAGE_NAME } from '../../internal/constants.js'; +import { PACKAGE_NAME } from '../../internal/constants'; import { cpCliVersion, cpModelVersion, cpNxPluginVersion, cpUtilsVersion, -} from '../../internal/versions.js'; -import type { InitGeneratorSchema } from './schema.js'; +} from '../../internal/versions'; +import type { InitGeneratorSchema } from './schema'; function checkDependenciesInstalled(host: Tree) { const packageJson = readJson(host, 'package.json'); diff --git a/packages/nx-plugin/src/index.ts b/packages/nx-plugin/src/index.ts index 20ebba48a..d8f698bbb 100644 --- a/packages/nx-plugin/src/index.ts +++ b/packages/nx-plugin/src/index.ts @@ -1,18 +1,15 @@ -import { createNodes } from './plugin/index.js'; +import { createNodes } from './plugin/index'; // default export for nx.json#plugins export default createNodes; -export * from './internal/versions.js'; -export { type InitGeneratorSchema } from './generators/init/schema.js'; -export { initGenerator, initSchematic } from './generators/init/generator.js'; -export type { ConfigurationGeneratorOptions } from './generators/configuration/schema.js'; -export { configurationGenerator } from './generators/configuration/generator.js'; -export { generateCodePushupConfig } from './generators/configuration/code-pushup-config.js'; -export { createNodes } from './plugin/index.js'; -export { - executeProcess, - type ProcessConfig, -} from './internal/execute-process.js'; -export { objectToCliArgs } from './executors/internal/cli.js'; +export * from './internal/versions'; +export { type InitGeneratorSchema } from './generators/init/schema'; +export { initGenerator, initSchematic } from './generators/init/generator'; +export type { ConfigurationGeneratorOptions } from './generators/configuration/schema'; +export { configurationGenerator } from './generators/configuration/generator'; +export { generateCodePushupConfig } from './generators/configuration/code-pushup-config'; +export { createNodes } from './plugin/index'; +export { executeProcess, type ProcessConfig } from './internal/execute-process'; +export { objectToCliArgs } from './executors/internal/cli'; export type { AutorunCommandExecutorOptions } from './executors/cli/schema.js'; diff --git a/packages/nx-plugin/src/internal/constants.ts b/packages/nx-plugin/src/internal/constants.ts index cac41a656..f69356ea3 100644 --- a/packages/nx-plugin/src/internal/constants.ts +++ b/packages/nx-plugin/src/internal/constants.ts @@ -1,5 +1,4 @@ -import { name } from '../../package.json'; - export const PROJECT_JSON_FILE_NAME = 'project.json'; -export const PACKAGE_NAME = name; +export const CODE_PUSHUP_CONFIG_REGEX = /^code-pushup(?:\.[\w-]+)?\.ts$/; +export const PACKAGE_NAME = '@code-pushup/nx-plugin'; export const DEFAULT_TARGET_NAME = 'code-pushup'; diff --git a/packages/nx-plugin/src/internal/execute-process.ts b/packages/nx-plugin/src/internal/execute-process.ts index cedc3fdbc..c9772cf78 100644 --- a/packages/nx-plugin/src/internal/execute-process.ts +++ b/packages/nx-plugin/src/internal/execute-process.ts @@ -123,7 +123,7 @@ export type ProcessObserver = { * // async process execution * const result = await executeProcess({ * command: 'node', - * args: ['download-data.js'], + * args: ['download-data'], * observer: { * onStdout: updateProgress, * error: handleError, diff --git a/packages/nx-plugin/src/internal/execute-process.unit.test.ts b/packages/nx-plugin/src/internal/execute-process.unit.test.ts index 5893b867f..58555a7ee 100644 --- a/packages/nx-plugin/src/internal/execute-process.unit.test.ts +++ b/packages/nx-plugin/src/internal/execute-process.unit.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest'; import { getAsyncProcessRunnerConfig } from '@code-pushup/test-utils'; -import { type ProcessObserver, executeProcess } from './execute-process.js'; +import { type ProcessObserver, executeProcess } from './execute-process'; describe('executeProcess', () => { const spyObserver: ProcessObserver = { diff --git a/packages/nx-plugin/src/plugin/index.ts b/packages/nx-plugin/src/plugin/index.ts index 648d0b4aa..186bb0d5c 100644 --- a/packages/nx-plugin/src/plugin/index.ts +++ b/packages/nx-plugin/src/plugin/index.ts @@ -1,2 +1,2 @@ -export { createNodes } from './plugin.js'; -export type { CreateNodesOptions } from './types.js'; +export { createNodes } from './plugin'; +export type { CreateNodesOptions } from './types'; diff --git a/packages/nx-plugin/src/plugin/plugin.unit.test.ts b/packages/nx-plugin/src/plugin/plugin.unit.test.ts index c51ebf570..aa218e617 100644 --- a/packages/nx-plugin/src/plugin/plugin.unit.test.ts +++ b/packages/nx-plugin/src/plugin/plugin.unit.test.ts @@ -2,9 +2,9 @@ import type { CreateNodesContext } from '@nx/devkit'; import { vol } from 'memfs'; import { describe, expect } from 'vitest'; import { invokeCreateNodesOnVirtualFiles } from '@code-pushup/test-nx-utils'; -import { PACKAGE_NAME, PROJECT_JSON_FILE_NAME } from '../internal/constants.js'; -import { CP_TARGET_NAME } from './constants.js'; -import { createNodes } from './plugin.js'; +import { PACKAGE_NAME, PROJECT_JSON_FILE_NAME } from '../internal/constants'; +import { CP_TARGET_NAME } from './constants'; +import { createNodes } from './plugin'; describe('@code-pushup/nx-plugin/plugin', () => { let context: CreateNodesContext; diff --git a/packages/nx-plugin/src/plugin/target/configuration-target.ts b/packages/nx-plugin/src/plugin/target/configuration-target.ts index d19b9325b..f9b16c985 100644 --- a/packages/nx-plugin/src/plugin/target/configuration-target.ts +++ b/packages/nx-plugin/src/plugin/target/configuration-target.ts @@ -1,8 +1,8 @@ import type { TargetConfiguration } from '@nx/devkit'; import type { RunCommandsOptions } from 'nx/src/executors/run-commands/run-commands.impl'; -import { objectToCliArgs } from '../../executors/internal/cli.js'; -import { PACKAGE_NAME } from '../../internal/constants.js'; -import { CP_TARGET_NAME } from '../constants.js'; +import { objectToCliArgs } from '../../executors/internal/cli'; +import { PACKAGE_NAME } from '../../internal/constants'; +import { CP_TARGET_NAME } from '../constants'; export function createConfigurationTarget(options?: { targetName?: string; diff --git a/packages/nx-plugin/src/plugin/target/configuration.target.unit.test.ts b/packages/nx-plugin/src/plugin/target/configuration.target.unit.test.ts index 87f4418c9..95bf05a6d 100644 --- a/packages/nx-plugin/src/plugin/target/configuration.target.unit.test.ts +++ b/packages/nx-plugin/src/plugin/target/configuration.target.unit.test.ts @@ -1,6 +1,6 @@ import { expect } from 'vitest'; -import { PACKAGE_NAME } from '../../internal/constants.js'; -import { createConfigurationTarget } from './configuration-target.js'; +import { PACKAGE_NAME } from '../../internal/constants'; +import { createConfigurationTarget } from './configuration-target'; describe('createConfigurationTarget', () => { it('should return code-pushup--configuration target for given project', () => { diff --git a/packages/nx-plugin/src/plugin/target/executor-target.ts b/packages/nx-plugin/src/plugin/target/executor-target.ts index e8b52eb8f..aeba82ad8 100644 --- a/packages/nx-plugin/src/plugin/target/executor-target.ts +++ b/packages/nx-plugin/src/plugin/target/executor-target.ts @@ -1,6 +1,6 @@ import type { TargetConfiguration } from '@nx/devkit'; -import { PACKAGE_NAME } from '../../internal/constants.js'; -import type { ProjectPrefixOptions } from '../types.js'; +import { PACKAGE_NAME } from '../../internal/constants'; +import type { ProjectPrefixOptions } from '../types'; export function createExecutorTarget(options?: { bin?: string; diff --git a/packages/nx-plugin/src/plugin/target/executor.target.unit.test.ts b/packages/nx-plugin/src/plugin/target/executor.target.unit.test.ts index 610b44bd7..8ea0799a7 100644 --- a/packages/nx-plugin/src/plugin/target/executor.target.unit.test.ts +++ b/packages/nx-plugin/src/plugin/target/executor.target.unit.test.ts @@ -1,5 +1,5 @@ import { expect } from 'vitest'; -import { createExecutorTarget } from './executor-target.js'; +import { createExecutorTarget } from './executor-target'; describe('createExecutorTarget', () => { it('should return executor target without project name', () => { diff --git a/packages/nx-plugin/src/plugin/target/targets.ts b/packages/nx-plugin/src/plugin/target/targets.ts index 3e659688b..188252a8d 100644 --- a/packages/nx-plugin/src/plugin/target/targets.ts +++ b/packages/nx-plugin/src/plugin/target/targets.ts @@ -1,13 +1,19 @@ import { readdir } from 'node:fs/promises'; -import { CP_TARGET_NAME } from '../constants.js'; -import type { NormalizedCreateNodesContext } from '../types.js'; -import { createConfigurationTarget } from './configuration-target.js'; -import { CODE_PUSHUP_CONFIG_REGEX } from './constants.js'; -import { createExecutorTarget } from './executor-target.js'; +import { CP_TARGET_NAME } from '../constants'; +import type { + CreateNodesOptions, + ProjectConfigurationWithName, +} from '../types'; +import { createConfigurationTarget } from './configuration-target'; +import { CODE_PUSHUP_CONFIG_REGEX } from './constants'; +import { createExecutorTarget } from './executor-target'; -export async function createTargets( - normalizedContext: NormalizedCreateNodesContext, -) { +export type CreateTargetsOptions = { + projectJson: ProjectConfigurationWithName; + projectRoot: string; + createOptions: CreateNodesOptions; +}; +export async function createTargets(normalizedContext: CreateTargetsOptions) { const { targetName = CP_TARGET_NAME, bin, diff --git a/packages/nx-plugin/src/plugin/target/targets.unit.test.ts b/packages/nx-plugin/src/plugin/target/targets.unit.test.ts index 9b730f726..0de7288d2 100644 --- a/packages/nx-plugin/src/plugin/target/targets.unit.test.ts +++ b/packages/nx-plugin/src/plugin/target/targets.unit.test.ts @@ -2,10 +2,10 @@ import { vol } from 'memfs'; import { rm } from 'node:fs/promises'; import { afterEach, beforeEach, expect } from 'vitest'; import { MEMFS_VOLUME } from '@code-pushup/test-utils'; -import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants.js'; -import { CP_TARGET_NAME } from '../constants.js'; -import type { NormalizedCreateNodesContext } from '../types.js'; -import { createTargets } from './targets.js'; +import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants'; +import { CP_TARGET_NAME } from '../constants'; +import type { NormalizedCreateNodesContext } from '../types'; +import { createTargets } from './targets'; describe('createTargets', () => { beforeEach(async () => { diff --git a/packages/nx-plugin/src/plugin/types.ts b/packages/nx-plugin/src/plugin/types.ts index 5e8d59db7..eb5982ce0 100644 --- a/packages/nx-plugin/src/plugin/types.ts +++ b/packages/nx-plugin/src/plugin/types.ts @@ -1,6 +1,11 @@ -import type { CreateNodesContext, ProjectConfiguration } from '@nx/devkit'; +import type { + CreateNodesContext, + CreateNodesContextV2, + ProjectConfiguration, +} from '@nx/devkit'; import type { WithRequired } from '@code-pushup/utils'; -import type { DynamicTargetOptions } from '../internal/types.js'; +import type { DynamicTargetOptions } from '../internal/types'; +import { CreateTargetsOptions } from './target/targets'; export type ProjectPrefixOptions = { projectPrefix?: string; @@ -13,8 +18,8 @@ export type ProjectConfigurationWithName = WithRequired< 'name' >; -export type NormalizedCreateNodesContext = CreateNodesContext & { - projectJson: ProjectConfigurationWithName; - projectRoot: string; - createOptions: CreateNodesOptions; -}; +export type NormalizedCreateNodesContext = CreateNodesContext & + CreateTargetsOptions; + +export type NormalizedCreateNodesV2Context = CreateNodesContextV2 & + CreateTargetsOptions; diff --git a/packages/nx-plugin/src/plugin/utils.unit.test.ts b/packages/nx-plugin/src/plugin/utils.unit.test.ts index edf2bf1cb..f88811467 100644 --- a/packages/nx-plugin/src/plugin/utils.unit.test.ts +++ b/packages/nx-plugin/src/plugin/utils.unit.test.ts @@ -2,7 +2,7 @@ import { vol } from 'memfs'; import { describe, expect } from 'vitest'; import { createNodesContext } from '@code-pushup/test-nx-utils'; import { MEMFS_VOLUME } from '@code-pushup/test-utils'; -import { normalizedCreateNodesContext } from './utils.js'; +import { normalizedCreateNodesContext } from './utils'; describe('normalizedCreateNodesContext', () => { it('should provide workspaceRoot', async () => { From d10f1bea8310d78089807ab994b511100798f5cf Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 22 Feb 2025 13:38:28 +0100 Subject: [PATCH 03/30] fix(nx-plugin): add createNodesV2 --- packages/nx-plugin/src/plugin/plugin.ts | 58 ++++++++++++++++++++++--- packages/nx-plugin/src/plugin/utils.ts | 33 ++++++++++++-- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/packages/nx-plugin/src/plugin/plugin.ts b/packages/nx-plugin/src/plugin/plugin.ts index 9129f1bd7..ae60f2193 100644 --- a/packages/nx-plugin/src/plugin/plugin.ts +++ b/packages/nx-plugin/src/plugin/plugin.ts @@ -1,14 +1,24 @@ -import type { +import { CreateNodes, CreateNodesContext, + CreateNodesContextV2, CreateNodesResult, + CreateNodesV2, + createNodesFromFiles, } from '@nx/devkit'; -import { PROJECT_JSON_FILE_NAME } from '../internal/constants.js'; -import { createTargets } from './target/targets.js'; -import type { CreateNodesOptions } from './types.js'; -import { normalizedCreateNodesContext } from './utils.js'; +import { dirname } from 'path'; +import { + CODE_PUSHUP_CONFIG_REGEX, + PROJECT_JSON_FILE_NAME, +} from '../internal/constants'; +import { createTargets } from './target/targets'; +import type { CreateNodesOptions } from './types'; +import { + normalizedCreateNodesContext, + normalizedCreateNodesV2Context, +} from './utils'; -// name has to be "createNodes" to get picked up by Nx +// name has to be "createNodes" to get picked up by Nx = [ + `**/${CODE_PUSHUP_CONFIG_REGEX}`, + async (configFiles, options, context) => { + return await createNodesFromFiles( + (configFile, options, context) => + createNodesInternal(configFile, options ?? {}, context), + configFiles, + options, + context, + ); + }, +]; + +async function createNodesInternal( + codePushupConfigFilePath: string, + options: CreateNodesOptions, + context: CreateNodesContextV2, +) { + //const projectConfiguration = readJsonFile(configFilePath); + const root = dirname(codePushupConfigFilePath); + const parsedCreateNodesOptions = options; + const normalizedContext = await normalizedCreateNodesV2Context( + context, + codePushupConfigFilePath, + parsedCreateNodesOptions, + ); + // Project configuration to be merged into the rest of the Nx configuration + return { + projects: { + [root]: { + targets: await createTargets(normalizedContext), + }, + }, + }; +} diff --git a/packages/nx-plugin/src/plugin/utils.ts b/packages/nx-plugin/src/plugin/utils.ts index e7a819f8d..b8b7cc4be 100644 --- a/packages/nx-plugin/src/plugin/utils.ts +++ b/packages/nx-plugin/src/plugin/utils.ts @@ -1,12 +1,13 @@ -import type { CreateNodesContext } from '@nx/devkit'; +import type { CreateNodesContext, CreateNodesContextV2 } from '@nx/devkit'; import { readFile } from 'node:fs/promises'; import * as path from 'node:path'; -import { CP_TARGET_NAME } from './constants.js'; +import { CP_TARGET_NAME } from './constants'; import type { CreateNodesOptions, NormalizedCreateNodesContext, + NormalizedCreateNodesV2Context, ProjectConfigurationWithName, -} from './types.js'; +} from './types'; export async function normalizedCreateNodesContext( context: CreateNodesContext, @@ -36,3 +37,29 @@ export async function normalizedCreateNodesContext( ); } } + +export async function normalizedCreateNodesV2Context( + context: CreateNodesContextV2, + projectConfigurationFile: string, + createOptions: CreateNodesOptions = {}, +): Promise { + const projectRoot = path.dirname(projectConfigurationFile); + + try { + const projectJson = JSON.parse( + (await readFile(projectConfigurationFile)).toString(), + ) as ProjectConfigurationWithName; + + const { targetName = CP_TARGET_NAME } = createOptions; + return { + ...context, + projectJson, + projectRoot, + createOptions: { ...createOptions, targetName }, + }; + } catch { + throw new Error( + `Error parsing project.json file ${projectConfigurationFile}.`, + ); + } +} From ff94e39992880e51f74c0c9e2b4126ed71b47453 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 22 Feb 2025 14:24:42 +0100 Subject: [PATCH 04/30] fix(nx-plugin): add createNodesV2 --- .../src/executors/cli/utils.unit.test.ts | 4 ++-- packages/nx-plugin/src/plugin/plugin.unit.test.ts | 1 + testing/test-nx-utils/src/lib/utils/nx-plugin.ts | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/nx-plugin/src/executors/cli/utils.unit.test.ts b/packages/nx-plugin/src/executors/cli/utils.unit.test.ts index 4702b4dff..c56bd198d 100644 --- a/packages/nx-plugin/src/executors/cli/utils.unit.test.ts +++ b/packages/nx-plugin/src/executors/cli/utils.unit.test.ts @@ -73,7 +73,7 @@ describe('parseAutorunExecutorOptions', () => { }, }, ); - expect(osAgnosticPath(executorOptions.config)).toBe( + expect(osAgnosticPath(executorOptions.config ?? '')).toBe( osAgnosticPath('root/code-pushup.config.ts'), ); expect(executorOptions).toEqual( @@ -91,7 +91,7 @@ describe('parseAutorunExecutorOptions', () => { }), ); - expect(osAgnosticPath(executorOptions.persist?.outputDir)).toBe( + expect(osAgnosticPath(executorOptions.persist?.outputDir ?? '')).toBe( osAgnosticPath('workspaceRoot/.code-pushup/my-app'), ); }); diff --git a/packages/nx-plugin/src/plugin/plugin.unit.test.ts b/packages/nx-plugin/src/plugin/plugin.unit.test.ts index aa218e617..012524116 100644 --- a/packages/nx-plugin/src/plugin/plugin.unit.test.ts +++ b/packages/nx-plugin/src/plugin/plugin.unit.test.ts @@ -13,6 +13,7 @@ describe('@code-pushup/nx-plugin/plugin', () => { context = { nxJsonConfiguration: {}, workspaceRoot: '', + configFiles: [], }; }); diff --git a/testing/test-nx-utils/src/lib/utils/nx-plugin.ts b/testing/test-nx-utils/src/lib/utils/nx-plugin.ts index 30d9706ba..65676bd9a 100644 --- a/testing/test-nx-utils/src/lib/utils/nx-plugin.ts +++ b/testing/test-nx-utils/src/lib/utils/nx-plugin.ts @@ -56,6 +56,21 @@ export async function invokeCreateNodesOnVirtualFiles< } export function createNodesContext( + options?: Partial, +): CreateNodesContext { + const { + workspaceRoot = process.cwd(), + nxJsonConfiguration = {}, + configFiles = [], + } = options ?? {}; + return { + workspaceRoot, + nxJsonConfiguration, + configFiles, + }; +} + +export function createNodesV2Context( options?: Partial, ): CreateNodesContextV2 { const { workspaceRoot = process.cwd(), nxJsonConfiguration = {} } = From 45c8667540fedf1f5a5b367e549603672255678c Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 22 Feb 2025 14:25:08 +0100 Subject: [PATCH 05/30] ci: setup plugin --- nx.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nx.json b/nx.json index c217cad19..2f47964b6 100644 --- a/nx.json +++ b/nx.json @@ -84,7 +84,10 @@ }, "plugins": [ { - "plugin": "./dist/packages/nx-plugin" + "plugin": "./dist/packages/nx-plugin", + "options": { + "targetName": "cp" + } }, { "plugin": "@push-based/nx-verdaccio", From a3316bc3f0e7fccb8e6898909286b6b7f4331e66 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 22 Feb 2025 14:25:30 +0100 Subject: [PATCH 06/30] ci: setup cp for models --- packages/models/code-pushup.config.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 packages/models/code-pushup.config.ts diff --git a/packages/models/code-pushup.config.ts b/packages/models/code-pushup.config.ts new file mode 100644 index 000000000..1c4475af8 --- /dev/null +++ b/packages/models/code-pushup.config.ts @@ -0,0 +1,10 @@ +import { mergeConfigs } from '@code-pushup/utils'; +import { eslintCoreConfigNx } from '../../code-pushup.preset'; + +// see: https://github.com/code-pushup/cli/blob/main/packages/models/docs/models-reference.md#coreconfig +export default mergeConfigs( + { + plugins: [], + }, + await eslintCoreConfigNx(), +); From 48143dca4bad6235c687979dc3089cfbaf4a28e3 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 22 Feb 2025 14:36:34 +0100 Subject: [PATCH 07/30] wip --- nx.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx.json b/nx.json index 2f47964b6..9289a6979 100644 --- a/nx.json +++ b/nx.json @@ -84,7 +84,7 @@ }, "plugins": [ { - "plugin": "./dist/packages/nx-plugin", + "plugin": "@code-pushup/nx-plugin", "options": { "targetName": "cp" } From 233cfd7324958336b016417ca9b159e58425eb25 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 4 Mar 2025 00:39:56 +0100 Subject: [PATCH 08/30] wip 1 --- .../tests/executor-cli.e2e.test.ts | 26 ++++++++++++++ packages/models/code-pushup.config.ts | 4 +-- packages/models/tsconfig.test.json | 1 + packages/nx-plugin/src/plugin/plugin.ts | 36 ------------------- 4 files changed, 29 insertions(+), 38 deletions(-) diff --git a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts index 2a3797492..e5561a462 100644 --- a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts +++ b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts @@ -100,6 +100,32 @@ describe('executor command', () => { ).rejects.toThrow(''); }); + it('should execute print-config executor with api key', async () => { + const cwd = path.join(testFileDir, 'execute-print-config-command'); + await addTargetToWorkspace(tree, { cwd, project }); + + const { stdout, code } = await executeProcess({ + command: 'npx', + args: [ + 'nx', + 'run', + `${project}:code-pushup`, + 'print-config', + '--upload.apiKey=a123a', + ], + cwd, + }); + + expect(code).toBe(0); + const cleanStdout = removeColorCodes(stdout); + expect(cleanStdout).toContain('nx run my-lib:code-pushup print-config'); + expect(cleanStdout).toContain('a123a'); + + await expect(() => + readJsonFile(path.join(cwd, '.code-pushup', project, 'report.json')), + ).rejects.toThrow(''); + }); + it('should execute collect executor and merge target and command-line options', async () => { const cwd = path.join(testFileDir, 'execute-collect-with-merged-options'); await addTargetToWorkspace( diff --git a/packages/models/code-pushup.config.ts b/packages/models/code-pushup.config.ts index 1c4475af8..dad38404f 100644 --- a/packages/models/code-pushup.config.ts +++ b/packages/models/code-pushup.config.ts @@ -1,5 +1,5 @@ -import { mergeConfigs } from '@code-pushup/utils'; -import { eslintCoreConfigNx } from '../../code-pushup.preset'; +import { eslintCoreConfigNx } from '../../code-pushup.preset.js'; +import { mergeConfigs } from '../../dist/packages/utils/src/index.js'; // see: https://github.com/code-pushup/cli/blob/main/packages/models/docs/models-reference.md#coreconfig export default mergeConfigs( diff --git a/packages/models/tsconfig.test.json b/packages/models/tsconfig.test.json index bb1ab5e0c..c7a178bbe 100644 --- a/packages/models/tsconfig.test.json +++ b/packages/models/tsconfig.test.json @@ -4,6 +4,7 @@ "outDir": "../../dist/out-tsc", "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"] }, + "exclude": ["**/code-pushup.config.ts"], "include": [ "vite.config.unit.ts", "vite.config.integration.ts", diff --git a/packages/nx-plugin/src/plugin/plugin.ts b/packages/nx-plugin/src/plugin/plugin.ts index ae60f2193..f5235f13d 100644 --- a/packages/nx-plugin/src/plugin/plugin.ts +++ b/packages/nx-plugin/src/plugin/plugin.ts @@ -42,39 +42,3 @@ export const createNodes: CreateNodes = [ }; }, ]; - -export const createNodesV2: CreateNodesV2 = [ - `**/${CODE_PUSHUP_CONFIG_REGEX}`, - async (configFiles, options, context) => { - return await createNodesFromFiles( - (configFile, options, context) => - createNodesInternal(configFile, options ?? {}, context), - configFiles, - options, - context, - ); - }, -]; - -async function createNodesInternal( - codePushupConfigFilePath: string, - options: CreateNodesOptions, - context: CreateNodesContextV2, -) { - //const projectConfiguration = readJsonFile(configFilePath); - const root = dirname(codePushupConfigFilePath); - const parsedCreateNodesOptions = options; - const normalizedContext = await normalizedCreateNodesV2Context( - context, - codePushupConfigFilePath, - parsedCreateNodesOptions, - ); - // Project configuration to be merged into the rest of the Nx configuration - return { - projects: { - [root]: { - targets: await createTargets(normalizedContext), - }, - }, - }; -} From c2ec88c0ef30dc5ef9fa0ae168451ac19ac56d40 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 5 Mar 2025 01:07:31 +0100 Subject: [PATCH 09/30] fix(nx-plugin): fix lint --- .../{eslint.config.cjs => eslint.config.js} | 1 + .../src/executors/cli/executor.unit.test.ts | 0 packages/nx-plugin/src/plugin/plugin.ts | 16 +++------------- packages/nx-plugin/src/plugin/types.ts | 2 +- 4 files changed, 5 insertions(+), 14 deletions(-) rename packages/nx-plugin/{eslint.config.cjs => eslint.config.js} (96%) delete mode 100644 packages/nx-plugin/src/executors/cli/executor.unit.test.ts diff --git a/packages/nx-plugin/eslint.config.cjs b/packages/nx-plugin/eslint.config.js similarity index 96% rename from packages/nx-plugin/eslint.config.cjs rename to packages/nx-plugin/eslint.config.js index e732748e6..937c98765 100644 --- a/packages/nx-plugin/eslint.config.cjs +++ b/packages/nx-plugin/eslint.config.js @@ -17,6 +17,7 @@ module.exports = tseslint.config( rules: { // Nx plugins don't yet support ESM: https://github.com/nrwl/nx/issues/15682 'unicorn/prefer-module': 'off', + 'n/file-extension-in-import': 'off', // used instead of verbatimModuleSyntax tsconfig flag (requires ESM) '@typescript-eslint/consistent-type-imports': [ 'warn', diff --git a/packages/nx-plugin/src/executors/cli/executor.unit.test.ts b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/nx-plugin/src/plugin/plugin.ts b/packages/nx-plugin/src/plugin/plugin.ts index f5235f13d..b80ede311 100644 --- a/packages/nx-plugin/src/plugin/plugin.ts +++ b/packages/nx-plugin/src/plugin/plugin.ts @@ -1,22 +1,12 @@ -import { +import type { CreateNodes, CreateNodesContext, - CreateNodesContextV2, CreateNodesResult, - CreateNodesV2, - createNodesFromFiles, } from '@nx/devkit'; -import { dirname } from 'path'; -import { - CODE_PUSHUP_CONFIG_REGEX, - PROJECT_JSON_FILE_NAME, -} from '../internal/constants'; +import { PROJECT_JSON_FILE_NAME } from '../internal/constants'; import { createTargets } from './target/targets'; import type { CreateNodesOptions } from './types'; -import { - normalizedCreateNodesContext, - normalizedCreateNodesV2Context, -} from './utils'; +import { normalizedCreateNodesContext } from './utils'; // name has to be "createNodes" to get picked up by Nx Date: Wed, 5 Mar 2025 02:05:50 +0100 Subject: [PATCH 10/30] fix(nx-plugin): fix lint --- .../src/lib/utils/nx-plugin.unit.test.ts | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/testing/test-nx-utils/src/lib/utils/nx-plugin.unit.test.ts b/testing/test-nx-utils/src/lib/utils/nx-plugin.unit.test.ts index 68a9d5daa..7710cfccf 100644 --- a/testing/test-nx-utils/src/lib/utils/nx-plugin.unit.test.ts +++ b/testing/test-nx-utils/src/lib/utils/nx-plugin.unit.test.ts @@ -11,18 +11,22 @@ describe('createNodesContext', () => { workspaceRoot: 'root', nxJsonConfiguration: { plugins: [] }, }); - expect(context).toEqual({ - workspaceRoot: 'root', - nxJsonConfiguration: { plugins: [] }, - }); + expect(context).toStrictEqual( + expect.objectContaining({ + workspaceRoot: 'root', + nxJsonConfiguration: { plugins: [] }, + }), + ); }); it('should return a context with defaults', () => { const context = createNodesContext(); - expect(context).toEqual({ - workspaceRoot: process.cwd(), - nxJsonConfiguration: {}, - }); + expect(context).toStrictEqual( + expect.objectContaining({ + workspaceRoot: process.cwd(), + nxJsonConfiguration: {}, + }), + ); }); }); From 35961492448eeac52c00edbe870f47256ed595be Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 5 Mar 2025 02:08:39 +0100 Subject: [PATCH 11/30] fix: wip --- nx.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/nx.json b/nx.json index 019e31adf..84fbf0790 100644 --- a/nx.json +++ b/nx.json @@ -16,11 +16,6 @@ "e2e": { "dependsOn": ["^build"] }, - "cp": { - "options": { - "bin": "dist/packages/cli/src/index.js" - } - }, "@nx/vite:test": { "cache": true, "inputs": ["default", "^production"], From d3756863673bd1af658eff536df173646d997309 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 5 Mar 2025 12:19:38 +0100 Subject: [PATCH 12/30] docs: add js docs --- packages/nx-plugin/src/internal/versions.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/nx-plugin/src/internal/versions.ts b/packages/nx-plugin/src/internal/versions.ts index 884dad9a7..b7e24f64a 100644 --- a/packages/nx-plugin/src/internal/versions.ts +++ b/packages/nx-plugin/src/internal/versions.ts @@ -16,6 +16,10 @@ export const cpCliVersion = loadPackageJson( path.join(projectsFolder, 'models'), ).version; +/** + * Load the package.json file from the given folder path. + * @param folderPath + */ function loadPackageJson(folderPath: string): PackageJson { return readJsonFile(path.join(folderPath, 'package.json')); } From a754393394967a01d643b5aff3810580225ec6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Chalk?= Date: Mon, 10 Mar 2025 11:59:01 +0100 Subject: [PATCH 13/30] refactor(nx-plugin): explicit import extensions --- .../nx-plugin/src/executors/cli/executor.ts | 8 +++---- .../nx-plugin/src/executors/cli/schema.ts | 2 +- .../executors/cli/utils.integration.test.ts | 6 ++--- packages/nx-plugin/src/executors/cli/utils.ts | 10 +++++--- .../src/executors/cli/utils.unit.test.ts | 4 ++-- .../src/executors/internal/cli.unit.test.ts | 2 +- .../internal/config.integration.test.ts | 2 +- .../src/executors/internal/config.ts | 4 ++-- .../src/executors/internal/context.ts | 2 +- .../executors/internal/context.unit.test.ts | 2 +- .../src/executors/internal/env.unit.test.ts | 2 +- .../code-pushup-config.integration.test.ts | 2 +- .../configuration/code-pushup-config.ts | 4 ++-- .../generator.integration.test.ts | 4 ++-- .../src/generators/configuration/generator.ts | 6 ++--- .../src/generators/configuration/schema.d.ts | 2 +- .../src/generators/configuration/utils.ts | 2 +- .../init/generator.integration.test.ts | 2 +- .../src/generators/init/generator.ts | 6 ++--- packages/nx-plugin/src/index.ts | 23 +++++++++++-------- .../src/internal/execute-process.unit.test.ts | 2 +- packages/nx-plugin/src/plugin/index.ts | 4 ++-- packages/nx-plugin/src/plugin/plugin.ts | 8 +++---- .../nx-plugin/src/plugin/plugin.unit.test.ts | 6 ++--- .../src/plugin/target/configuration-target.ts | 6 ++--- .../target/configuration.target.unit.test.ts | 4 ++-- .../src/plugin/target/executor-target.ts | 4 ++-- .../target/executor.target.unit.test.ts | 2 +- .../nx-plugin/src/plugin/target/targets.ts | 10 ++++---- .../src/plugin/target/targets.unit.test.ts | 8 +++---- packages/nx-plugin/src/plugin/types.ts | 4 ++-- packages/nx-plugin/src/plugin/utils.ts | 4 ++-- .../nx-plugin/src/plugin/utils.unit.test.ts | 2 +- 33 files changed, 83 insertions(+), 76 deletions(-) diff --git a/packages/nx-plugin/src/executors/cli/executor.ts b/packages/nx-plugin/src/executors/cli/executor.ts index 5db5e5e98..2ff27ed74 100644 --- a/packages/nx-plugin/src/executors/cli/executor.ts +++ b/packages/nx-plugin/src/executors/cli/executor.ts @@ -1,9 +1,9 @@ import { type ExecutorContext, logger } from '@nx/devkit'; import { execSync } from 'node:child_process'; -import { createCliCommand } from '../internal/cli'; -import { normalizeContext } from '../internal/context'; -import type { AutorunCommandExecutorOptions } from './schema'; -import { mergeExecutorOptions, parseAutorunExecutorOptions } from './utils'; +import { createCliCommand } from '../internal/cli.js'; +import { normalizeContext } from '../internal/context.js'; +import type { AutorunCommandExecutorOptions } from './schema.js'; +import { mergeExecutorOptions, parseAutorunExecutorOptions } from './utils.js'; export type ExecutorOutput = { success: boolean; diff --git a/packages/nx-plugin/src/executors/cli/schema.ts b/packages/nx-plugin/src/executors/cli/schema.ts index d610483cb..d73a394b6 100644 --- a/packages/nx-plugin/src/executors/cli/schema.ts +++ b/packages/nx-plugin/src/executors/cli/schema.ts @@ -4,7 +4,7 @@ import type { GeneralExecutorOnlyOptions, GlobalExecutorOptions, ProjectExecutorOnlyOptions, -} from '../internal/types'; +} from '../internal/types.js'; export type AutorunCommandExecutorOnlyOptions = ProjectExecutorOnlyOptions & CollectExecutorOnlyOptions & diff --git a/packages/nx-plugin/src/executors/cli/utils.integration.test.ts b/packages/nx-plugin/src/executors/cli/utils.integration.test.ts index d15f9961d..180f22af1 100644 --- a/packages/nx-plugin/src/executors/cli/utils.integration.test.ts +++ b/packages/nx-plugin/src/executors/cli/utils.integration.test.ts @@ -1,8 +1,8 @@ import { expect, vi } from 'vitest'; import type { UploadConfig } from '@code-pushup/models'; -import { normalizedExecutorContext } from '../../../mock/utils/executor'; -import * as config from '../internal/config'; -import { parseAutorunExecutorOptions } from './utils'; +import { normalizedExecutorContext } from '../../../mock/utils/executor.js'; +import * as config from '../internal/config.js'; +import { parseAutorunExecutorOptions } from './utils.js'; describe('parseAutorunExecutorOptions', () => { const persistConfigSpy = vi.spyOn(config, 'persistConfig'); diff --git a/packages/nx-plugin/src/executors/cli/utils.ts b/packages/nx-plugin/src/executors/cli/utils.ts index cc121c958..afcca4542 100644 --- a/packages/nx-plugin/src/executors/cli/utils.ts +++ b/packages/nx-plugin/src/executors/cli/utils.ts @@ -1,9 +1,13 @@ -import { globalConfig, persistConfig, uploadConfig } from '../internal/config'; -import type { NormalizedExecutorContext } from '../internal/context'; +import { + globalConfig, + persistConfig, + uploadConfig, +} from '../internal/config.js'; +import type { NormalizedExecutorContext } from '../internal/context.js'; import type { AutorunCommandExecutorOnlyOptions, AutorunCommandExecutorOptions, -} from './schema'; +} from './schema.js'; export function parseAutorunExecutorOnlyOptions( options: Partial, diff --git a/packages/nx-plugin/src/executors/cli/utils.unit.test.ts b/packages/nx-plugin/src/executors/cli/utils.unit.test.ts index d60c36204..7a4141eff 100644 --- a/packages/nx-plugin/src/executors/cli/utils.unit.test.ts +++ b/packages/nx-plugin/src/executors/cli/utils.unit.test.ts @@ -1,11 +1,11 @@ import { type MockInstance, expect, vi } from 'vitest'; import { osAgnosticPath } from '@code-pushup/test-utils'; -import type { Command } from '../internal/types'; +import type { Command } from '../internal/types.js'; import { mergeExecutorOptions, parseAutorunExecutorOnlyOptions, parseAutorunExecutorOptions, -} from './utils'; +} from './utils.js'; describe('parseAutorunExecutorOnlyOptions', () => { it('should provide NO default projectPrefix', () => { diff --git a/packages/nx-plugin/src/executors/internal/cli.unit.test.ts b/packages/nx-plugin/src/executors/internal/cli.unit.test.ts index ab39b876b..e65cb0ec0 100644 --- a/packages/nx-plugin/src/executors/internal/cli.unit.test.ts +++ b/packages/nx-plugin/src/executors/internal/cli.unit.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createCliCommand, objectToCliArgs } from './cli'; +import { createCliCommand, objectToCliArgs } from './cli.js'; describe('objectToCliArgs', () => { it('should empty params', () => { diff --git a/packages/nx-plugin/src/executors/internal/config.integration.test.ts b/packages/nx-plugin/src/executors/internal/config.integration.test.ts index 4e7d91517..54b2e32dc 100644 --- a/packages/nx-plugin/src/executors/internal/config.integration.test.ts +++ b/packages/nx-plugin/src/executors/internal/config.integration.test.ts @@ -1,5 +1,5 @@ import { describe, expect } from 'vitest'; -import { ENV } from '../../../mock/fixtures/env'; +import { ENV } from '../../../mock/fixtures/env.js'; import { uploadConfig } from './config.js'; import * as env from './env.js'; diff --git a/packages/nx-plugin/src/executors/internal/config.ts b/packages/nx-plugin/src/executors/internal/config.ts index e083c3824..0eb13f8a8 100644 --- a/packages/nx-plugin/src/executors/internal/config.ts +++ b/packages/nx-plugin/src/executors/internal/config.ts @@ -1,11 +1,11 @@ import * as path from 'node:path'; import type { PersistConfig, UploadConfig } from '@code-pushup/models'; -import { parseEnv } from './env'; +import { parseEnv } from './env.js'; import type { BaseNormalizedExecutorContext, GlobalExecutorOptions, ProjectExecutorOnlyOptions, -} from './types'; +} from './types.js'; export function globalConfig( options: Partial>, diff --git a/packages/nx-plugin/src/executors/internal/context.ts b/packages/nx-plugin/src/executors/internal/context.ts index 33fd4ca14..38ca33416 100644 --- a/packages/nx-plugin/src/executors/internal/context.ts +++ b/packages/nx-plugin/src/executors/internal/context.ts @@ -1,5 +1,5 @@ import type { ExecutorContext } from 'nx/src/config/misc-interfaces'; -import type { BaseNormalizedExecutorContext } from './types'; +import type { BaseNormalizedExecutorContext } from './types.js'; export type NormalizedExecutorContext = BaseNormalizedExecutorContext & { projectName: string; diff --git a/packages/nx-plugin/src/executors/internal/context.unit.test.ts b/packages/nx-plugin/src/executors/internal/context.unit.test.ts index fbd43a733..9be17d2a9 100644 --- a/packages/nx-plugin/src/executors/internal/context.unit.test.ts +++ b/packages/nx-plugin/src/executors/internal/context.unit.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { normalizeContext } from './context'; +import { normalizeContext } from './context.js'; describe('normalizeContext', () => { it('should normalizeContext', () => { diff --git a/packages/nx-plugin/src/executors/internal/env.unit.test.ts b/packages/nx-plugin/src/executors/internal/env.unit.test.ts index eca10b8c5..548ef1e3b 100644 --- a/packages/nx-plugin/src/executors/internal/env.unit.test.ts +++ b/packages/nx-plugin/src/executors/internal/env.unit.test.ts @@ -1,5 +1,5 @@ import { describe, expect } from 'vitest'; -import { parseEnv } from './env'; +import { parseEnv } from './env.js'; describe('parseEnv', () => { it('should parse empty env vars', () => { diff --git a/packages/nx-plugin/src/generators/configuration/code-pushup-config.integration.test.ts b/packages/nx-plugin/src/generators/configuration/code-pushup-config.integration.test.ts index b07bd4e18..38238ff50 100644 --- a/packages/nx-plugin/src/generators/configuration/code-pushup-config.integration.test.ts +++ b/packages/nx-plugin/src/generators/configuration/code-pushup-config.integration.test.ts @@ -3,7 +3,7 @@ import { formatFiles } from '@nx/devkit'; import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import * as path from 'node:path'; import { describe, expect, it } from 'vitest'; -import { generateCodePushupConfig } from './code-pushup-config'; +import { generateCodePushupConfig } from './code-pushup-config.js'; describe('generateCodePushupConfig options', () => { let tree: devKit.Tree; diff --git a/packages/nx-plugin/src/generators/configuration/code-pushup-config.ts b/packages/nx-plugin/src/generators/configuration/code-pushup-config.ts index 671196971..6854797fb 100644 --- a/packages/nx-plugin/src/generators/configuration/code-pushup-config.ts +++ b/packages/nx-plugin/src/generators/configuration/code-pushup-config.ts @@ -2,13 +2,13 @@ import { type Tree, generateFiles, logger } from '@nx/devkit'; import * as path from 'node:path'; import type { PersistConfig, UploadConfig } from '@code-pushup/models'; import type { ItemOrArray } from '@code-pushup/utils'; -import type { ExecutableCode } from './types'; +import type { ExecutableCode } from './types.js'; import { formatArrayToLinesOfJsString, formatObjectToFormattedJsString, normalizeExecutableCode, normalizeItemOrArray, -} from './utils'; +} from './utils.js'; export const DEFAULT_IMPORTS = [ "import type { CoreConfig } from '@code-pushup/models';", diff --git a/packages/nx-plugin/src/generators/configuration/generator.integration.test.ts b/packages/nx-plugin/src/generators/configuration/generator.integration.test.ts index dc3ce206e..c98d60064 100644 --- a/packages/nx-plugin/src/generators/configuration/generator.integration.test.ts +++ b/packages/nx-plugin/src/generators/configuration/generator.integration.test.ts @@ -7,8 +7,8 @@ import { import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import * as path from 'node:path'; import { afterEach, describe, expect, it, vi } from 'vitest'; -import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants'; -import { addTargetToProject, configurationGenerator } from './generator'; +import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants.js'; +import { addTargetToProject, configurationGenerator } from './generator.js'; describe('addTargetToProject', () => { let tree: Tree; diff --git a/packages/nx-plugin/src/generators/configuration/generator.ts b/packages/nx-plugin/src/generators/configuration/generator.ts index dc0d49913..4b71b60a2 100644 --- a/packages/nx-plugin/src/generators/configuration/generator.ts +++ b/packages/nx-plugin/src/generators/configuration/generator.ts @@ -6,9 +6,9 @@ import { updateProjectConfiguration, } from '@nx/devkit'; import type { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json'; -import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants'; -import { generateCodePushupConfig } from './code-pushup-config'; -import type { ConfigurationGeneratorOptions } from './schema'; +import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants.js'; +import { generateCodePushupConfig } from './code-pushup-config.js'; +import type { ConfigurationGeneratorOptions } from './schema.js'; export async function configurationGenerator( tree: Tree, diff --git a/packages/nx-plugin/src/generators/configuration/schema.d.ts b/packages/nx-plugin/src/generators/configuration/schema.d.ts index d7b700308..b105270c6 100644 --- a/packages/nx-plugin/src/generators/configuration/schema.d.ts +++ b/packages/nx-plugin/src/generators/configuration/schema.d.ts @@ -1,4 +1,4 @@ -import type { DynamicTargetOptions } from '../../internal/types'; +import type { DynamicTargetOptions } from '../../internal/types.js'; export type ConfigurationGeneratorOptions = { project: string; diff --git a/packages/nx-plugin/src/generators/configuration/utils.ts b/packages/nx-plugin/src/generators/configuration/utils.ts index 5063a7aef..36464358a 100644 --- a/packages/nx-plugin/src/generators/configuration/utils.ts +++ b/packages/nx-plugin/src/generators/configuration/utils.ts @@ -1,5 +1,5 @@ import type { ExtractArrays } from '@code-pushup/utils'; -import type { ExecutableCode } from './types'; +import type { ExecutableCode } from './types.js'; export function normalizeExecutableCode( executableCode: ExecutableCode, diff --git a/packages/nx-plugin/src/generators/init/generator.integration.test.ts b/packages/nx-plugin/src/generators/init/generator.integration.test.ts index 05fe14511..5ab890bd1 100644 --- a/packages/nx-plugin/src/generators/init/generator.integration.test.ts +++ b/packages/nx-plugin/src/generators/init/generator.integration.test.ts @@ -1,7 +1,7 @@ import { type Tree, logger, readJson, readNxJson } from '@nx/devkit'; import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import { describe, expect, it, vi } from 'vitest'; -import { initGenerator } from './generator'; +import { initGenerator } from './generator.js'; type PackageJson = { devDependencies: Record; diff --git a/packages/nx-plugin/src/generators/init/generator.ts b/packages/nx-plugin/src/generators/init/generator.ts index 12f058751..265298fb0 100644 --- a/packages/nx-plugin/src/generators/init/generator.ts +++ b/packages/nx-plugin/src/generators/init/generator.ts @@ -12,14 +12,14 @@ import { updateNxJson, } from '@nx/devkit'; import type { PackageJson } from 'nx/src/utils/package-json'; -import { PACKAGE_NAME } from '../../internal/constants'; +import { PACKAGE_NAME } from '../../internal/constants.js'; import { cpCliVersion, cpModelVersion, cpNxPluginVersion, cpUtilsVersion, -} from '../../internal/versions'; -import type { InitGeneratorSchema } from './schema'; +} from '../../internal/versions.js'; +import type { InitGeneratorSchema } from './schema.js'; function checkDependenciesInstalled(host: Tree) { const packageJson = readJson(host, 'package.json'); diff --git a/packages/nx-plugin/src/index.ts b/packages/nx-plugin/src/index.ts index d8f698bbb..e516b18ce 100644 --- a/packages/nx-plugin/src/index.ts +++ b/packages/nx-plugin/src/index.ts @@ -1,15 +1,18 @@ -import { createNodes } from './plugin/index'; +import { createNodes } from './plugin/index.js'; // default export for nx.json#plugins export default createNodes; -export * from './internal/versions'; -export { type InitGeneratorSchema } from './generators/init/schema'; -export { initGenerator, initSchematic } from './generators/init/generator'; -export type { ConfigurationGeneratorOptions } from './generators/configuration/schema'; -export { configurationGenerator } from './generators/configuration/generator'; -export { generateCodePushupConfig } from './generators/configuration/code-pushup-config'; -export { createNodes } from './plugin/index'; -export { executeProcess, type ProcessConfig } from './internal/execute-process'; -export { objectToCliArgs } from './executors/internal/cli'; export type { AutorunCommandExecutorOptions } from './executors/cli/schema.js'; +export { objectToCliArgs } from './executors/internal/cli.js'; +export { generateCodePushupConfig } from './generators/configuration/code-pushup-config.js'; +export { configurationGenerator } from './generators/configuration/generator.js'; +export type { ConfigurationGeneratorOptions } from './generators/configuration/schema.js'; +export { initGenerator, initSchematic } from './generators/init/generator.js'; +export { type InitGeneratorSchema } from './generators/init/schema.js'; +export { + executeProcess, + type ProcessConfig, +} from './internal/execute-process.js'; +export * from './internal/versions.js'; +export { createNodes } from './plugin/index.js'; diff --git a/packages/nx-plugin/src/internal/execute-process.unit.test.ts b/packages/nx-plugin/src/internal/execute-process.unit.test.ts index 58555a7ee..5893b867f 100644 --- a/packages/nx-plugin/src/internal/execute-process.unit.test.ts +++ b/packages/nx-plugin/src/internal/execute-process.unit.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest'; import { getAsyncProcessRunnerConfig } from '@code-pushup/test-utils'; -import { type ProcessObserver, executeProcess } from './execute-process'; +import { type ProcessObserver, executeProcess } from './execute-process.js'; describe('executeProcess', () => { const spyObserver: ProcessObserver = { diff --git a/packages/nx-plugin/src/plugin/index.ts b/packages/nx-plugin/src/plugin/index.ts index 186bb0d5c..648d0b4aa 100644 --- a/packages/nx-plugin/src/plugin/index.ts +++ b/packages/nx-plugin/src/plugin/index.ts @@ -1,2 +1,2 @@ -export { createNodes } from './plugin'; -export type { CreateNodesOptions } from './types'; +export { createNodes } from './plugin.js'; +export type { CreateNodesOptions } from './types.js'; diff --git a/packages/nx-plugin/src/plugin/plugin.ts b/packages/nx-plugin/src/plugin/plugin.ts index b80ede311..1f125f5a8 100644 --- a/packages/nx-plugin/src/plugin/plugin.ts +++ b/packages/nx-plugin/src/plugin/plugin.ts @@ -3,10 +3,10 @@ import type { CreateNodesContext, CreateNodesResult, } from '@nx/devkit'; -import { PROJECT_JSON_FILE_NAME } from '../internal/constants'; -import { createTargets } from './target/targets'; -import type { CreateNodesOptions } from './types'; -import { normalizedCreateNodesContext } from './utils'; +import { PROJECT_JSON_FILE_NAME } from '../internal/constants.js'; +import { createTargets } from './target/targets.js'; +import type { CreateNodesOptions } from './types.js'; +import { normalizedCreateNodesContext } from './utils.js'; // name has to be "createNodes" to get picked up by Nx { let context: CreateNodesContext; diff --git a/packages/nx-plugin/src/plugin/target/configuration-target.ts b/packages/nx-plugin/src/plugin/target/configuration-target.ts index f9b16c985..d19b9325b 100644 --- a/packages/nx-plugin/src/plugin/target/configuration-target.ts +++ b/packages/nx-plugin/src/plugin/target/configuration-target.ts @@ -1,8 +1,8 @@ import type { TargetConfiguration } from '@nx/devkit'; import type { RunCommandsOptions } from 'nx/src/executors/run-commands/run-commands.impl'; -import { objectToCliArgs } from '../../executors/internal/cli'; -import { PACKAGE_NAME } from '../../internal/constants'; -import { CP_TARGET_NAME } from '../constants'; +import { objectToCliArgs } from '../../executors/internal/cli.js'; +import { PACKAGE_NAME } from '../../internal/constants.js'; +import { CP_TARGET_NAME } from '../constants.js'; export function createConfigurationTarget(options?: { targetName?: string; diff --git a/packages/nx-plugin/src/plugin/target/configuration.target.unit.test.ts b/packages/nx-plugin/src/plugin/target/configuration.target.unit.test.ts index 95bf05a6d..87f4418c9 100644 --- a/packages/nx-plugin/src/plugin/target/configuration.target.unit.test.ts +++ b/packages/nx-plugin/src/plugin/target/configuration.target.unit.test.ts @@ -1,6 +1,6 @@ import { expect } from 'vitest'; -import { PACKAGE_NAME } from '../../internal/constants'; -import { createConfigurationTarget } from './configuration-target'; +import { PACKAGE_NAME } from '../../internal/constants.js'; +import { createConfigurationTarget } from './configuration-target.js'; describe('createConfigurationTarget', () => { it('should return code-pushup--configuration target for given project', () => { diff --git a/packages/nx-plugin/src/plugin/target/executor-target.ts b/packages/nx-plugin/src/plugin/target/executor-target.ts index aeba82ad8..e8b52eb8f 100644 --- a/packages/nx-plugin/src/plugin/target/executor-target.ts +++ b/packages/nx-plugin/src/plugin/target/executor-target.ts @@ -1,6 +1,6 @@ import type { TargetConfiguration } from '@nx/devkit'; -import { PACKAGE_NAME } from '../../internal/constants'; -import type { ProjectPrefixOptions } from '../types'; +import { PACKAGE_NAME } from '../../internal/constants.js'; +import type { ProjectPrefixOptions } from '../types.js'; export function createExecutorTarget(options?: { bin?: string; diff --git a/packages/nx-plugin/src/plugin/target/executor.target.unit.test.ts b/packages/nx-plugin/src/plugin/target/executor.target.unit.test.ts index 8ea0799a7..610b44bd7 100644 --- a/packages/nx-plugin/src/plugin/target/executor.target.unit.test.ts +++ b/packages/nx-plugin/src/plugin/target/executor.target.unit.test.ts @@ -1,5 +1,5 @@ import { expect } from 'vitest'; -import { createExecutorTarget } from './executor-target'; +import { createExecutorTarget } from './executor-target.js'; describe('createExecutorTarget', () => { it('should return executor target without project name', () => { diff --git a/packages/nx-plugin/src/plugin/target/targets.ts b/packages/nx-plugin/src/plugin/target/targets.ts index 188252a8d..55e608896 100644 --- a/packages/nx-plugin/src/plugin/target/targets.ts +++ b/packages/nx-plugin/src/plugin/target/targets.ts @@ -1,12 +1,12 @@ import { readdir } from 'node:fs/promises'; -import { CP_TARGET_NAME } from '../constants'; +import { CP_TARGET_NAME } from '../constants.js'; import type { CreateNodesOptions, ProjectConfigurationWithName, -} from '../types'; -import { createConfigurationTarget } from './configuration-target'; -import { CODE_PUSHUP_CONFIG_REGEX } from './constants'; -import { createExecutorTarget } from './executor-target'; +} from '../types.js'; +import { createConfigurationTarget } from './configuration-target.js'; +import { CODE_PUSHUP_CONFIG_REGEX } from './constants.js'; +import { createExecutorTarget } from './executor-target.js'; export type CreateTargetsOptions = { projectJson: ProjectConfigurationWithName; diff --git a/packages/nx-plugin/src/plugin/target/targets.unit.test.ts b/packages/nx-plugin/src/plugin/target/targets.unit.test.ts index 0de7288d2..9b730f726 100644 --- a/packages/nx-plugin/src/plugin/target/targets.unit.test.ts +++ b/packages/nx-plugin/src/plugin/target/targets.unit.test.ts @@ -2,10 +2,10 @@ import { vol } from 'memfs'; import { rm } from 'node:fs/promises'; import { afterEach, beforeEach, expect } from 'vitest'; import { MEMFS_VOLUME } from '@code-pushup/test-utils'; -import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants'; -import { CP_TARGET_NAME } from '../constants'; -import type { NormalizedCreateNodesContext } from '../types'; -import { createTargets } from './targets'; +import { DEFAULT_TARGET_NAME, PACKAGE_NAME } from '../../internal/constants.js'; +import { CP_TARGET_NAME } from '../constants.js'; +import type { NormalizedCreateNodesContext } from '../types.js'; +import { createTargets } from './targets.js'; describe('createTargets', () => { beforeEach(async () => { diff --git a/packages/nx-plugin/src/plugin/types.ts b/packages/nx-plugin/src/plugin/types.ts index 4a1394972..4fd57ed95 100644 --- a/packages/nx-plugin/src/plugin/types.ts +++ b/packages/nx-plugin/src/plugin/types.ts @@ -4,8 +4,8 @@ import type { ProjectConfiguration, } from '@nx/devkit'; import type { WithRequired } from '@code-pushup/utils'; -import type { DynamicTargetOptions } from '../internal/types'; -import type { CreateTargetsOptions } from './target/targets'; +import type { DynamicTargetOptions } from '../internal/types.js'; +import type { CreateTargetsOptions } from './target/targets.js'; export type ProjectPrefixOptions = { projectPrefix?: string; diff --git a/packages/nx-plugin/src/plugin/utils.ts b/packages/nx-plugin/src/plugin/utils.ts index b8b7cc4be..8d551f682 100644 --- a/packages/nx-plugin/src/plugin/utils.ts +++ b/packages/nx-plugin/src/plugin/utils.ts @@ -1,13 +1,13 @@ import type { CreateNodesContext, CreateNodesContextV2 } from '@nx/devkit'; import { readFile } from 'node:fs/promises'; import * as path from 'node:path'; -import { CP_TARGET_NAME } from './constants'; +import { CP_TARGET_NAME } from './constants.js'; import type { CreateNodesOptions, NormalizedCreateNodesContext, NormalizedCreateNodesV2Context, ProjectConfigurationWithName, -} from './types'; +} from './types.js'; export async function normalizedCreateNodesContext( context: CreateNodesContext, diff --git a/packages/nx-plugin/src/plugin/utils.unit.test.ts b/packages/nx-plugin/src/plugin/utils.unit.test.ts index f88811467..edf2bf1cb 100644 --- a/packages/nx-plugin/src/plugin/utils.unit.test.ts +++ b/packages/nx-plugin/src/plugin/utils.unit.test.ts @@ -2,7 +2,7 @@ import { vol } from 'memfs'; import { describe, expect } from 'vitest'; import { createNodesContext } from '@code-pushup/test-nx-utils'; import { MEMFS_VOLUME } from '@code-pushup/test-utils'; -import { normalizedCreateNodesContext } from './utils'; +import { normalizedCreateNodesContext } from './utils.js'; describe('normalizedCreateNodesContext', () => { it('should provide workspaceRoot', async () => { From 2bcfcc70498dcbef617ee872a037806fa7fcc143 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Mon, 10 Mar 2025 17:16:59 +0100 Subject: [PATCH 14/30] Update packages/nx-plugin/src/plugin/target/targets.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/nx-plugin/src/plugin/target/targets.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/nx-plugin/src/plugin/target/targets.ts b/packages/nx-plugin/src/plugin/target/targets.ts index 55e608896..eb68740ef 100644 --- a/packages/nx-plugin/src/plugin/target/targets.ts +++ b/packages/nx-plugin/src/plugin/target/targets.ts @@ -13,6 +13,7 @@ export type CreateTargetsOptions = { projectRoot: string; createOptions: CreateNodesOptions; }; + export async function createTargets(normalizedContext: CreateTargetsOptions) { const { targetName = CP_TARGET_NAME, From 385d77c4418e8d0342192a152a4f2cb0428d16df Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Wed, 5 Mar 2025 11:13:25 +0100 Subject: [PATCH 15/30] fix: update nx-verdaccio pkg (#954) --- package-lock.json | 665 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 2 +- 2 files changed, 653 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7094c8ac4..8a43b0e37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "@nx/react": "19.8.13", "@nx/vite": "19.8.13", "@nx/workspace": "19.8.13", - "@push-based/nx-verdaccio": "0.0.0-alpha.26", + "@push-based/nx-verdaccio": "0.0.0-alpha.30", "@swc-node/register": "1.9.2", "@swc/cli": "0.3.14", "@swc/core": "1.5.7", @@ -5769,15 +5769,53 @@ } }, "node_modules/@push-based/nx-verdaccio": { - "version": "0.0.0-alpha.26", - "resolved": "https://registry.npmjs.org/@push-based/nx-verdaccio/-/nx-verdaccio-0.0.0-alpha.26.tgz", - "integrity": "sha512-Go11Dg+w5Ntl5Ig8YNzVVPbpOG85aVszjyBIK0FvVBX+/QllQY1F4fP8K8fYnMJnO9v5Tao3cryGFY5Zo9i+/g==", + "version": "0.0.0-alpha.30", + "resolved": "https://registry.npmjs.org/@push-based/nx-verdaccio/-/nx-verdaccio-0.0.0-alpha.30.tgz", + "integrity": "sha512-PB/WpfcqmyypyXkWKJBVinIgvOgYJV3ckXdQXKBHJuEKyUnfiUObmgnGqmlQqCgFlv5tvPkNGEFXDPTGL9JyGw==", "dev": true, "dependencies": { "@nx/devkit": "19.8.0", + "@nx/vite": "19.8.0", "ansis": "^3.3.2", "simple-git": "^3.27.0", - "tslib": "^2.3.0" + "tslib": "^2.3.0", + "vite": "~5.0.0", + "vitest": "^1.3.1" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, "node_modules/@push-based/nx-verdaccio/node_modules/@nrwl/devkit": { @@ -5789,6 +5827,46 @@ "@nx/devkit": "19.8.0" } }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nrwl/js": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nrwl/js/-/js-19.8.0.tgz", + "integrity": "sha512-agmIwKD6zK0l+aIEhDv3VuPW10rn5fhHeif3k5q9EgT47QL2gCNzU54oYpuXoKeenJCsDMzOEkJb1IsglVas6g==", + "dev": true, + "dependencies": { + "@nx/js": "19.8.0" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nrwl/tao": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-19.8.0.tgz", + "integrity": "sha512-tybyYdhHNfyBRb8SOc/SasT1iwjYkp/QibS8L3ayTvpvvzJpNr8BpuTznQWIkaIjilflmcdHl+rMiQDqwABqpg==", + "dev": true, + "dependencies": { + "nx": "19.8.0", + "tslib": "^2.3.0" + }, + "bin": { + "tao": "index.js" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nrwl/vite": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nrwl/vite/-/vite-19.8.0.tgz", + "integrity": "sha512-Nux7PN5HYFnSbVj0lVIhgMRkfJ7AYRBr8lXDsJBFboxUtmnPGpG5aV6o/9Fu2XD/eiLBsHCmMcusqkD0+jCvMA==", + "dev": true, + "dependencies": { + "@nx/vite": "19.8.0" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nrwl/workspace": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nrwl/workspace/-/workspace-19.8.0.tgz", + "integrity": "sha512-HSN0GML7RaVUSRD3lOc07atCjs4Vzs3Jgs9/7+zFtldKsmsY4GzYIWpJ4G6IDl9u3YJwTKtRmuj5BVI7G+ZGmw==", + "dev": true, + "dependencies": { + "@nx/workspace": "19.8.0" + } + }, "node_modules/@push-based/nx-verdaccio/node_modules/@nx/devkit": { "version": "19.8.0", "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-19.8.0.tgz", @@ -5809,19 +5887,580 @@ "nx": ">= 17 <= 20" } }, - "node_modules/@push-based/nx-verdaccio/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/js": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/js/-/js-19.8.0.tgz", + "integrity": "sha512-gexu1nYN3Hl3+yNuowgfd3sW5uooMKx9Dg6FPWWn/27+eJlTny5A2nQ3YR85yKRiJbNEP23am4le788pyVq2MQ==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "@babel/core": "^7.23.2", + "@babel/plugin-proposal-decorators": "^7.22.7", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-runtime": "^7.23.2", + "@babel/preset-env": "^7.23.2", + "@babel/preset-typescript": "^7.22.5", + "@babel/runtime": "^7.22.6", + "@nrwl/js": "19.8.0", + "@nx/devkit": "19.8.0", + "@nx/workspace": "19.8.0", + "babel-plugin-const-enum": "^1.0.1", + "babel-plugin-macros": "^2.8.0", + "babel-plugin-transform-typescript-metadata": "^0.3.1", + "chalk": "^4.1.0", + "columnify": "^1.6.0", + "detect-port": "^1.5.1", + "fast-glob": "3.2.7", + "ignore": "^5.0.4", + "js-tokens": "^4.0.0", + "jsonc-parser": "3.2.0", + "minimatch": "9.0.3", + "npm-package-arg": "11.0.1", + "npm-run-path": "^4.0.1", + "ora": "5.3.0", + "semver": "^7.5.3", + "source-map-support": "0.5.19", + "ts-node": "10.9.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "verdaccio": "^5.0.4" }, + "peerDependenciesMeta": { + "verdaccio": { + "optional": true + } + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/nx-darwin-arm64": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-19.8.0.tgz", + "integrity": "sha512-JWtBb6ndCdGE+RBIwKN85BZnX41lFGsFxnsmot71GeAj/g7Cb0PM2qcmxawoy8yLPTBGZhb+eHER3z3nDIqRog==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 10" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/nx-darwin-x64": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-19.8.0.tgz", + "integrity": "sha512-NcNaqbbStBkyahLaoKFtW6nEdjCjYT5ZOmGjc6UpAx1Y3pkk/FcIOYJRCBxwuOsRRsEAyeVcHPdYrouZmV+6Yw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/nx-freebsd-x64": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-19.8.0.tgz", + "integrity": "sha512-QXHRnMW5LrpYvtmdFRL2CRgX9CWDccrs2xhQNNzcgsLgL87Wte5kjDoJJN4GQjtrmjD3Q93w67CE9lhqnpXBvQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-19.8.0.tgz", + "integrity": "sha512-VjZOLMxz0gT+0AdDygxQS0Vvi3AcEzO3y9o9WdGKKaDVUDycrFn72X+ZbvFoio1dF7S1s2TbmOlR09Bu1yTgGg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/nx-linux-arm64-gnu": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-19.8.0.tgz", + "integrity": "sha512-sCSrXkSmEfDUDGLESXB3eHXECAIYz9nosFZpCggyUP1vgF/QcV40fHnV38nrFbKaVHuoaxy43RgnD+I3o6sDSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/nx-linux-arm64-musl": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-19.8.0.tgz", + "integrity": "sha512-F3xEe7NGjsVKZTVlvUiUOTmCzxteRsQH2SSsYXyAfgJ42P3eZPc9HgeLx6RByjC/NBCwc7XEECMP1FjQgQXHVw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/nx-linux-x64-gnu": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-19.8.0.tgz", + "integrity": "sha512-4uYuE+LvxOFXvi9z9ueJSVrME5D383SHNCjs6jYwc9KovCsmL5oPVXRieoE4/hYI4lrjly+CrAnPZU1P7ocBiw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/nx-linux-x64-musl": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-19.8.0.tgz", + "integrity": "sha512-9UDEGjOvNt+m+kMBCAB7CGisSwv05Xvaq8K3NJ+xM5GPG74EkQel24mSoIJfm/6zmDkdZCiRzNN9VRjOjzOz6Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/nx-win32-arm64-msvc": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-19.8.0.tgz", + "integrity": "sha512-JVzm0KjyLZY5ponBukZ/b35wttW0b3LB0nqaiiHY7WKwSzo+m0UGEYHD/Yk6rKA0RRZN2wQVeIzLeWfYcZYrhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/nx-win32-x64-msvc": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-19.8.0.tgz", + "integrity": "sha512-IRLhMZIInvp9okLsjnj76zaz8iaMovtLr6MHIFOOPIMsZYRhqQTArF5Os/NqEezeYYxvX6YZ5hKYe0xQO7A5LA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/vite": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/vite/-/vite-19.8.0.tgz", + "integrity": "sha512-Krok+zalc6as1w+V+D/mmY+vh5qKdkvz4omMds2k3d+RQNxIb7Mh78ueGVQr5zRtR9CKSSPvDMtUklnjDlp1SQ==", + "dev": true, + "dependencies": { + "@nrwl/vite": "19.8.0", + "@nx/devkit": "19.8.0", + "@nx/js": "19.8.0", + "@phenomnomnominal/tsquery": "~5.0.1", + "@swc/helpers": "~0.5.0", + "enquirer": "~2.3.6", + "minimatch": "9.0.3", + "tsconfig-paths": "^4.1.2" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "vite": "^5.0.0", + "vitest": "^1.3.1 || ^2.0.0" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/@nx/workspace": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/@nx/workspace/-/workspace-19.8.0.tgz", + "integrity": "sha512-8/NHRuJAqurNaFIUuSZdV8qNqiFykXlHjPp6E4raNmB8seIKYJVeYZgw9D7d5piOuLHA3o0JWSKJQ3nBElfCBw==", + "dev": true, + "dependencies": { + "@nrwl/workspace": "19.8.0", + "@nx/devkit": "19.8.0", + "chalk": "^4.1.0", + "enquirer": "~2.3.6", + "nx": "19.8.0", + "tslib": "^2.3.0", + "yargs-parser": "21.1.1" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@push-based/nx-verdaccio/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/@push-based/nx-verdaccio/node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/nx": { + "version": "19.8.0", + "resolved": "https://registry.npmjs.org/nx/-/nx-19.8.0.tgz", + "integrity": "sha512-zD1ZvkfxECrd9QnvUyAUVLESmjl0bpIhB1gLcYN2BqsCkB1vkngbxIvXDorI98keOVEfHzeuwNSkufQNls1hug==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@napi-rs/wasm-runtime": "0.2.4", + "@nrwl/tao": "19.8.0", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "3.0.0-rc.46", + "@zkochan/js-yaml": "0.0.7", + "axios": "^1.7.4", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^8.0.1", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "enquirer": "~2.3.6", + "figures": "3.2.0", + "flat": "^5.0.2", + "front-matter": "^4.0.2", + "fs-extra": "^11.1.0", + "ignore": "^5.0.4", + "jest-diff": "^29.4.1", + "jsonc-parser": "3.2.0", + "lines-and-columns": "2.0.3", + "minimatch": "9.0.3", + "node-machine-id": "1.1.12", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "ora": "5.3.0", + "semver": "^7.5.3", + "string-width": "^4.2.3", + "strong-log-transformer": "^2.1.0", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "bin/nx.js", + "nx-cloud": "bin/nx-cloud.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "19.8.0", + "@nx/nx-darwin-x64": "19.8.0", + "@nx/nx-freebsd-x64": "19.8.0", + "@nx/nx-linux-arm-gnueabihf": "19.8.0", + "@nx/nx-linux-arm64-gnu": "19.8.0", + "@nx/nx-linux-arm64-musl": "19.8.0", + "@nx/nx-linux-x64-gnu": "19.8.0", + "@nx/nx-linux-x64-musl": "19.8.0", + "@nx/nx-win32-arm64-msvc": "19.8.0", + "@nx/nx-win32-x64-msvc": "19.8.0" + }, + "peerDependencies": { + "@swc-node/register": "^1.8.0", + "@swc/core": "^1.3.85" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/@push-based/nx-verdaccio/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@push-based/nx-verdaccio/node_modules/vite": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.13.tgz", + "integrity": "sha512-/9ovhv2M2dGTuA+dY93B9trfyWMDRQw2jdVBhHNP6wr0oF34wG2i/N55801iZIpgUpnHDm4F/FabGQLyc+eOgg==", + "dev": true, + "dependencies": { + "esbuild": "^0.19.3", + "postcss": "^8.4.32", + "rollup": "^4.2.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } } }, "node_modules/@rollup/rollup-android-arm-eabi": { diff --git a/package.json b/package.json index 4313d674d..66b0db8fb 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@nx/react": "19.8.13", "@nx/vite": "19.8.13", "@nx/workspace": "19.8.13", - "@push-based/nx-verdaccio": "0.0.0-alpha.26", + "@push-based/nx-verdaccio": "0.0.0-alpha.30", "@swc-node/register": "1.9.2", "@swc/cli": "0.3.14", "@swc/core": "1.5.7", From fa5635ee0b6b4ce8d1dbe22725591a3b7453d85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Chalk?= Date: Wed, 5 Mar 2025 15:59:20 +0100 Subject: [PATCH 16/30] fix(utils): ignore non-json lines in fromJsonLines utility --- packages/utils/src/lib/transform.ts | 14 ++++++++++++-- packages/utils/src/lib/transform.unit.test.ts | 11 +++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/utils/src/lib/transform.ts b/packages/utils/src/lib/transform.ts index f33aaa40e..86caf9aef 100644 --- a/packages/utils/src/lib/transform.ts +++ b/packages/utils/src/lib/transform.ts @@ -114,9 +114,19 @@ export function toUnixNewlines(text: string): string { return platform() === 'win32' ? text.replace(/\r\n/g, '\n') : text; } -export function fromJsonLines(jsonLines: string) { +export function fromJsonLines(jsonLines: string) { const unifiedNewLines = toUnixNewlines(jsonLines).trim(); - return JSON.parse(`[${unifiedNewLines.split('\n').join(',')}]`) as T; + const invalid = Symbol('invalid json'); + return unifiedNewLines + .split('\n') + .map(line => { + try { + return JSON.parse(line); + } catch { + return invalid; + } + }) + .filter(line => line !== invalid) as T; } export function toJsonLines(json: T[]) { diff --git a/packages/utils/src/lib/transform.unit.test.ts b/packages/utils/src/lib/transform.unit.test.ts index d4ad2cfcf..b72982e3d 100644 --- a/packages/utils/src/lib/transform.unit.test.ts +++ b/packages/utils/src/lib/transform.unit.test.ts @@ -258,6 +258,17 @@ describe('JSON lines format', () => { expect(fromJsonLines(jsonLines)).toEqual([head, body]); }); + + it('should ignore non-JSON lines', () => { + const jsonLines = [ + '(node:346640) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.', + '(Use `node --trace-deprecation ...` to show where the warning was created)', + JSON.stringify(head), + JSON.stringify(body), + ].join('\n'); + + expect(fromJsonLines(jsonLines)).toEqual([head, body]); + }); }); describe('toJsonLines', () => { From 9e68eb12b570e50d991206ffd467ca6288b1df2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Chalk?= Date: Wed, 5 Mar 2025 16:01:03 +0100 Subject: [PATCH 17/30] fix(plugin-js-packages): ignore non-empty stderr --- packages/plugin-js-packages/src/lib/runner/index.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/plugin-js-packages/src/lib/runner/index.ts b/packages/plugin-js-packages/src/lib/runner/index.ts index e2784e30e..f8bca562d 100644 --- a/packages/plugin-js-packages/src/lib/runner/index.ts +++ b/packages/plugin-js-packages/src/lib/runner/index.ts @@ -78,18 +78,13 @@ async function processOutdated( packageJsonPaths: PackageJsonPaths, ) { const pm = packageManagers[id]; - const { stdout, stderr } = await executeProcess({ + const { stdout } = await executeProcess({ command: pm.command, args: pm.outdated.commandArgs, cwd: process.cwd(), ignoreExitCode: true, // outdated returns exit code 1 when outdated dependencies are found }); - // Successful outdated check has empty stderr - if (stderr) { - throw new Error(`JS packages plugin: outdated error: ${stderr}`); - } - // Locate all package.json files in the repository if not provided const finalPaths = Array.isArray(packageJsonPaths) ? packageJsonPaths @@ -122,16 +117,12 @@ async function processAudit( const auditResults = await Promise.allSettled( compatibleAuditDepGroups.map( async (depGroup): Promise<[DependencyGroup, AuditResult]> => { - const { stdout, stderr } = await executeProcess({ + const { stdout } = await executeProcess({ command: pm.command, args: pm.audit.getCommandArgs(depGroup), cwd: process.cwd(), ignoreExitCode: pm.audit.ignoreExitCode, }); - // Successful audit check has empty stderr - if (stderr) { - throw new Error(`JS packages plugin: audit error: ${stderr}`); - } return [depGroup, pm.audit.unifyResult(stdout)]; }, ), From 88fd037087f65b066e81ec6b20f6dbe41d26c54c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Chalk?= Date: Wed, 5 Mar 2025 16:44:44 +0100 Subject: [PATCH 18/30] release: 0.64.2 [skip ci] --- CHANGELOG.md | 13 +++++++++++++ packages/ci/package.json | 6 +++--- packages/cli/package.json | 8 ++++---- packages/core/package.json | 6 +++--- packages/create-cli/package.json | 6 +++--- packages/models/package.json | 2 +- packages/nx-plugin/package.json | 6 +++--- packages/plugin-coverage/package.json | 6 +++--- packages/plugin-eslint/package.json | 6 +++--- packages/plugin-js-packages/package.json | 6 +++--- packages/plugin-jsdocs/package.json | 6 +++--- packages/plugin-lighthouse/package.json | 6 +++--- packages/utils/package.json | 4 ++-- 13 files changed, 47 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fe4153ba..646637653 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.64.2 (2025-03-05) + +### 🩹 Fixes + +- update nx-verdaccio pkg ([#954](https://github.com/code-pushup/cli/pull/954)) +- **plugin-js-packages:** ignore non-empty stderr ([7936a00c](https://github.com/code-pushup/cli/commit/7936a00c)) +- **utils:** ignore non-json lines in fromJsonLines utility ([7886c572](https://github.com/code-pushup/cli/commit/7886c572)) + +### ❀️ Thank You + +- MatΔ›j Chalk +- Michael Hladky @BioPhoton + ## 0.64.1 (2025-03-04) ### 🩹 Fixes diff --git a/packages/ci/package.json b/packages/ci/package.json index fb9846487..848409d64 100644 --- a/packages/ci/package.json +++ b/packages/ci/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/ci", - "version": "0.64.1", + "version": "0.64.2", "description": "CI automation logic for Code PushUp (provider-agnostic)", "license": "MIT", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/ci#readme", @@ -26,8 +26,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.1", - "@code-pushup/utils": "0.64.1", + "@code-pushup/models": "0.64.2", + "@code-pushup/utils": "0.64.2", "glob": "^10.4.5", "simple-git": "^3.20.0", "yaml": "^2.5.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index b4df8398c..8dd956e26 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/cli", - "version": "0.64.1", + "version": "0.64.2", "license": "MIT", "description": "A CLI to run all kinds of code quality measurements to align your team with company goals", "homepage": "https://code-pushup.dev", @@ -42,9 +42,9 @@ "code-pushup": "./src/index.js" }, "dependencies": { - "@code-pushup/models": "0.64.1", - "@code-pushup/core": "0.64.1", - "@code-pushup/utils": "0.64.1", + "@code-pushup/models": "0.64.2", + "@code-pushup/core": "0.64.2", + "@code-pushup/utils": "0.64.2", "yargs": "^17.7.2", "ansis": "^3.3.0", "simple-git": "^3.20.0" diff --git a/packages/core/package.json b/packages/core/package.json index 18ea97021..5d58e81c8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/core", - "version": "0.64.1", + "version": "0.64.2", "license": "MIT", "description": "Core business logic for the used by the Code PushUp CLI", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/core#readme", @@ -39,8 +39,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.1", - "@code-pushup/utils": "0.64.1", + "@code-pushup/models": "0.64.2", + "@code-pushup/utils": "0.64.2", "ansis": "^3.3.0" }, "peerDependencies": { diff --git a/packages/create-cli/package.json b/packages/create-cli/package.json index 24b144d7a..8460da227 100644 --- a/packages/create-cli/package.json +++ b/packages/create-cli/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/create-cli", - "version": "0.64.1", + "version": "0.64.2", "license": "MIT", "bin": "index.js", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/create-cli#readme", @@ -26,7 +26,7 @@ }, "type": "module", "dependencies": { - "@code-pushup/nx-plugin": "0.64.1", - "@code-pushup/utils": "0.64.1" + "@code-pushup/nx-plugin": "0.64.2", + "@code-pushup/utils": "0.64.2" } } diff --git a/packages/models/package.json b/packages/models/package.json index e764d76d5..1aed38e97 100644 --- a/packages/models/package.json +++ b/packages/models/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/models", - "version": "0.64.1", + "version": "0.64.2", "license": "MIT", "description": "Model definitions and validators for the Code PushUp CLI", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/models#readme", diff --git a/packages/nx-plugin/package.json b/packages/nx-plugin/package.json index e616c78c0..ee6c9c517 100644 --- a/packages/nx-plugin/package.json +++ b/packages/nx-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/nx-plugin", - "version": "0.64.1", + "version": "0.64.2", "license": "MIT", "description": "Nx plugin to integrate the Code PushUp CLI into your workspace πŸ› οΈ", "publishConfig": { @@ -32,8 +32,8 @@ "generators": "./generators.json", "executors": "./executors.json", "dependencies": { - "@code-pushup/models": "0.64.1", - "@code-pushup/utils": "0.64.1", + "@code-pushup/models": "0.64.2", + "@code-pushup/utils": "0.64.2", "@nx/devkit": "^17.0.0 || ^18.0.0 || ^19.0.0", "ansis": "^3.3.0", "nx": "^17.0.0 || ^18.0.0 || ^19.0.0", diff --git a/packages/plugin-coverage/package.json b/packages/plugin-coverage/package.json index b2f96ca8e..7048142df 100644 --- a/packages/plugin-coverage/package.json +++ b/packages/plugin-coverage/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/coverage-plugin", - "version": "0.64.1", + "version": "0.64.2", "description": "Code PushUp plugin for tracking code coverage β˜‚", "license": "MIT", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-coverage#readme", @@ -34,8 +34,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.1", - "@code-pushup/utils": "0.64.1", + "@code-pushup/models": "0.64.2", + "@code-pushup/utils": "0.64.2", "ansis": "^3.3.0", "parse-lcov": "^1.0.4", "yargs": "^17.7.2", diff --git a/packages/plugin-eslint/package.json b/packages/plugin-eslint/package.json index 0f2fbe61d..b58bd12ec 100644 --- a/packages/plugin-eslint/package.json +++ b/packages/plugin-eslint/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/eslint-plugin", - "version": "0.64.1", + "version": "0.64.2", "license": "MIT", "description": "Code PushUp plugin for detecting problems in source code using ESLint.πŸ“‹", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-eslint#readme", @@ -38,8 +38,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/utils": "0.64.1", - "@code-pushup/models": "0.64.1", + "@code-pushup/utils": "0.64.2", + "@code-pushup/models": "0.64.2", "yargs": "^17.7.2", "zod": "^3.22.4" }, diff --git a/packages/plugin-js-packages/package.json b/packages/plugin-js-packages/package.json index c12db1999..12ba35d63 100644 --- a/packages/plugin-js-packages/package.json +++ b/packages/plugin-js-packages/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/js-packages-plugin", - "version": "0.64.1", + "version": "0.64.2", "description": "Code PushUp plugin for JavaScript packages πŸ›‘οΈ", "license": "MIT", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-js-packages#readme", @@ -37,8 +37,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.1", - "@code-pushup/utils": "0.64.1", + "@code-pushup/models": "0.64.2", + "@code-pushup/utils": "0.64.2", "build-md": "^0.4.1", "semver": "^7.6.0", "yargs": "^17.7.2", diff --git a/packages/plugin-jsdocs/package.json b/packages/plugin-jsdocs/package.json index 6c1d54e21..1d9df3d0d 100644 --- a/packages/plugin-jsdocs/package.json +++ b/packages/plugin-jsdocs/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/jsdocs-plugin", - "version": "0.64.1", + "version": "0.64.2", "description": "Code PushUp plugin for tracking documentation coverage πŸ“š", "license": "MIT", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-jsdocs#readme", @@ -35,8 +35,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.1", - "@code-pushup/utils": "0.64.1", + "@code-pushup/models": "0.64.2", + "@code-pushup/utils": "0.64.2", "zod": "^3.22.4", "ts-morph": "^24.0.0" } diff --git a/packages/plugin-lighthouse/package.json b/packages/plugin-lighthouse/package.json index 495c905fe..13cc8a2b7 100644 --- a/packages/plugin-lighthouse/package.json +++ b/packages/plugin-lighthouse/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/lighthouse-plugin", - "version": "0.64.1", + "version": "0.64.2", "license": "MIT", "description": "Code PushUp plugin for measuring web performance and quality with Lighthouse πŸ”₯", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-lighthouse#readme", @@ -36,8 +36,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.1", - "@code-pushup/utils": "0.64.1", + "@code-pushup/models": "0.64.2", + "@code-pushup/utils": "0.64.2", "ansis": "^3.3.0", "chrome-launcher": "^1.1.1", "lighthouse": "^12.0.0", diff --git a/packages/utils/package.json b/packages/utils/package.json index 7df5dfbee..9c2b7a822 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/utils", - "version": "0.64.1", + "version": "0.64.2", "description": "Low-level utilities (helper functions, etc.) used by Code PushUp CLI", "license": "MIT", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/utils#readme", @@ -27,7 +27,7 @@ "node": ">=17.0.0" }, "dependencies": { - "@code-pushup/models": "0.64.1", + "@code-pushup/models": "0.64.2", "@isaacs/cliui": "^8.0.2", "@poppinss/cliui": "^6.4.0", "ansis": "^3.3.0", From 00aae50cca16bbcaa94fc9739d8f188f130ac4b2 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Wed, 5 Mar 2025 16:45:53 +0100 Subject: [PATCH 19/30] feat(utils): add score filter to md report generation (#956) --- ...-report-category-section.unit.test.ts.snap | 18 +++ ...=> generate-md-report-category-section.ts} | 37 +++--- ...te-md-report-category-section.unit.test.ts | 106 +++++++++++++++++- .../src/lib/reports/generate-md-report.ts | 23 +++- .../reports/generate-md-report.unit.test.ts | 76 +++++++++++++ packages/utils/src/lib/reports/types.ts | 6 +- packages/utils/src/lib/reports/utils.ts | 8 ++ .../utils/src/lib/reports/utils.unit.test.ts | 13 +++ 8 files changed, 267 insertions(+), 20 deletions(-) rename packages/utils/src/lib/reports/{generate-md-report-categoy-section.ts => generate-md-report-category-section.ts} (78%) diff --git a/packages/utils/src/lib/reports/__snapshots__/generate-md-report-category-section.unit.test.ts.snap b/packages/utils/src/lib/reports/__snapshots__/generate-md-report-category-section.unit.test.ts.snap index d8b4fde36..191eaf9ab 100644 --- a/packages/utils/src/lib/reports/__snapshots__/generate-md-report-category-section.unit.test.ts.snap +++ b/packages/utils/src/lib/reports/__snapshots__/generate-md-report-category-section.unit.test.ts.snap @@ -45,6 +45,17 @@ exports[`categoriesDetailsSection > should render complete categories details 1` " `; +exports[`categoriesDetailsSection > should render filtered categories details > filtered 1`] = ` +"## 🏷 Categories + +### Bug Prevention + +🟒 Score: **100** βœ… + +- 🟩 [No let](#no-let-eslint) (_Eslint_) - **0** +" +`; + exports[`categoriesOverviewSection > should render complete categories table 1`] = ` "| 🏷 Category | ⭐ Score | πŸ›‘ Audits | | :-------------------------------- | :-------: | :-------: | @@ -54,6 +65,13 @@ exports[`categoriesOverviewSection > should render complete categories table 1`] " `; +exports[`categoriesOverviewSection > should render filtered categories table 1`] = ` +"| 🏷 Category | ⭐ Score | πŸ›‘ Audits | +| :-------------------------------- | :--------: | :-------: | +| [Bug Prevention](#bug-prevention) | 🟒 **100** | 1 | +" +`; + exports[`categoriesOverviewSection > should render targetScore icon "❌" if score fails 1`] = ` "| 🏷 Category | ⭐ Score | πŸ›‘ Audits | | :-------------------------------- | :---------: | :-------: | diff --git a/packages/utils/src/lib/reports/generate-md-report-categoy-section.ts b/packages/utils/src/lib/reports/generate-md-report-category-section.ts similarity index 78% rename from packages/utils/src/lib/reports/generate-md-report-categoy-section.ts rename to packages/utils/src/lib/reports/generate-md-report-category-section.ts index 063bc30e3..5cac4a477 100644 --- a/packages/utils/src/lib/reports/generate-md-report-categoy-section.ts +++ b/packages/utils/src/lib/reports/generate-md-report-category-section.ts @@ -4,17 +4,19 @@ import { slugify } from '../formatting.js'; import { HIERARCHY } from '../text-formats/index.js'; import { metaDescription } from './formatting.js'; import { getSortableAuditByRef, getSortableGroupByRef } from './sorting.js'; -import type { ScoredGroup, ScoredReport } from './types.js'; +import type { ScoreFilter, ScoredGroup, ScoredReport } from './types.js'; import { countCategoryAudits, formatReportScore, getPluginNameFromSlug, + scoreFilter, scoreMarker, targetScoreIcon, } from './utils.js'; export function categoriesOverviewSection( report: Required>, + options?: ScoreFilter, ): MarkdownDocument { const { categories, plugins } = report; return new MarkdownDocument().table( @@ -23,26 +25,29 @@ export function categoriesOverviewSection( { heading: '⭐ Score', alignment: 'center' }, { heading: 'πŸ›‘ Audits', alignment: 'center' }, ], - categories.map(({ title, refs, score, isBinary }) => [ - // @TODO refactor `isBinary: boolean` to `targetScore: number` #713 - // The heading "ID" is inferred from the heading text in Markdown. - md.link(`#${slugify(title)}`, title), - md`${scoreMarker(score)} ${md.bold( - formatReportScore(score), - )}${binaryIconSuffix(score, isBinary)}`, - countCategoryAudits(refs, plugins).toString(), - ]), + categories + .filter(scoreFilter(options)) + .map(({ title, refs, score, isBinary }) => [ + // @TODO refactor `isBinary: boolean` to `targetScore: number` #713 + // The heading "ID" is inferred from the heading text in Markdown. + md.link(`#${slugify(title)}`, title), + md`${scoreMarker(score)} ${md.bold( + formatReportScore(score), + )}${binaryIconSuffix(score, isBinary)}`, + countCategoryAudits(refs, plugins).toString(), + ]), ); } export function categoriesDetailsSection( report: Required>, + options?: ScoreFilter, ): MarkdownDocument { const { categories, plugins } = report; - + const isScoreDisplayed = scoreFilter(options); return new MarkdownDocument() .heading(HIERARCHY.level_2, '🏷 Categories') - .$foreach(categories, (doc, category) => + .$foreach(categories.filter(isScoreDisplayed), (doc, category) => doc .heading(HIERARCHY.level_3, category.title) .paragraph(metaDescription(category)) @@ -63,13 +68,17 @@ export function categoriesDetailsSection( ), ); const pluginTitle = getPluginNameFromSlug(ref.plugin, plugins); - return categoryGroupItem(group, groupAudits, pluginTitle); + return isScoreDisplayed(group) + ? categoryGroupItem(group, groupAudits, pluginTitle) + : ''; } // Add audit details else { const audit = getSortableAuditByRef(ref, plugins); const pluginTitle = getPluginNameFromSlug(ref.plugin, plugins); - return categoryRef(audit, pluginTitle); + return isScoreDisplayed(audit) + ? categoryRef(audit, pluginTitle) + : ''; } }), ), diff --git a/packages/utils/src/lib/reports/generate-md-report-category-section.unit.test.ts b/packages/utils/src/lib/reports/generate-md-report-category-section.unit.test.ts index 6afaca2f2..01b00876e 100644 --- a/packages/utils/src/lib/reports/generate-md-report-category-section.unit.test.ts +++ b/packages/utils/src/lib/reports/generate-md-report-category-section.unit.test.ts @@ -6,7 +6,7 @@ import { categoriesOverviewSection, categoryGroupItem, categoryRef, -} from './generate-md-report-categoy-section.js'; +} from './generate-md-report-category-section.js'; import type { ScoredGroup, ScoredReport } from './types.js'; // === Categories Overview Section @@ -49,6 +49,48 @@ describe('categoriesOverviewSection', () => { ).toMatchSnapshot(); }); + it('should render filtered categories table', () => { + expect( + categoriesOverviewSection( + { + plugins: [ + { + slug: 'eslint', + title: 'Eslint', + }, + { + slug: 'lighthouse', + title: 'Lighthouse', + }, + ], + categories: [ + { + slug: 'bug-prevention', + title: 'Bug Prevention', + score: 1, + refs: [{ slug: 'no-let', type: 'audit' }], + }, + { + slug: 'performance', + title: 'Performance', + score: 0.74, + refs: [{ slug: 'largest-contentful-paint', type: 'audit' }], + }, + { + slug: 'typescript', + title: 'Typescript', + score: 0.14, + refs: [{ slug: 'no-any', type: 'audit' }], + }, + ], + } as Required>, + { + isScoreListed: score => score === 1, + }, + ).toString(), + ).toMatchSnapshot(); + }); + it('should render targetScore icon "❌" if score fails', () => { expect( categoriesOverviewSection({ @@ -215,6 +257,68 @@ describe('categoriesDetailsSection', () => { ).toMatchSnapshot(); }); + it('should render filtered categories details', () => { + expect( + categoriesDetailsSection( + { + plugins: [ + { + slug: 'eslint', + title: 'Eslint', + audits: [ + { slug: 'no-let', title: 'No let', score: 1, value: 0 }, + { slug: 'no-any', title: 'No any', score: 0, value: 5 }, + ], + }, + { + slug: 'lighthouse', + title: 'Lighthouse', + audits: [ + { + slug: 'largest-contentful-paint', + title: 'Largest Contentful Paint', + score: 0.7, + value: 2905, + }, + ], + }, + ], + categories: [ + { + slug: 'bug-prevention', + title: 'Bug Prevention', + score: 1, + isBinary: true, + refs: [{ slug: 'no-let', type: 'audit', plugin: 'eslint' }], + }, + { + slug: 'performance', + title: 'Performance', + score: 0.74, + refs: [ + { + slug: 'largest-contentful-paint', + type: 'audit', + plugin: 'lighthouse', + }, + ], + }, + { + slug: 'typescript', + title: 'Typescript', + score: 0.14, + isBinary: true, + refs: [{ slug: 'no-any', type: 'audit', plugin: 'eslint' }], + }, + ], + } as Required>, + { + isScoreListed: score => score === 1, + }, + ).toString(), + ).toMatchSnapshot('filtered'); + }); + it('should render categories details and add "❌" when isBinary is failing', () => { expect( categoriesDetailsSection({ diff --git a/packages/utils/src/lib/reports/generate-md-report.ts b/packages/utils/src/lib/reports/generate-md-report.ts index 3ae8b1c7d..c452b22f6 100644 --- a/packages/utils/src/lib/reports/generate-md-report.ts +++ b/packages/utils/src/lib/reports/generate-md-report.ts @@ -16,9 +16,14 @@ import { import { categoriesDetailsSection, categoriesOverviewSection, -} from './generate-md-report-categoy-section.js'; +} from './generate-md-report-category-section.js'; import type { MdReportOptions, ScoredReport } from './types.js'; -import { formatReportScore, scoreMarker, severityMarker } from './utils.js'; +import { + formatReportScore, + scoreFilter, + scoreMarker, + severityMarker, +} from './utils.js'; export function auditDetailsAuditValue({ score, @@ -30,6 +35,10 @@ export function auditDetailsAuditValue({ )} (score: ${formatReportScore(score)})`; } +/** + * Check if the report has categories. + * @param report + */ function hasCategories( report: ScoredReport, ): report is ScoredReport & Required> { @@ -44,7 +53,10 @@ export function generateMdReport( .heading(HIERARCHY.level_1, REPORT_HEADLINE_TEXT) .$concat( ...(hasCategories(report) - ? [categoriesOverviewSection(report), categoriesDetailsSection(report)] + ? [ + categoriesOverviewSection(report, options), + categoriesDetailsSection(report, options), + ] : []), auditsSection(report, options), aboutSection(report), @@ -110,11 +122,14 @@ export function auditsSection( { plugins }: Pick, options?: MdReportOptions, ): MarkdownDocument { + const isScoreDisplayed = scoreFilter(options); return new MarkdownDocument() .heading(HIERARCHY.level_2, 'πŸ›‘οΈ Audits') .$foreach( plugins.flatMap(plugin => - plugin.audits.map(audit => ({ ...audit, plugin })), + plugin.audits + .filter(isScoreDisplayed) + .map(audit => ({ ...audit, plugin })), ), (doc, { plugin, ...audit }) => { const auditTitle = `${audit.title} (${plugin.title})`; diff --git a/packages/utils/src/lib/reports/generate-md-report.unit.test.ts b/packages/utils/src/lib/reports/generate-md-report.unit.test.ts index bc870837f..671f6b4b8 100644 --- a/packages/utils/src/lib/reports/generate-md-report.unit.test.ts +++ b/packages/utils/src/lib/reports/generate-md-report.unit.test.ts @@ -47,6 +47,54 @@ const baseScoredReport = { ], } as ScoredReport; +const baseScoredReport2 = { + date: '2025.01.01', + duration: 4200, + version: 'v1.0.0', + commit: { + message: 'ci: update action', + author: 'Michael ', + date: new Date('2025.01.01'), + hash: '535b8e9e557336618a764f3fa45609d224a62837', + }, + plugins: [ + { + slug: 'lighthouse', + version: '1.0.1', + duration: 15_365, + title: 'Lighthouse', + audits: [ + { + slug: 'largest-contentful-paint', + title: 'Largest Contentful Paint', + score: 0.6, + value: 2700, + }, + { + slug: 'cumulative-layout-shift', + title: 'Cumulative Layout Shift', + score: 1, + value: 0, + }, + ], + }, + ], + categories: [ + { + title: 'Speed', + slug: 'speed', + score: 0.93, + refs: [{ slug: 'largest-contentful-paint', plugin: 'lighthouse' }], + }, + { + title: 'Visual Stability', + slug: 'visual-stability', + score: 1, + refs: [{ slug: 'cumulative-layout-shift', plugin: 'lighthouse' }], + }, + ], +} as ScoredReport; + // === Audit Details describe('auditDetailsAuditValue', () => { @@ -359,6 +407,22 @@ describe('auditsSection', () => { ).toMatch('🟩 **0** (score: 100)'); }); + it('should render filtered result', () => { + const auditSection = auditsSection( + { + plugins: [ + { audits: [{ score: 1, value: 0 }] }, + { audits: [{ score: 0, value: 1 }] }, + ], + } as ScoredReport, + { + isScoreListed: (score: number) => score === 1, + }, + ).toString(); + expect(auditSection).toMatch('(score: 100)'); + expect(auditSection).not.toMatch('(score: 0)'); + }); + it('should render audit details', () => { const md = auditsSection({ plugins: [ @@ -580,6 +644,18 @@ describe('generateMdReport', () => { expect(md).toMatch('Made with ❀ by [Code PushUp]'); }); + it('should render sections filtered by isScoreListed of the report', () => { + const md = generateMdReport(baseScoredReport2, { + isScoreListed: (score: number) => score === 1, + }); + + expect(md).toMatch('Visual Stability'); + expect(md).toMatch('Cumulative Layout Shift'); + + expect(md).not.toMatch('Speed'); + expect(md).not.toMatch('Largest Contentful Paint'); + }); + it('should skip categories section when categories are missing', () => { const md = generateMdReport({ ...baseScoredReport, categories: undefined }); expect(md).not.toMatch('## 🏷 Categories'); diff --git a/packages/utils/src/lib/reports/types.ts b/packages/utils/src/lib/reports/types.ts index 1c89d5986..a79059db0 100644 --- a/packages/utils/src/lib/reports/types.ts +++ b/packages/utils/src/lib/reports/types.ts @@ -32,7 +32,11 @@ export type SortableAuditReport = AuditReport & { export type DiffOutcome = 'positive' | 'negative' | 'mixed' | 'unchanged'; -export type MdReportOptions = Pick; +export type ScoreFilter = { + isScoreListed?: (score: number) => boolean; +}; + +export type MdReportOptions = Pick & ScoreFilter; export const SUPPORTED_ENVIRONMENTS = [ 'vscode', diff --git a/packages/utils/src/lib/reports/utils.ts b/packages/utils/src/lib/reports/utils.ts index 7dfaba833..fbb0aec0f 100644 --- a/packages/utils/src/lib/reports/utils.ts +++ b/packages/utils/src/lib/reports/utils.ts @@ -10,11 +10,19 @@ import type { } from '@code-pushup/models'; import { SCORE_COLOR_RANGE } from './constants.js'; import type { + ScoreFilter, ScoredReport, SortableAuditReport, SortableGroup, } from './types.js'; +export function scoreFilter( + options?: ScoreFilter, +) { + const { isScoreListed = () => true } = options ?? {}; + return ({ score }: T) => isScoreListed(score); +} + export function formatReportScore(score: number): string { const scaledScore = score * 100; const roundedScore = Math.round(scaledScore); diff --git a/packages/utils/src/lib/reports/utils.unit.test.ts b/packages/utils/src/lib/reports/utils.unit.test.ts index 965807a35..087edb82a 100644 --- a/packages/utils/src/lib/reports/utils.unit.test.ts +++ b/packages/utils/src/lib/reports/utils.unit.test.ts @@ -26,11 +26,24 @@ import { formatValueChange, getPluginNameFromSlug, roundValue, + scoreFilter, scoreMarker, severityMarker, targetScoreIcon, } from './utils.js'; +describe('scoreFilter', () => { + it('should not filter by score if no options are passed', () => { + expect(scoreFilter()({ score: 0 })).toBe(true); + }); + + it('should filter by score if options are passed', () => { + expect( + scoreFilter({ isScoreListed: score => score === 0.5 })({ score: 0 }), + ).toBe(false); + }); +}); + describe('formatReportScore', () => { it.each([ [0, '0'], From 76c2b475bc218c680eea9028973b942da64a1e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Chalk?= Date: Wed, 5 Mar 2025 17:45:02 +0100 Subject: [PATCH 20/30] release: 0.65.0 [skip ci] --- CHANGELOG.md | 10 ++++++++++ packages/ci/package.json | 6 +++--- packages/cli/package.json | 8 ++++---- packages/core/package.json | 6 +++--- packages/create-cli/package.json | 6 +++--- packages/models/package.json | 2 +- packages/nx-plugin/package.json | 6 +++--- packages/plugin-coverage/package.json | 6 +++--- packages/plugin-eslint/package.json | 6 +++--- packages/plugin-js-packages/package.json | 6 +++--- packages/plugin-jsdocs/package.json | 6 +++--- packages/plugin-lighthouse/package.json | 6 +++--- packages/utils/package.json | 4 ++-- 13 files changed, 44 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 646637653..5a2ae82e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.65.0 (2025-03-05) + +### πŸš€ Features + +- **utils:** add score filter to md report generation ([#956](https://github.com/code-pushup/cli/pull/956)) + +### ❀️ Thank You + +- Michael Hladky @BioPhoton + ## 0.64.2 (2025-03-05) ### 🩹 Fixes diff --git a/packages/ci/package.json b/packages/ci/package.json index 848409d64..a0d8d4200 100644 --- a/packages/ci/package.json +++ b/packages/ci/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/ci", - "version": "0.64.2", + "version": "0.65.0", "description": "CI automation logic for Code PushUp (provider-agnostic)", "license": "MIT", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/ci#readme", @@ -26,8 +26,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.2", - "@code-pushup/utils": "0.64.2", + "@code-pushup/models": "0.65.0", + "@code-pushup/utils": "0.65.0", "glob": "^10.4.5", "simple-git": "^3.20.0", "yaml": "^2.5.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index 8dd956e26..aa65ece68 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/cli", - "version": "0.64.2", + "version": "0.65.0", "license": "MIT", "description": "A CLI to run all kinds of code quality measurements to align your team with company goals", "homepage": "https://code-pushup.dev", @@ -42,9 +42,9 @@ "code-pushup": "./src/index.js" }, "dependencies": { - "@code-pushup/models": "0.64.2", - "@code-pushup/core": "0.64.2", - "@code-pushup/utils": "0.64.2", + "@code-pushup/models": "0.65.0", + "@code-pushup/core": "0.65.0", + "@code-pushup/utils": "0.65.0", "yargs": "^17.7.2", "ansis": "^3.3.0", "simple-git": "^3.20.0" diff --git a/packages/core/package.json b/packages/core/package.json index 5d58e81c8..88bc879bd 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/core", - "version": "0.64.2", + "version": "0.65.0", "license": "MIT", "description": "Core business logic for the used by the Code PushUp CLI", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/core#readme", @@ -39,8 +39,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.2", - "@code-pushup/utils": "0.64.2", + "@code-pushup/models": "0.65.0", + "@code-pushup/utils": "0.65.0", "ansis": "^3.3.0" }, "peerDependencies": { diff --git a/packages/create-cli/package.json b/packages/create-cli/package.json index 8460da227..812de33b3 100644 --- a/packages/create-cli/package.json +++ b/packages/create-cli/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/create-cli", - "version": "0.64.2", + "version": "0.65.0", "license": "MIT", "bin": "index.js", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/create-cli#readme", @@ -26,7 +26,7 @@ }, "type": "module", "dependencies": { - "@code-pushup/nx-plugin": "0.64.2", - "@code-pushup/utils": "0.64.2" + "@code-pushup/nx-plugin": "0.65.0", + "@code-pushup/utils": "0.65.0" } } diff --git a/packages/models/package.json b/packages/models/package.json index 1aed38e97..35e5cfd92 100644 --- a/packages/models/package.json +++ b/packages/models/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/models", - "version": "0.64.2", + "version": "0.65.0", "license": "MIT", "description": "Model definitions and validators for the Code PushUp CLI", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/models#readme", diff --git a/packages/nx-plugin/package.json b/packages/nx-plugin/package.json index ee6c9c517..27b9aec84 100644 --- a/packages/nx-plugin/package.json +++ b/packages/nx-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/nx-plugin", - "version": "0.64.2", + "version": "0.65.0", "license": "MIT", "description": "Nx plugin to integrate the Code PushUp CLI into your workspace πŸ› οΈ", "publishConfig": { @@ -32,8 +32,8 @@ "generators": "./generators.json", "executors": "./executors.json", "dependencies": { - "@code-pushup/models": "0.64.2", - "@code-pushup/utils": "0.64.2", + "@code-pushup/models": "0.65.0", + "@code-pushup/utils": "0.65.0", "@nx/devkit": "^17.0.0 || ^18.0.0 || ^19.0.0", "ansis": "^3.3.0", "nx": "^17.0.0 || ^18.0.0 || ^19.0.0", diff --git a/packages/plugin-coverage/package.json b/packages/plugin-coverage/package.json index 7048142df..a95dfcdec 100644 --- a/packages/plugin-coverage/package.json +++ b/packages/plugin-coverage/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/coverage-plugin", - "version": "0.64.2", + "version": "0.65.0", "description": "Code PushUp plugin for tracking code coverage β˜‚", "license": "MIT", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-coverage#readme", @@ -34,8 +34,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.2", - "@code-pushup/utils": "0.64.2", + "@code-pushup/models": "0.65.0", + "@code-pushup/utils": "0.65.0", "ansis": "^3.3.0", "parse-lcov": "^1.0.4", "yargs": "^17.7.2", diff --git a/packages/plugin-eslint/package.json b/packages/plugin-eslint/package.json index b58bd12ec..d48972c10 100644 --- a/packages/plugin-eslint/package.json +++ b/packages/plugin-eslint/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/eslint-plugin", - "version": "0.64.2", + "version": "0.65.0", "license": "MIT", "description": "Code PushUp plugin for detecting problems in source code using ESLint.πŸ“‹", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-eslint#readme", @@ -38,8 +38,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/utils": "0.64.2", - "@code-pushup/models": "0.64.2", + "@code-pushup/utils": "0.65.0", + "@code-pushup/models": "0.65.0", "yargs": "^17.7.2", "zod": "^3.22.4" }, diff --git a/packages/plugin-js-packages/package.json b/packages/plugin-js-packages/package.json index 12ba35d63..f16262f85 100644 --- a/packages/plugin-js-packages/package.json +++ b/packages/plugin-js-packages/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/js-packages-plugin", - "version": "0.64.2", + "version": "0.65.0", "description": "Code PushUp plugin for JavaScript packages πŸ›‘οΈ", "license": "MIT", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-js-packages#readme", @@ -37,8 +37,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.2", - "@code-pushup/utils": "0.64.2", + "@code-pushup/models": "0.65.0", + "@code-pushup/utils": "0.65.0", "build-md": "^0.4.1", "semver": "^7.6.0", "yargs": "^17.7.2", diff --git a/packages/plugin-jsdocs/package.json b/packages/plugin-jsdocs/package.json index 1d9df3d0d..49ca6ec48 100644 --- a/packages/plugin-jsdocs/package.json +++ b/packages/plugin-jsdocs/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/jsdocs-plugin", - "version": "0.64.2", + "version": "0.65.0", "description": "Code PushUp plugin for tracking documentation coverage πŸ“š", "license": "MIT", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-jsdocs#readme", @@ -35,8 +35,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.2", - "@code-pushup/utils": "0.64.2", + "@code-pushup/models": "0.65.0", + "@code-pushup/utils": "0.65.0", "zod": "^3.22.4", "ts-morph": "^24.0.0" } diff --git a/packages/plugin-lighthouse/package.json b/packages/plugin-lighthouse/package.json index 13cc8a2b7..c7884ca25 100644 --- a/packages/plugin-lighthouse/package.json +++ b/packages/plugin-lighthouse/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/lighthouse-plugin", - "version": "0.64.2", + "version": "0.65.0", "license": "MIT", "description": "Code PushUp plugin for measuring web performance and quality with Lighthouse πŸ”₯", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-lighthouse#readme", @@ -36,8 +36,8 @@ }, "type": "module", "dependencies": { - "@code-pushup/models": "0.64.2", - "@code-pushup/utils": "0.64.2", + "@code-pushup/models": "0.65.0", + "@code-pushup/utils": "0.65.0", "ansis": "^3.3.0", "chrome-launcher": "^1.1.1", "lighthouse": "^12.0.0", diff --git a/packages/utils/package.json b/packages/utils/package.json index 9c2b7a822..3b1d8ed24 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@code-pushup/utils", - "version": "0.64.2", + "version": "0.65.0", "description": "Low-level utilities (helper functions, etc.) used by Code PushUp CLI", "license": "MIT", "homepage": "https://github.com/code-pushup/cli/tree/main/packages/utils#readme", @@ -27,7 +27,7 @@ "node": ">=17.0.0" }, "dependencies": { - "@code-pushup/models": "0.64.2", + "@code-pushup/models": "0.65.0", "@isaacs/cliui": "^8.0.2", "@poppinss/cliui": "^6.4.0", "ansis": "^3.3.0", From 24374977f6daa6c2893098ab76da796dbe94fab8 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 10 Mar 2025 17:18:26 +0100 Subject: [PATCH 21/30] fix: adjust logic --- .../src/executors/cli/executor.unit.test.ts | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 packages/nx-plugin/src/executors/cli/executor.unit.test.ts diff --git a/packages/nx-plugin/src/executors/cli/executor.unit.test.ts b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts new file mode 100644 index 000000000..77a81a6f0 --- /dev/null +++ b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts @@ -0,0 +1,109 @@ +import { logger } from '@nx/devkit'; +import { execSync } from 'node:child_process'; +import { afterEach, expect, vi } from 'vitest'; +import { executorContext } from '@code-pushup/test-nx-utils'; +import { MEMFS_VOLUME } from '@code-pushup/test-utils'; +import runAutorunExecutor from './executor.js'; + +vi.mock('node:child_process', async () => { + const actual = await vi.importActual('node:child_process'); + + return { + ...actual, + execSync: vi.fn((command: string) => { + if (command.includes('THROW_ERROR')) { + throw new Error(command); + } + }), + }; +}); + +describe('runAutorunExecutor', () => { + const loggerInfoSpy = vi.spyOn(logger, 'info'); + const loggerWarnSpy = vi.spyOn(logger, 'warn'); + + afterEach(() => { + loggerWarnSpy.mockReset(); + loggerInfoSpy.mockReset(); + }); + + it('should call execSync with return result', async () => { + const output = await runAutorunExecutor({}, executorContext('utils')); + expect(output.success).toBe(true); + expect(output.command).toMatch('npx @code-pushup/cli'); + // eslint-disable-next-line n/no-sync + expect(execSync).toHaveBeenCalledWith( + expect.stringContaining('npx @code-pushup/cli'), + { cwd: MEMFS_VOLUME }, + ); + }); + + it('should normalize context', async () => { + const output = await runAutorunExecutor( + {}, + { + ...executorContext('utils'), + cwd: 'cwd-form-context', + }, + ); + expect(output.success).toBe(true); + expect(output.command).toMatch('utils'); + // eslint-disable-next-line n/no-sync + expect(execSync).toHaveBeenCalledWith(expect.stringContaining('utils'), { + cwd: 'cwd-form-context', + }); + }); + + it('should process executorOptions', async () => { + const output = await runAutorunExecutor( + { persist: { filename: 'REPORT' } }, + executorContext('testing-utils'), + ); + expect(output.success).toBe(true); + expect(output.command).toMatch('--persist.filename="REPORT"'); + }); + + it('should create command from context, options and arguments', async () => { + vi.stubEnv('CP_PROJECT', 'CLI'); + const output = await runAutorunExecutor( + { persist: { filename: 'REPORT', format: ['md', 'json'] } }, + executorContext('core'), + ); + expect(output.command).toMatch('--persist.filename="REPORT"'); + expect(output.command).toMatch( + '--persist.format="md" --persist.format="json"', + ); + expect(output.command).toMatch('--upload.project="CLI"'); + }); + + it('should log information if verbose is set', async () => { + const output = await runAutorunExecutor( + { verbose: true }, + { ...executorContext('github-action'), cwd: '' }, + ); + // eslint-disable-next-line n/no-sync + expect(execSync).toHaveBeenCalledTimes(1); + + expect(output.command).toMatch('--verbose'); + expect(loggerWarnSpy).toHaveBeenCalledTimes(0); + expect(loggerInfoSpy).toHaveBeenCalledTimes(2); + expect(loggerInfoSpy).toHaveBeenCalledWith( + expect.stringContaining(`Run CLI executor`), + ); + expect(loggerInfoSpy).toHaveBeenCalledWith( + expect.stringContaining('Command: npx @code-pushup/cli'), + ); + }); + + it('should log command if dryRun is set', async () => { + await runAutorunExecutor({ dryRun: true }, executorContext('utils')); + + expect(loggerInfoSpy).toHaveBeenCalledTimes(0); + expect(loggerWarnSpy).toHaveBeenCalledTimes(1); + expect(loggerWarnSpy).toHaveBeenCalledWith( + expect.stringContaining( + 'DryRun execution of: npx @code-pushup/cli --dryRun', + ), + ); + }); +}); From 8de356270e523ddb76e899824c09acb02c1b49bb Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Mon, 10 Mar 2025 17:19:03 +0100 Subject: [PATCH 22/30] Update packages/nx-plugin/eslint.config.js 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/nx-plugin/eslint.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/nx-plugin/eslint.config.js b/packages/nx-plugin/eslint.config.js index 937c98765..e732748e6 100644 --- a/packages/nx-plugin/eslint.config.js +++ b/packages/nx-plugin/eslint.config.js @@ -17,7 +17,6 @@ module.exports = tseslint.config( rules: { // Nx plugins don't yet support ESM: https://github.com/nrwl/nx/issues/15682 'unicorn/prefer-module': 'off', - 'n/file-extension-in-import': 'off', // used instead of verbatimModuleSyntax tsconfig flag (requires ESM) '@typescript-eslint/consistent-type-imports': [ 'warn', From f5cf751b37361b75110163570af2b6d1f6b4d983 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 10 Mar 2025 17:19:38 +0100 Subject: [PATCH 23/30] fix: wip --- packages/models/code-pushup.config.ts | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 packages/models/code-pushup.config.ts diff --git a/packages/models/code-pushup.config.ts b/packages/models/code-pushup.config.ts deleted file mode 100644 index dad38404f..000000000 --- a/packages/models/code-pushup.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { eslintCoreConfigNx } from '../../code-pushup.preset.js'; -import { mergeConfigs } from '../../dist/packages/utils/src/index.js'; - -// see: https://github.com/code-pushup/cli/blob/main/packages/models/docs/models-reference.md#coreconfig -export default mergeConfigs( - { - plugins: [], - }, - await eslintCoreConfigNx(), -); From fb846ff8beb044f421017b46ea57faf12bfae5a1 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 10 Mar 2025 17:25:05 +0100 Subject: [PATCH 24/30] fix: wip --- packages/plugin-eslint/vite.config.integration.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/plugin-eslint/vite.config.integration.ts b/packages/plugin-eslint/vite.config.integration.ts index f7c0e3b58..66b388920 100644 --- a/packages/plugin-eslint/vite.config.integration.ts +++ b/packages/plugin-eslint/vite.config.integration.ts @@ -5,6 +5,8 @@ import { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases.js export default defineConfig({ cacheDir: '../../node_modules/.vite/plugin-eslint', test: { + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + testTimeout: 25_000, reporters: ['basic'], globals: true, cache: { From 90daca539a90421415108f488b8df7d154ba6429 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 10 Mar 2025 21:56:15 +0100 Subject: [PATCH 25/30] fix: e2e tests --- .../tests/executor-cli.e2e.test.ts | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts index e5561a462..e543ccdbf 100644 --- a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts +++ b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts @@ -1,7 +1,7 @@ -import { type Tree, updateProjectConfiguration } from '@nx/devkit'; +import {type Tree, updateProjectConfiguration} from '@nx/devkit'; import path from 'node:path'; -import { readProjectConfiguration } from 'nx/src/generators/utils/project-configuration'; -import { afterEach, expect } from 'vitest'; +import {readProjectConfiguration} from 'nx/src/generators/utils/project-configuration'; +import {afterEach, expect} from 'vitest'; import { type AutorunCommandExecutorOptions, generateCodePushupConfig, @@ -17,15 +17,15 @@ import { removeColorCodes, teardownTestFolder, } from '@code-pushup/test-utils'; -import { executeProcess, readJsonFile } from '@code-pushup/utils'; -import { INLINE_PLUGIN } from './inline-plugin.js'; +import {executeProcess, readJsonFile} from '@code-pushup/utils'; +import {INLINE_PLUGIN} from './inline-plugin.js'; async function addTargetToWorkspace( tree: Tree, options: { cwd: string; project: string }, executorOptions?: AutorunCommandExecutorOptions, ) { - const { cwd, project } = options; + const {cwd, project} = options; const projectCfg = readProjectConfiguration(tree, project); updateProjectConfiguration(tree, project, { ...projectCfg, @@ -33,11 +33,11 @@ async function addTargetToWorkspace( ...projectCfg.targets, 'code-pushup': { executor: '@code-pushup/nx-plugin:cli', - ...(executorOptions && { options: executorOptions }), + ...(executorOptions && {options: executorOptions}), }, }, }); - const { root } = projectCfg; + const {root} = projectCfg; generateCodePushupConfig(tree, root, { plugins: [ { @@ -61,6 +61,10 @@ describe('executor command', () => { beforeEach(async () => { tree = await generateWorkspaceAndProject(project); + vi.stubEnv('CP_ORGANIZATION', ''); + vi.stubEnv('CP_PROJECT', ''); + vi.stubEnv('CP_SERVER', ''); + vi.stubEnv('CP_API_KEY', ''); }); afterEach(async () => { @@ -69,8 +73,8 @@ describe('executor command', () => { it('should execute no specific command by default', async () => { const cwd = path.join(testFileDir, 'execute-default-command'); - await addTargetToWorkspace(tree, { cwd, project }); - const { stdout, code } = await executeProcess({ + await addTargetToWorkspace(tree, {cwd, project}); + const {stdout, code} = await executeProcess({ command: 'npx', args: ['nx', 'run', `${project}:code-pushup`, '--dryRun'], cwd, @@ -83,9 +87,9 @@ describe('executor command', () => { it('should execute print-config executor', async () => { const cwd = path.join(testFileDir, 'execute-print-config-command'); - await addTargetToWorkspace(tree, { cwd, project }); + await addTargetToWorkspace(tree, {cwd, project}); - const { stdout, code } = await executeProcess({ + const {stdout, code} = await executeProcess({ command: 'npx', args: ['nx', 'run', `${project}:code-pushup`, 'print-config'], cwd, @@ -102,9 +106,9 @@ describe('executor command', () => { it('should execute print-config executor with api key', async () => { const cwd = path.join(testFileDir, 'execute-print-config-command'); - await addTargetToWorkspace(tree, { cwd, project }); + await addTargetToWorkspace(tree, {cwd, project}); - const { stdout, code } = await executeProcess({ + const {stdout, code} = await executeProcess({ command: 'npx', args: [ 'nx', @@ -130,7 +134,7 @@ describe('executor command', () => { const cwd = path.join(testFileDir, 'execute-collect-with-merged-options'); await addTargetToWorkspace( tree, - { cwd, project }, + {cwd, project}, { persist: { outputDir: '.reports', @@ -139,7 +143,7 @@ describe('executor command', () => { }, ); - const { stdout, code } = await executeProcess({ + const {stdout, code} = await executeProcess({ command: 'npx', args: [ 'nx', @@ -164,9 +168,9 @@ describe('executor command', () => { it('should execute collect executor and add report to sub folder named by project', async () => { const cwd = path.join(testFileDir, 'execute-collect-command'); - await addTargetToWorkspace(tree, { cwd, project }); + await addTargetToWorkspace(tree, {cwd, project}); - const { stdout, code } = await executeProcess({ + const {stdout, code} = await executeProcess({ command: 'npx', args: ['nx', 'run', `${project}:code-pushup`, 'collect'], cwd, From acbd3ab3417d16edbfb5f5266dcbe6b15752d823 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 10 Mar 2025 22:10:00 +0100 Subject: [PATCH 26/30] fix: e2e tests --- .../tests/executor-cli.e2e.test.ts | 36 +++++++++---------- .../src/executors/cli/executor.unit.test.ts | 35 ++++++++++++++++-- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts index e543ccdbf..67b2e94df 100644 --- a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts +++ b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts @@ -1,7 +1,7 @@ -import {type Tree, updateProjectConfiguration} from '@nx/devkit'; +import { type Tree, updateProjectConfiguration } from '@nx/devkit'; import path from 'node:path'; -import {readProjectConfiguration} from 'nx/src/generators/utils/project-configuration'; -import {afterEach, expect} from 'vitest'; +import { readProjectConfiguration } from 'nx/src/generators/utils/project-configuration'; +import { afterEach, expect } from 'vitest'; import { type AutorunCommandExecutorOptions, generateCodePushupConfig, @@ -17,15 +17,15 @@ import { removeColorCodes, teardownTestFolder, } from '@code-pushup/test-utils'; -import {executeProcess, readJsonFile} from '@code-pushup/utils'; -import {INLINE_PLUGIN} from './inline-plugin.js'; +import { executeProcess, readJsonFile } from '@code-pushup/utils'; +import { INLINE_PLUGIN } from './inline-plugin.js'; async function addTargetToWorkspace( tree: Tree, options: { cwd: string; project: string }, executorOptions?: AutorunCommandExecutorOptions, ) { - const {cwd, project} = options; + const { cwd, project } = options; const projectCfg = readProjectConfiguration(tree, project); updateProjectConfiguration(tree, project, { ...projectCfg, @@ -33,11 +33,11 @@ async function addTargetToWorkspace( ...projectCfg.targets, 'code-pushup': { executor: '@code-pushup/nx-plugin:cli', - ...(executorOptions && {options: executorOptions}), + ...(executorOptions && { options: executorOptions }), }, }, }); - const {root} = projectCfg; + const { root } = projectCfg; generateCodePushupConfig(tree, root, { plugins: [ { @@ -73,8 +73,8 @@ describe('executor command', () => { it('should execute no specific command by default', async () => { const cwd = path.join(testFileDir, 'execute-default-command'); - await addTargetToWorkspace(tree, {cwd, project}); - const {stdout, code} = await executeProcess({ + await addTargetToWorkspace(tree, { cwd, project }); + const { stdout, code } = await executeProcess({ command: 'npx', args: ['nx', 'run', `${project}:code-pushup`, '--dryRun'], cwd, @@ -87,9 +87,9 @@ describe('executor command', () => { it('should execute print-config executor', async () => { const cwd = path.join(testFileDir, 'execute-print-config-command'); - await addTargetToWorkspace(tree, {cwd, project}); + await addTargetToWorkspace(tree, { cwd, project }); - const {stdout, code} = await executeProcess({ + const { stdout, code } = await executeProcess({ command: 'npx', args: ['nx', 'run', `${project}:code-pushup`, 'print-config'], cwd, @@ -106,9 +106,9 @@ describe('executor command', () => { it('should execute print-config executor with api key', async () => { const cwd = path.join(testFileDir, 'execute-print-config-command'); - await addTargetToWorkspace(tree, {cwd, project}); + await addTargetToWorkspace(tree, { cwd, project }); - const {stdout, code} = await executeProcess({ + const { stdout, code } = await executeProcess({ command: 'npx', args: [ 'nx', @@ -134,7 +134,7 @@ describe('executor command', () => { const cwd = path.join(testFileDir, 'execute-collect-with-merged-options'); await addTargetToWorkspace( tree, - {cwd, project}, + { cwd, project }, { persist: { outputDir: '.reports', @@ -143,7 +143,7 @@ describe('executor command', () => { }, ); - const {stdout, code} = await executeProcess({ + const { stdout, code } = await executeProcess({ command: 'npx', args: [ 'nx', @@ -168,9 +168,9 @@ describe('executor command', () => { it('should execute collect executor and add report to sub folder named by project', async () => { const cwd = path.join(testFileDir, 'execute-collect-command'); - await addTargetToWorkspace(tree, {cwd, project}); + await addTargetToWorkspace(tree, { cwd, project }); - const {stdout, code} = await executeProcess({ + const { stdout, code } = await executeProcess({ command: 'npx', args: ['nx', 'run', `${project}:code-pushup`, 'collect'], cwd, diff --git a/packages/nx-plugin/src/executors/cli/executor.unit.test.ts b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts index 77a81a6f0..da08e28f2 100644 --- a/packages/nx-plugin/src/executors/cli/executor.unit.test.ts +++ b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts @@ -1,6 +1,6 @@ import { logger } from '@nx/devkit'; import { execSync } from 'node:child_process'; -import { afterEach, expect, vi } from 'vitest'; +import { afterAll, afterEach, beforeEach, expect, vi } from 'vitest'; import { executorContext } from '@code-pushup/test-nx-utils'; import { MEMFS_VOLUME } from '@code-pushup/test-utils'; import runAutorunExecutor from './executor.js'; @@ -19,14 +19,31 @@ vi.mock('node:child_process', async () => { }); describe('runAutorunExecutor', () => { + const processEnvCP = Object.fromEntries( + Object.entries(process.env).filter(([k]) => k.startsWith('CP_')), + ); const loggerInfoSpy = vi.spyOn(logger, 'info'); const loggerWarnSpy = vi.spyOn(logger, 'warn'); + beforeAll(() => { + Object.entries(process.env) + .filter(([k]) => k.startsWith('CP_')) + .forEach(([k]) => delete process.env[k]); + }); + + beforeEach(() => { + vi.unstubAllEnvs(); + }); + afterEach(() => { loggerWarnSpy.mockReset(); loggerInfoSpy.mockReset(); }); + afterAll(() => { + Object.entries(processEnvCP).forEach(([k, v]) => (process.env[k] = v)); + }); + it('should call execSync with return result', async () => { const output = await runAutorunExecutor({}, executorContext('utils')); expect(output.success).toBe(true); @@ -63,7 +80,20 @@ describe('runAutorunExecutor', () => { expect(output.command).toMatch('--persist.filename="REPORT"'); }); - it('should create command from context, options and arguments', async () => { + it('should create command from context and options if no api key is set', async () => { + vi.stubEnv('CP_PROJECT', 'CLI'); + const output = await runAutorunExecutor( + { persist: { filename: 'REPORT', format: ['md', 'json'] } }, + executorContext('core'), + ); + expect(output.command).toMatch('--persist.filename="REPORT"'); + expect(output.command).toMatch( + '--persist.format="md" --persist.format="json"', + ); + }); + + it('should create command from context, options and arguments if api key is set', async () => { + vi.stubEnv('CP_API_KEY', 'cp_1234567'); vi.stubEnv('CP_PROJECT', 'CLI'); const output = await runAutorunExecutor( { persist: { filename: 'REPORT', format: ['md', 'json'] } }, @@ -73,6 +103,7 @@ describe('runAutorunExecutor', () => { expect(output.command).toMatch( '--persist.format="md" --persist.format="json"', ); + expect(output.command).toMatch('--upload.apiKey="cp_1234567"'); expect(output.command).toMatch('--upload.project="CLI"'); }); From 3e32e37192e9701636ef3ae0b937930e6693b783 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 10 Mar 2025 22:15:02 +0100 Subject: [PATCH 27/30] fix: wip --- packages/plugin-eslint/vite.config.integration.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/plugin-eslint/vite.config.integration.ts b/packages/plugin-eslint/vite.config.integration.ts index 66b388920..f7c0e3b58 100644 --- a/packages/plugin-eslint/vite.config.integration.ts +++ b/packages/plugin-eslint/vite.config.integration.ts @@ -5,8 +5,6 @@ import { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases.js export default defineConfig({ cacheDir: '../../node_modules/.vite/plugin-eslint', test: { - // eslint-disable-next-line @typescript-eslint/no-magic-numbers - testTimeout: 25_000, reporters: ['basic'], globals: true, cache: { From 7cf9479b435a39847c53fb82415f8d509ee40906 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 10 Mar 2025 22:20:24 +0100 Subject: [PATCH 28/30] fix: wip --- packages/nx-plugin/src/executors/cli/executor.unit.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/nx-plugin/src/executors/cli/executor.unit.test.ts b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts index da08e28f2..9af4f1b6b 100644 --- a/packages/nx-plugin/src/executors/cli/executor.unit.test.ts +++ b/packages/nx-plugin/src/executors/cli/executor.unit.test.ts @@ -25,6 +25,7 @@ describe('runAutorunExecutor', () => { const loggerInfoSpy = vi.spyOn(logger, 'info'); const loggerWarnSpy = vi.spyOn(logger, 'warn'); + /* eslint-disable functional/immutable-data, @typescript-eslint/no-dynamic-delete */ beforeAll(() => { Object.entries(process.env) .filter(([k]) => k.startsWith('CP_')) @@ -43,6 +44,7 @@ describe('runAutorunExecutor', () => { afterAll(() => { Object.entries(processEnvCP).forEach(([k, v]) => (process.env[k] = v)); }); + /* eslint-enable functional/immutable-data, @typescript-eslint/no-dynamic-delete */ it('should call execSync with return result', async () => { const output = await runAutorunExecutor({}, executorContext('utils')); From 74c39cb03009d2f325b3e2ba989c998598342f6d Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 10 Mar 2025 22:30:11 +0100 Subject: [PATCH 29/30] fix: wip e2e --- .../tests/executor-cli.e2e.test.ts | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts index 67b2e94df..4c92df962 100644 --- a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts +++ b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts @@ -1,24 +1,12 @@ -import { type Tree, updateProjectConfiguration } from '@nx/devkit'; +import {type Tree, updateProjectConfiguration} from '@nx/devkit'; import path from 'node:path'; -import { readProjectConfiguration } from 'nx/src/generators/utils/project-configuration'; -import { afterEach, expect } from 'vitest'; -import { - type AutorunCommandExecutorOptions, - generateCodePushupConfig, -} from '@code-pushup/nx-plugin'; -import { - generateWorkspaceAndProject, - materializeTree, - nxTargetProject, -} from '@code-pushup/test-nx-utils'; -import { - E2E_ENVIRONMENTS_DIR, - TEST_OUTPUT_DIR, - removeColorCodes, - teardownTestFolder, -} from '@code-pushup/test-utils'; -import { executeProcess, readJsonFile } from '@code-pushup/utils'; -import { INLINE_PLUGIN } from './inline-plugin.js'; +import {readProjectConfiguration} from 'nx/src/generators/utils/project-configuration'; +import {afterAll, afterEach, beforeEach, expect, vi} from 'vitest'; +import {type AutorunCommandExecutorOptions, generateCodePushupConfig,} from '@code-pushup/nx-plugin'; +import {generateWorkspaceAndProject, materializeTree, nxTargetProject,} from '@code-pushup/test-nx-utils'; +import {E2E_ENVIRONMENTS_DIR, removeColorCodes, teardownTestFolder, TEST_OUTPUT_DIR,} from '@code-pushup/test-utils'; +import {executeProcess, readJsonFile} from '@code-pushup/utils'; +import {INLINE_PLUGIN} from './inline-plugin.js'; async function addTargetToWorkspace( tree: Tree, @@ -58,19 +46,32 @@ describe('executor command', () => { TEST_OUTPUT_DIR, 'executor-cli', ); + const processEnvCP = Object.fromEntries( + Object.entries(process.env).filter(([k]) => k.startsWith('CP_')), + ); + + /* eslint-disable functional/immutable-data, @typescript-eslint/no-dynamic-delete */ + beforeAll(() => { + Object.entries(process.env) + .filter(([k]) => k.startsWith('CP_')) + .forEach(([k]) => delete process.env[k]); + }); - beforeEach(async () => { + beforeEach(() => { + vi.unstubAllEnvs(); tree = await generateWorkspaceAndProject(project); - vi.stubEnv('CP_ORGANIZATION', ''); - vi.stubEnv('CP_PROJECT', ''); - vi.stubEnv('CP_SERVER', ''); - vi.stubEnv('CP_API_KEY', ''); }); afterEach(async () => { await teardownTestFolder(testFileDir); }); + afterAll(() => { + Object.entries(processEnvCP).forEach(([k, v]) => (process.env[k] = v)); + }); + /* eslint-enable functional/immutable-data, @typescript-eslint/no-dynamic-delete */ + + it('should execute no specific command by default', async () => { const cwd = path.join(testFileDir, 'execute-default-command'); await addTargetToWorkspace(tree, { cwd, project }); From f17ce38da8479f109244a6f12cbce0ce4779354f Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 10 Mar 2025 22:35:45 +0100 Subject: [PATCH 30/30] fix: wip e2e 2 --- .../tests/executor-cli.e2e.test.ts | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts index 4c92df962..689c555b2 100644 --- a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts +++ b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts @@ -1,12 +1,24 @@ -import {type Tree, updateProjectConfiguration} from '@nx/devkit'; +import { type Tree, updateProjectConfiguration } from '@nx/devkit'; import path from 'node:path'; -import {readProjectConfiguration} from 'nx/src/generators/utils/project-configuration'; -import {afterAll, afterEach, beforeEach, expect, vi} from 'vitest'; -import {type AutorunCommandExecutorOptions, generateCodePushupConfig,} from '@code-pushup/nx-plugin'; -import {generateWorkspaceAndProject, materializeTree, nxTargetProject,} from '@code-pushup/test-nx-utils'; -import {E2E_ENVIRONMENTS_DIR, removeColorCodes, teardownTestFolder, TEST_OUTPUT_DIR,} from '@code-pushup/test-utils'; -import {executeProcess, readJsonFile} from '@code-pushup/utils'; -import {INLINE_PLUGIN} from './inline-plugin.js'; +import { readProjectConfiguration } from 'nx/src/generators/utils/project-configuration'; +import { afterAll, afterEach, beforeEach, expect, vi } from 'vitest'; +import { + type AutorunCommandExecutorOptions, + generateCodePushupConfig, +} from '@code-pushup/nx-plugin'; +import { + generateWorkspaceAndProject, + materializeTree, + nxTargetProject, +} from '@code-pushup/test-nx-utils'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + removeColorCodes, + teardownTestFolder, +} from '@code-pushup/test-utils'; +import { executeProcess, readJsonFile } from '@code-pushup/utils'; +import { INLINE_PLUGIN } from './inline-plugin.js'; async function addTargetToWorkspace( tree: Tree, @@ -57,7 +69,7 @@ describe('executor command', () => { .forEach(([k]) => delete process.env[k]); }); - beforeEach(() => { + beforeEach(async () => { vi.unstubAllEnvs(); tree = await generateWorkspaceAndProject(project); }); @@ -71,7 +83,6 @@ describe('executor command', () => { }); /* eslint-enable functional/immutable-data, @typescript-eslint/no-dynamic-delete */ - it('should execute no specific command by default', async () => { const cwd = path.join(testFileDir, 'execute-default-command'); await addTargetToWorkspace(tree, { cwd, project });