From d35a67806462dfae9fbab99c7c08a432b6a366d5 Mon Sep 17 00:00:00 2001 From: AgentEnder Date: Thu, 8 Feb 2024 11:25:04 -0500 Subject: [PATCH] fix(core): read all targets from package json when defining target defaults --- .../target-defaults/target-defaults-plugin.ts | 16 +- packages/nx/src/utils/package-json.spec.ts | 144 ++++++++++++++---- packages/nx/src/utils/package-json.ts | 26 ++-- packages/nx/src/utils/project-graph-utils.ts | 4 - 4 files changed, 134 insertions(+), 56 deletions(-) diff --git a/packages/nx/src/plugins/target-defaults/target-defaults-plugin.ts b/packages/nx/src/plugins/target-defaults/target-defaults-plugin.ts index 884140531a244..9b920e6e151db 100644 --- a/packages/nx/src/plugins/target-defaults/target-defaults-plugin.ts +++ b/packages/nx/src/plugins/target-defaults/target-defaults-plugin.ts @@ -9,7 +9,10 @@ import { import { readJsonFile } from '../../utils/fileutils'; import { combineGlobPatterns } from '../../utils/globs'; import { NxPluginV2 } from '../../utils/nx-plugin'; -import { PackageJson } from '../../utils/package-json'; +import { + PackageJson, + readTargetsFromPackageJson, +} from '../../utils/package-json'; import { getGlobPatternsFromPackageManagerWorkspaces } from '../package-json-workspaces'; /** @@ -58,16 +61,11 @@ export const TargetDefaultsPlugin: NxPluginV2 = { const packageJson = readJsonOrNull( join(ctx.workspaceRoot, root, 'package.json') ); - const includedScripts = packageJson?.nx?.includedScripts; const projectDefinedTargets = new Set([ - ...Object.keys(packageJson?.scripts ?? {}).filter((script) => { - if (includedScripts) { - return includedScripts.includes(script); - } - return true; - }), ...Object.keys(projectJson?.targets ?? {}), - ...Object.keys(packageJson?.nx?.targets ?? {}), + ...(packageJson + ? Object.keys(readTargetsFromPackageJson(packageJson)) + : []), ]); const executorToTargetMap = getExecutorToTargetMap( diff --git a/packages/nx/src/utils/package-json.spec.ts b/packages/nx/src/utils/package-json.spec.ts index 5c42572a25715..3c02952ed75f1 100644 --- a/packages/nx/src/utils/package-json.spec.ts +++ b/packages/nx/src/utils/package-json.spec.ts @@ -10,36 +10,7 @@ import { describe('buildTargetFromScript', () => { it('should use nx:run-script', () => { - const target = buildTargetFromScript('build', null); - expect(target.executor).toEqual('nx:run-script'); - }); - - it('should use options provided in nx target package json configuration', () => { - const target = buildTargetFromScript('build', { - targets: { - build: { - outputs: ['custom'], - }, - }, - }); - - expect(target.outputs).toEqual(['custom']); - }); - - it('should not override script or executor', () => { - const target = buildTargetFromScript('build', { - targets: { - build: { - outputs: ['custom'], - options: { - script: 'other', - }, - executor: 'custom:execute', - }, - }, - }); - - expect(target.options.script).toEqual('build'); + const target = buildTargetFromScript('build'); expect(target.executor).toEqual('nx:run-script'); }); }); @@ -127,6 +98,119 @@ describe('readTargetsFromPackageJson', () => { }, }); }); + + it('should extend script based targets if matching config', () => { + const result = readTargetsFromPackageJson({ + name: 'my-other-app', + version: '', + scripts: { + build: 'echo 1', + }, + nx: { + targets: { + build: { + outputs: ['custom'], + }, + }, + }, + }); + expect(result.build).toMatchInlineSnapshot(` + { + "executor": "nx:run-script", + "options": { + "script": "build", + }, + "outputs": [ + "custom", + ], + } + `); + }); + + it('should override scripts if provided an executor', () => { + const result = readTargetsFromPackageJson({ + name: 'my-other-app', + version: '', + scripts: { + build: 'echo 1', + }, + nx: { + targets: { + build: { + executor: 'nx:run-commands', + options: { + commands: ['echo 2'], + }, + }, + }, + }, + }); + expect(result.build).toMatchInlineSnapshot(` + { + "executor": "nx:run-commands", + "options": { + "commands": [ + "echo 2", + ], + }, + } + `); + }); + + it('should override script if provided in options', () => { + const result = readTargetsFromPackageJson({ + name: 'my-other-app', + version: '', + scripts: { + build: 'echo 1', + }, + nx: { + targets: { + build: { + executor: 'nx:run-script', + options: { + script: 'echo 2', + }, + }, + }, + }, + }); + expect(result.build).toMatchInlineSnapshot(` + { + "executor": "nx:run-script", + "options": { + "script": "echo 2", + }, + } + `); + }); + + it('should support targets without scripts', () => { + const result = readTargetsFromPackageJson({ + name: 'my-other-app', + version: '', + nx: { + targets: { + build: { + executor: 'nx:run-commands', + options: { + commands: ['echo 2'], + }, + }, + }, + }, + }); + expect(result.build).toMatchInlineSnapshot(` + { + "executor": "nx:run-commands", + "options": { + "commands": [ + "echo 2", + ], + }, + } + `); + }); }); const rootPackageJson: PackageJson = readJsonFile( diff --git a/packages/nx/src/utils/package-json.ts b/packages/nx/src/utils/package-json.ts index 95487c4588596..13efacaa60b14 100644 --- a/packages/nx/src/utils/package-json.ts +++ b/packages/nx/src/utils/package-json.ts @@ -6,6 +6,7 @@ import { } from '../config/workspace-json-project-json'; import { readJsonFile } from './fileutils'; import { getNxRequirePaths } from './installation-directory'; +import { mergeTargetConfigurations } from '../project-graph/utils/project-configuration-utils'; export interface NxProjectPackageJsonConfiguration { implicitDependencies?: string[]; @@ -113,17 +114,10 @@ export function readNxMigrateConfig( }; } -export function buildTargetFromScript( - script: string, - nx: NxProjectPackageJsonConfiguration -): TargetConfiguration { - const nxTargetConfiguration = nx?.targets?.[script] || {}; - +export function buildTargetFromScript(script: string): TargetConfiguration { return { - ...nxTargetConfiguration, executor: 'nx:run-script', options: { - ...(nxTargetConfiguration.options || {}), script, }, }; @@ -132,11 +126,17 @@ export function buildTargetFromScript( export function readTargetsFromPackageJson(packageJson: PackageJson) { const { scripts, nx } = packageJson; const res: Record = {}; - Object.keys(scripts || {}).forEach((script) => { - if (!nx?.includedScripts || nx?.includedScripts.includes(script)) { - res[script] = buildTargetFromScript(script, nx); - } - }); + const includedScripts = nx?.includedScripts || Object.keys(scripts ?? {}); + // + for (const script of includedScripts) { + res[script] = buildTargetFromScript(script); + } + for (const targetName in nx?.targets) { + res[targetName] = mergeTargetConfigurations( + nx?.targets[targetName], + res[targetName] + ); + } /** * Add implicit nx-release-publish target for all package.json files that are diff --git a/packages/nx/src/utils/project-graph-utils.ts b/packages/nx/src/utils/project-graph-utils.ts index e3e9663c51081..e5f51e71b843d 100644 --- a/packages/nx/src/utils/project-graph-utils.ts +++ b/packages/nx/src/utils/project-graph-utils.ts @@ -1,9 +1,5 @@ -import { buildTargetFromScript, PackageJson } from './package-json'; -import { join } from 'path'; import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph'; -import { readJsonFile } from './fileutils'; import { readCachedProjectGraph } from '../project-graph/project-graph'; -import { TargetConfiguration } from '../config/workspace-json-project-json'; export function projectHasTarget( project: ProjectGraphProjectNode,