From a3cf10c060922bbb673b49e794d00b4eb9d20241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leosvel=20P=C3=A9rez=20Espinosa?= Date: Tue, 11 Jul 2023 09:53:44 +0100 Subject: [PATCH] fix(misc): fix migrations updating target options to consider target defaults --- ...-projects-to-update-buildable-deps.spec.ts | 55 ++++++++++++++++++- ...y-set-projects-to-update-buildable-deps.ts | 33 ++++++----- ...-projects-to-update-buildable-deps.spec.ts | 49 ++++++++++++++++- ...y-set-projects-to-update-buildable-deps.ts | 33 ++++++----- ...-projects-to-update-buildable-deps.spec.ts | 49 ++++++++++++++++- ...y-set-projects-to-update-buildable-deps.ts | 33 ++++++----- 6 files changed, 204 insertions(+), 48 deletions(-) diff --git a/packages/angular/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts b/packages/angular/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts index cc0f0378242ae..beb741d5e2930 100644 --- a/packages/angular/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts +++ b/packages/angular/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts @@ -1,5 +1,6 @@ import { ProjectConfiguration, + ProjectGraph, Tree, addProjectConfiguration, readProjectConfiguration, @@ -7,11 +8,18 @@ import { import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import migration from './explicitly-set-projects-to-update-buildable-deps'; +let projectGraph: ProjectGraph; +jest.mock('@nx/devkit', () => ({ + ...jest.requireActual('@nx/devkit'), + createProjectGraphAsync: () => Promise.resolve(projectGraph), +})); + describe('explicitly-set-projects-to-update-buildable-deps migration', () => { let tree: Tree; beforeEach(() => { tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); + projectGraph = { dependencies: {}, nodes: {} }; }); it.each([ @@ -22,7 +30,7 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { ])( 'should set updateBuildableProjectDepsInPackageJson option to "true" when not specified in target using "%s"', async (executor) => { - addProjectConfiguration(tree, 'lib1', { + addProject(tree, 'lib1', { root: 'libs/lib1', projectType: 'library', targets: { build: { executor, options: {} } }, @@ -37,6 +45,29 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { } ); + it.each([ + '@nx/angular:ng-packagr-lite', + '@nrwl/angular:ng-packagr-lite', + '@nx/angular:package', + '@nrwl/angular:package', + ])( + 'should set updateBuildableProjectDepsInPackageJson option to "true" when target has no options object defined using "%s"', + async (executor) => { + addProject(tree, 'lib1', { + root: 'libs/lib1', + projectType: 'library', + targets: { build: { executor } }, + }); + + await migration(tree); + + const project = readProjectConfiguration(tree, 'lib1'); + expect( + project.targets.build.options.updateBuildableProjectDepsInPackageJson + ).toBe(true); + } + ); + it.each([ '@nx/angular:ng-packagr-lite', '@nrwl/angular:ng-packagr-lite', @@ -45,7 +76,7 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { ])( 'should not overwrite updateBuildableProjectDepsInPackageJson option when it is specified in target using "%s"', async (executor) => { - addProjectConfiguration(tree, 'lib1', { + addProject(tree, 'lib1', { root: 'libs/lib1', projectType: 'library', targets: { @@ -76,7 +107,7 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { }, }, }; - addProjectConfiguration(tree, 'lib1', originalProjectConfig); + addProject(tree, 'lib1', originalProjectConfig); await migration(tree); @@ -84,3 +115,21 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { expect(project.targets).toStrictEqual(originalProjectConfig.targets); }); }); + +function addProject( + tree: Tree, + projectName: string, + config: ProjectConfiguration +): void { + projectGraph = { + dependencies: {}, + nodes: { + [projectName]: { + data: config, + name: projectName, + type: config.projectType === 'application' ? 'app' : 'lib', + }, + }, + }; + addProjectConfiguration(tree, projectName, config); +} diff --git a/packages/angular/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts b/packages/angular/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts index 09e5f6c9cc4d5..8842d8205e9c0 100644 --- a/packages/angular/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts +++ b/packages/angular/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts @@ -1,6 +1,7 @@ import { + createProjectGraphAsync, formatFiles, - getProjects, + readProjectConfiguration, Tree, updateProjectConfiguration, } from '@nx/devkit'; @@ -13,31 +14,37 @@ const executors = new Set([ ]); export default async function (tree: Tree) { - const projects = getProjects(tree); + // use project graph to get the expanded target configurations + const projectGraph = await createProjectGraphAsync(); - for (const [projectName, project] of projects) { - if (project.projectType !== 'library') { + for (const [projectName, { data: projectData }] of Object.entries( + projectGraph.nodes + )) { + if (projectData.projectType !== 'library') { continue; } - let updated = false; - for (const [, target] of Object.entries(project.targets || {})) { + for (const [targetName, target] of Object.entries( + projectData.targets || {} + )) { if (!executors.has(target.executor)) { continue; } if ( - target.options && + !target.options || target.options.updateBuildableProjectDepsInPackageJson === undefined ) { - target.options.updateBuildableProjectDepsInPackageJson = true; - updated = true; + // read the project configuration to write the explicit project configuration + // and avoid writing the expanded target configuration + const project = readProjectConfiguration(tree, projectName); + project.targets[targetName].options ??= {}; + project.targets[ + targetName + ].options.updateBuildableProjectDepsInPackageJson = true; + updateProjectConfiguration(tree, projectName, project); } } - - if (updated) { - updateProjectConfiguration(tree, projectName, project); - } } await formatFiles(tree); diff --git a/packages/js/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts b/packages/js/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts index 07caa361d79f4..3374fd0050e7c 100644 --- a/packages/js/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts +++ b/packages/js/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts @@ -1,5 +1,6 @@ import { ProjectConfiguration, + ProjectGraph, Tree, addProjectConfiguration, readProjectConfiguration, @@ -7,6 +8,12 @@ import { import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import migration from './explicitly-set-projects-to-update-buildable-deps'; +let projectGraph: ProjectGraph; +jest.mock('@nx/devkit', () => ({ + ...jest.requireActual('@nx/devkit'), + createProjectGraphAsync: () => Promise.resolve(projectGraph), +})); + describe('explicitly-set-projects-to-update-buildable-deps migration', () => { let tree: Tree; @@ -17,7 +24,7 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { it.each(['@nx/js:swc', '@nrwl/js:swc', '@nx/js:tsc', '@nrwl/js:tsc'])( 'should set updateBuildableProjectDepsInPackageJson option to "true" when not specified in target using "%s"', async (executor) => { - addProjectConfiguration(tree, 'lib1', { + addProject(tree, 'lib1', { root: 'libs/lib1', projectType: 'library', targets: { build: { executor, options: {} } }, @@ -32,10 +39,28 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { } ); + it.each(['@nx/js:swc', '@nrwl/js:swc', '@nx/js:tsc', '@nrwl/js:tsc'])( + 'should set updateBuildableProjectDepsInPackageJson option to "true" when target has no options object defined using "%s"', + async (executor) => { + addProject(tree, 'lib1', { + root: 'libs/lib1', + projectType: 'library', + targets: { build: { executor } }, + }); + + await migration(tree); + + const project = readProjectConfiguration(tree, 'lib1'); + expect( + project.targets.build.options.updateBuildableProjectDepsInPackageJson + ).toBe(true); + } + ); + it.each(['@nx/js:swc', '@nrwl/js:swc', '@nx/js:tsc', '@nrwl/js:tsc'])( 'should not overwrite updateBuildableProjectDepsInPackageJson option when it is specified in target using "%s"', async (executor) => { - addProjectConfiguration(tree, 'lib1', { + addProject(tree, 'lib1', { root: 'libs/lib1', projectType: 'library', targets: { @@ -66,7 +91,7 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { }, }, }; - addProjectConfiguration(tree, 'lib1', originalProjectConfig); + addProject(tree, 'lib1', originalProjectConfig); await migration(tree); @@ -74,3 +99,21 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { expect(project.targets).toStrictEqual(originalProjectConfig.targets); }); }); + +function addProject( + tree: Tree, + projectName: string, + config: ProjectConfiguration +): void { + projectGraph = { + dependencies: {}, + nodes: { + [projectName]: { + data: config, + name: projectName, + type: config.projectType === 'application' ? 'app' : 'lib', + }, + }, + }; + addProjectConfiguration(tree, projectName, config); +} diff --git a/packages/js/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts b/packages/js/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts index 5273b2a748520..edbe446bf598f 100644 --- a/packages/js/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts +++ b/packages/js/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts @@ -1,6 +1,7 @@ import { + createProjectGraphAsync, formatFiles, - getProjects, + readProjectConfiguration, Tree, updateProjectConfiguration, } from '@nx/devkit'; @@ -13,31 +14,37 @@ const executors = new Set([ ]); export default async function (tree: Tree) { - const projects = getProjects(tree); + // use project graph to get the expanded target configurations + const projectGraph = await createProjectGraphAsync(); - for (const [projectName, project] of projects) { - if (project.projectType !== 'library') { + for (const [projectName, { data: projectData }] of Object.entries( + projectGraph.nodes + )) { + if (projectData.projectType !== 'library') { continue; } - let updated = false; - for (const [, target] of Object.entries(project.targets || {})) { + for (const [targetName, target] of Object.entries( + projectData.targets || {} + )) { if (!executors.has(target.executor)) { continue; } if ( - target.options && + !target.options || target.options.updateBuildableProjectDepsInPackageJson === undefined ) { - target.options.updateBuildableProjectDepsInPackageJson = true; - updated = true; + // read the project configuration to write the explicit project configuration + // and avoid writing the expanded target configuration + const project = readProjectConfiguration(tree, projectName); + project.targets[targetName].options ??= {}; + project.targets[ + targetName + ].options.updateBuildableProjectDepsInPackageJson = true; + updateProjectConfiguration(tree, projectName, project); } } - - if (updated) { - updateProjectConfiguration(tree, projectName, project); - } } await formatFiles(tree); diff --git a/packages/rollup/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts b/packages/rollup/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts index 0d244a11a33ec..e507d75aeaca3 100644 --- a/packages/rollup/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts +++ b/packages/rollup/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.spec.ts @@ -1,5 +1,6 @@ import { ProjectConfiguration, + ProjectGraph, Tree, addProjectConfiguration, readProjectConfiguration, @@ -7,6 +8,12 @@ import { import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import migration from './explicitly-set-projects-to-update-buildable-deps'; +let projectGraph: ProjectGraph; +jest.mock('@nx/devkit', () => ({ + ...jest.requireActual('@nx/devkit'), + createProjectGraphAsync: () => Promise.resolve(projectGraph), +})); + describe('explicitly-set-projects-to-update-buildable-deps migration', () => { let tree: Tree; @@ -17,7 +24,7 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { it.each(['@nx/rollup:rollup', '@nrwl/rollup:rollup'])( 'should set updateBuildableProjectDepsInPackageJson option to "true" when not specified in target using "%s"', async (executor) => { - addProjectConfiguration(tree, 'lib1', { + addProject(tree, 'lib1', { root: 'libs/lib1', projectType: 'library', targets: { build: { executor, options: {} } }, @@ -32,10 +39,28 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { } ); + it.each(['@nx/rollup:rollup', '@nrwl/rollup:rollup'])( + 'should set updateBuildableProjectDepsInPackageJson option to "true" when target has no options object defined using "%s"', + async (executor) => { + addProject(tree, 'lib1', { + root: 'libs/lib1', + projectType: 'library', + targets: { build: { executor } }, + }); + + await migration(tree); + + const project = readProjectConfiguration(tree, 'lib1'); + expect( + project.targets.build.options.updateBuildableProjectDepsInPackageJson + ).toBe(true); + } + ); + it.each(['@nx/js:swc', '@nrwl/js:swc', '@nx/js:tsc', '@nrwl/js:tsc'])( 'should not overwrite updateBuildableProjectDepsInPackageJson option when it is specified in target using "%s"', async (executor) => { - addProjectConfiguration(tree, 'lib1', { + addProject(tree, 'lib1', { root: 'libs/lib1', projectType: 'library', targets: { @@ -66,7 +91,7 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { }, }, }; - addProjectConfiguration(tree, 'lib1', originalProjectConfig); + addProject(tree, 'lib1', originalProjectConfig); await migration(tree); @@ -74,3 +99,21 @@ describe('explicitly-set-projects-to-update-buildable-deps migration', () => { expect(project.targets).toStrictEqual(originalProjectConfig.targets); }); }); + +function addProject( + tree: Tree, + projectName: string, + config: ProjectConfiguration +): void { + projectGraph = { + dependencies: {}, + nodes: { + [projectName]: { + data: config, + name: projectName, + type: config.projectType === 'application' ? 'app' : 'lib', + }, + }, + }; + addProjectConfiguration(tree, projectName, config); +} diff --git a/packages/rollup/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts b/packages/rollup/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts index e3377e89e2f7d..5af99c4f5b181 100644 --- a/packages/rollup/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts +++ b/packages/rollup/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.ts @@ -1,6 +1,7 @@ import { + createProjectGraphAsync, formatFiles, - getProjects, + readProjectConfiguration, Tree, updateProjectConfiguration, } from '@nx/devkit'; @@ -8,31 +9,37 @@ import { const executors = new Set(['@nx/rollup:rollup', '@nrwl/rollup:rollup']); export default async function (tree: Tree) { - const projects = getProjects(tree); + // use project graph to get the expanded target configurations + const projectGraph = await createProjectGraphAsync(); - for (const [projectName, project] of projects) { - if (project.projectType !== 'library') { + for (const [projectName, { data: projectData }] of Object.entries( + projectGraph.nodes + )) { + if (projectData.projectType !== 'library') { continue; } - let updated = false; - for (const [, target] of Object.entries(project.targets || {})) { + for (const [targetName, target] of Object.entries( + projectData.targets || {} + )) { if (!executors.has(target.executor)) { continue; } if ( - target.options && + !target.options || target.options.updateBuildableProjectDepsInPackageJson === undefined ) { - target.options.updateBuildableProjectDepsInPackageJson = true; - updated = true; + // read the project configuration to write the explicit project configuration + // and avoid writing the expanded target configuration + const project = readProjectConfiguration(tree, projectName); + project.targets[targetName].options ??= {}; + project.targets[ + targetName + ].options.updateBuildableProjectDepsInPackageJson = true; + updateProjectConfiguration(tree, projectName, project); } } - - if (updated) { - updateProjectConfiguration(tree, projectName, project); - } } await formatFiles(tree);