diff --git a/packages/nx/src/command-line/migrate/migrate.spec.ts b/packages/nx/src/command-line/migrate/migrate.spec.ts index 9985b0102c848d..0407f27ae2ee24 100644 --- a/packages/nx/src/command-line/migrate/migrate.spec.ts +++ b/packages/nx/src/command-line/migrate/migrate.spec.ts @@ -426,6 +426,7 @@ describe('Migration', () => { }, '@my-company/lib-4': { version: '2.0.1', addToPackageJson: false }, }, + minVersionWithSkippedUpdates: undefined, }); }); @@ -503,6 +504,7 @@ describe('Migration', () => { '@my-company/lib-1': { version: '3.0.0', addToPackageJson: false }, '@my-company/lib-2': { version: '3.0.0', addToPackageJson: false }, }, + minVersionWithSkippedUpdates: undefined, }); }); @@ -635,6 +637,7 @@ describe('Migration', () => { child2: { version: '3.0.0', addToPackageJson: false }, child3: { version: '3.0.0', addToPackageJson: false }, }, + minVersionWithSkippedUpdates: undefined, }); expect(enquirer.prompt).toHaveBeenCalledWith( expect.arrayContaining([ @@ -693,6 +696,7 @@ describe('Migration', () => { mypackage: { version: '2.0.0', addToPackageJson: false }, child1: { version: '3.0.0', addToPackageJson: false }, }, + minVersionWithSkippedUpdates: '2.0.0', }); expect(enquirer.prompt).toHaveBeenCalled(); }); @@ -749,6 +753,7 @@ describe('Migration', () => { child2: { version: '3.0.0', addToPackageJson: false }, child3: { version: '3.0.0', addToPackageJson: false }, }, + minVersionWithSkippedUpdates: undefined, }); expect(enquirer.prompt).not.toHaveBeenCalled(); }); @@ -831,6 +836,7 @@ describe('Migration', () => { child2: { version: '3.0.0', addToPackageJson: false }, child3: { version: '3.0.0', addToPackageJson: false }, }, + minVersionWithSkippedUpdates: undefined, }); }); @@ -913,6 +919,7 @@ describe('Migration', () => { pkg1: { version: '2.0.0', addToPackageJson: false }, pkg2: { version: '2.0.0', addToPackageJson: false }, }, + minVersionWithSkippedUpdates: undefined, }); }); @@ -961,6 +968,7 @@ describe('Migration', () => { mypackage: { version: '2.0.0', addToPackageJson: false }, child1: { version: '3.0.0', addToPackageJson: false }, }, + minVersionWithSkippedUpdates: undefined, }); expect(enquirer.prompt).toHaveBeenCalledWith( expect.arrayContaining([ @@ -1013,6 +1021,7 @@ describe('Migration', () => { packageUpdates: { mypackage: { version: '2.0.0', addToPackageJson: false }, }, + minVersionWithSkippedUpdates: undefined, }); expect(enquirer.prompt).not.toHaveBeenCalled(); }); @@ -1257,6 +1266,7 @@ describe('Migration', () => { packageUpdates: { parent: { version: '2.0.0', addToPackageJson: false }, }, + minVersionWithSkippedUpdates: '2.0.0', }); expect(enquirer.prompt).toHaveBeenCalled(); }); diff --git a/packages/nx/src/command-line/migrate/migrate.ts b/packages/nx/src/command-line/migrate/migrate.ts index 5942e928bc6aa4..0f4dc683cd8735 100644 --- a/packages/nx/src/command-line/migrate/migrate.ts +++ b/packages/nx/src/command-line/migrate/migrate.ts @@ -137,6 +137,7 @@ export class Migrator { private readonly collectedVersions: Record = {}; private readonly promptAnswers: Record = {}; private readonly nxInstallation: NxJsonConfiguration['installation'] | null; + private minVersionWithSkippedUpdates: string | undefined; constructor(opts: MigratorOptions) { this.packageJson = opts.packageJson; @@ -156,7 +157,11 @@ export class Migrator { }); const migrations = await this.createMigrateJson(); - return { packageUpdates: this.packageUpdates, migrations }; + return { + packageUpdates: this.packageUpdates, + migrations, + minVersionWithSkippedUpdates: this.minVersionWithSkippedUpdates, + }; } private async createMigrateJson() { @@ -567,6 +572,15 @@ export class Migrator { }, ]).then(({ shouldApply }: { shouldApply: boolean }) => { this.promptAnswers[promptKey] = shouldApply; + + if ( + !shouldApply && + (!this.minVersionWithSkippedUpdates || + lt(packageUpdate.version, this.minVersionWithSkippedUpdates)) + ) { + this.minVersionWithSkippedUpdates = packageUpdate.version; + } + return shouldApply; }); } @@ -1232,10 +1246,8 @@ async function generateMigrationsJsonAndUpdatePackageJson( excludeAppliedMigrations: opts.excludeAppliedMigrations, }); - const { migrations, packageUpdates } = await migrator.migrate( - opts.targetPackage, - opts.targetVersion - ); + const { migrations, packageUpdates, minVersionWithSkippedUpdates } = + await migrator.migrate(opts.targetPackage, opts.targetVersion); updatePackageJson(root, packageUpdates); await updateInstallationDetails(root, packageUpdates); @@ -1264,6 +1276,11 @@ async function generateMigrationsJsonAndUpdatePackageJson( ...(migrations.length > 0 ? [`- Run '${pmc.exec} nx migrate --run-migrations'`] : []), + ...(opts.interactive && minVersionWithSkippedUpdates + ? [ + `- You opted out of some migrations for now. Write the following command down somewhere to apply these migrations later: 'nx migrate ${opts.targetVersion} --from ${opts.targetPackage}@${minVersionWithSkippedUpdates} --exclude-applied-migrations'.`, + ] + : []), `- To learn more go to https://nx.dev/core-features/automate-updating-dependencies`, ...(showConnectToCloudMessage() ? [