diff --git a/docs/generated/devkit/Migration.md b/docs/generated/devkit/Migration.md new file mode 100644 index 0000000000..a66b6287c6 --- /dev/null +++ b/docs/generated/devkit/Migration.md @@ -0,0 +1,22 @@ +# Type alias: Migration + +Ƭ **Migration**: (`tree`: [`Tree`](../../devkit/documents/Tree)) => `void` \| `Promise`\<`void`\> \| `string`[] \| `Promise`\<`string`[]\> + +Represents a migration that is executed when running `nx migrate`. + +Returning a string[] from the migration function will be interpreted as +a list of next steps to be displayed to the user. + +#### Type declaration + +▸ (`tree`): `void` \| `Promise`\<`void`\> \| `string`[] \| `Promise`\<`string`[]\> + +##### Parameters + +| Name | Type | +| :----- | :------------------------------------ | +| `tree` | [`Tree`](../../devkit/documents/Tree) | + +##### Returns + +`void` \| `Promise`\<`void`\> \| `string`[] \| `Promise`\<`string`[]\> diff --git a/docs/generated/devkit/NxJsonConfiguration.md b/docs/generated/devkit/NxJsonConfiguration.md index 6d9d9e38fd..17add6a641 100644 --- a/docs/generated/devkit/NxJsonConfiguration.md +++ b/docs/generated/devkit/NxJsonConfiguration.md @@ -45,7 +45,6 @@ Nx.json configuration - [tui](../../devkit/documents/NxJsonConfiguration#tui): Object - [useDaemonProcess](../../devkit/documents/NxJsonConfiguration#usedaemonprocess): boolean - [useInferencePlugins](../../devkit/documents/NxJsonConfiguration#useinferenceplugins): boolean -- [useLegacyCache](../../devkit/documents/NxJsonConfiguration#uselegacycache): boolean - [workspaceLayout](../../devkit/documents/NxJsonConfiguration#workspacelayout): Object ## Properties @@ -321,14 +320,6 @@ Set this to false to disable adding inference plugins when generating new projec --- -### useLegacyCache - -• `Optional` **useLegacyCache**: `boolean` - -Use the legacy file system cache instead of the db cache - ---- - ### workspaceLayout • `Optional` **workspaceLayout**: `Object` diff --git a/docs/generated/devkit/README.md b/docs/generated/devkit/README.md index 26449f38d7..c873221ad0 100644 --- a/docs/generated/devkit/README.md +++ b/docs/generated/devkit/README.md @@ -84,6 +84,7 @@ It only uses language primitives and immutable objects - [Hasher](../../devkit/documents/Hasher) - [ImplicitDependency](../../devkit/documents/ImplicitDependency) - [ImplicitDependencyEntry](../../devkit/documents/ImplicitDependencyEntry) +- [Migration](../../devkit/documents/Migration) - [NxPlugin](../../devkit/documents/NxPlugin) - [NxPluginV2](../../devkit/documents/NxPluginV2) - [PackageManager](../../devkit/documents/PackageManager) diff --git a/docs/generated/devkit/Workspace.md b/docs/generated/devkit/Workspace.md index f747213d62..75ab29b306 100644 --- a/docs/generated/devkit/Workspace.md +++ b/docs/generated/devkit/Workspace.md @@ -44,7 +44,6 @@ use ProjectsConfigurations or NxJsonConfiguration - [tui](../../devkit/documents/Workspace#tui): Object - [useDaemonProcess](../../devkit/documents/Workspace#usedaemonprocess): boolean - [useInferencePlugins](../../devkit/documents/Workspace#useinferenceplugins): boolean -- [useLegacyCache](../../devkit/documents/Workspace#uselegacycache): boolean - [version](../../devkit/documents/Workspace#version): number - [workspaceLayout](../../devkit/documents/Workspace#workspacelayout): Object @@ -441,18 +440,6 @@ Set this to false to disable adding inference plugins when generating new projec --- -### useLegacyCache - -• `Optional` **useLegacyCache**: `boolean` - -Use the legacy file system cache instead of the db cache - -#### Inherited from - -[NxJsonConfiguration](../../devkit/documents/NxJsonConfiguration).[useLegacyCache](../../devkit/documents/NxJsonConfiguration#uselegacycache) - ---- - ### version • **version**: `number` diff --git a/docs/generated/manifests/nx-api.json b/docs/generated/manifests/nx-api.json index f28ec39bcc..facbf347ab 100644 --- a/docs/generated/manifests/nx-api.json +++ b/docs/generated/manifests/nx-api.json @@ -3364,6 +3364,26 @@ } }, "migrations": { + "/nx-api/nx/migrations/remove-legacy-cache": { + "description": "Removes the legacy cache configuration from nx.json", + "file": "generated/packages/nx/migrations/remove-legacy-cache.json", + "hidden": false, + "name": "remove-legacy-cache", + "version": "21.0.0-beta.8", + "originalFilePath": "/packages/nx", + "path": "/nx-api/nx/migrations/remove-legacy-cache", + "type": "migration" + }, + "/nx-api/nx/migrations/remove-custom-tasks-runner": { + "description": "Removes the legacy cache configuration from nx.json", + "file": "generated/packages/nx/migrations/remove-custom-tasks-runner.json", + "hidden": false, + "name": "remove-custom-tasks-runner", + "version": "21.0.0-beta.8", + "originalFilePath": "/packages/nx", + "path": "/nx-api/nx/migrations/remove-custom-tasks-runner", + "type": "migration" + }, "/nx-api/nx/migrations/release-version-config-changes": { "description": "Updates release version config based on the breaking changes in Nx v21", "file": "generated/packages/nx/migrations/release-version-config-changes.json", diff --git a/docs/generated/packages-metadata.json b/docs/generated/packages-metadata.json index c2eac021a8..8064a60089 100644 --- a/docs/generated/packages-metadata.json +++ b/docs/generated/packages-metadata.json @@ -3340,6 +3340,26 @@ } ], "migrations": [ + { + "description": "Removes the legacy cache configuration from nx.json", + "file": "generated/packages/nx/migrations/remove-legacy-cache.json", + "hidden": false, + "name": "remove-legacy-cache", + "version": "21.0.0-beta.8", + "originalFilePath": "/packages/nx", + "path": "nx/migrations/remove-legacy-cache", + "type": "migration" + }, + { + "description": "Removes the legacy cache configuration from nx.json", + "file": "generated/packages/nx/migrations/remove-custom-tasks-runner.json", + "hidden": false, + "name": "remove-custom-tasks-runner", + "version": "21.0.0-beta.8", + "originalFilePath": "/packages/nx", + "path": "nx/migrations/remove-custom-tasks-runner", + "type": "migration" + }, { "description": "Updates release version config based on the breaking changes in Nx v21", "file": "generated/packages/nx/migrations/release-version-config-changes.json", diff --git a/docs/generated/packages/devkit/documents/nx_devkit.md b/docs/generated/packages/devkit/documents/nx_devkit.md index 26449f38d7..c873221ad0 100644 --- a/docs/generated/packages/devkit/documents/nx_devkit.md +++ b/docs/generated/packages/devkit/documents/nx_devkit.md @@ -84,6 +84,7 @@ It only uses language primitives and immutable objects - [Hasher](../../devkit/documents/Hasher) - [ImplicitDependency](../../devkit/documents/ImplicitDependency) - [ImplicitDependencyEntry](../../devkit/documents/ImplicitDependencyEntry) +- [Migration](../../devkit/documents/Migration) - [NxPlugin](../../devkit/documents/NxPlugin) - [NxPluginV2](../../devkit/documents/NxPluginV2) - [PackageManager](../../devkit/documents/PackageManager) diff --git a/docs/generated/packages/nx/migrations/remove-custom-tasks-runner.json b/docs/generated/packages/nx/migrations/remove-custom-tasks-runner.json new file mode 100644 index 0000000000..387d346a0d --- /dev/null +++ b/docs/generated/packages/nx/migrations/remove-custom-tasks-runner.json @@ -0,0 +1,12 @@ +{ + "name": "remove-custom-tasks-runner", + "version": "21.0.0-beta.8", + "description": "Removes the legacy cache configuration from nx.json", + "implementation": "/packages/nx/src/migrations/update-21-0-0/remove-custom-tasks-runner.ts", + "aliases": [], + "hidden": false, + "path": "/packages/nx", + "schema": null, + "type": "migration", + "examplesFile": "#### Remove Custom Tasks Runners\n\nRemoves `tasksRunnerOptions` entries from `nx.json` that contain custom tasks runners. In Nx 21, custom tasks runners are no longer functional. See /deprecated/custom-tasks-runner for more information.\n\n#### Sample Code Changes\n\nRemoves custom task runner configuration from `nx.json`.\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {},\n \"tasksRunnerOptions\": {\n \"default\": {\n \"runner\": \"custom-task-runner\"\n }\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {}\n}\n```\n\n{% /tab %}\n{% /tabs %}\n" +} diff --git a/docs/generated/packages/nx/migrations/remove-legacy-cache.json b/docs/generated/packages/nx/migrations/remove-legacy-cache.json new file mode 100644 index 0000000000..fd33abdd00 --- /dev/null +++ b/docs/generated/packages/nx/migrations/remove-legacy-cache.json @@ -0,0 +1,12 @@ +{ + "name": "remove-legacy-cache", + "version": "21.0.0-beta.8", + "description": "Removes the legacy cache configuration from nx.json", + "implementation": "/packages/nx/src/migrations/update-21-0-0/remove-legacy-cache.ts", + "aliases": [], + "hidden": false, + "path": "/packages/nx", + "schema": null, + "type": "migration", + "examplesFile": "#### Use Legacy Cache\n\nRemoves `useLegacyCache` from `nx.json` as it is no longer functional in Nx 21\n\n#### Sample Code Changes\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {},\n \"useLegacyCache\": true\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% fileName=\"nx.json\" %}\n{\n \"targetDefaults\": {}\n}\n```\n\n{% /tab %}\n{% /tabs %}\n" +} diff --git a/packages/nx/migrations.json b/packages/nx/migrations.json index 3e3a114a5b..2a5ac3214c 100644 --- a/packages/nx/migrations.json +++ b/packages/nx/migrations.json @@ -33,6 +33,16 @@ "version": "21.0.0-beta.1", "description": "Updates release version config based on the breaking changes in Nx v21", "implementation": "./src/migrations/update-21-0-0/release-version-config-changes" + }, + "remove-legacy-cache": { + "version": "21.0.0-beta.8", + "description": "Removes the legacy cache configuration from nx.json", + "implementation": "./src/migrations/update-21-0-0/remove-legacy-cache" + }, + "remove-custom-tasks-runner": { + "version": "21.0.0-beta.8", + "description": "Removes the legacy cache configuration from nx.json", + "implementation": "./src/migrations/update-21-0-0/remove-custom-tasks-runner" } } } diff --git a/packages/nx/src/command-line/migrate/migrate-ui-api.ts b/packages/nx/src/command-line/migrate/migrate-ui-api.ts index beff69c431..1c1c9035d4 100644 --- a/packages/nx/src/command-line/migrate/migrate-ui-api.ts +++ b/packages/nx/src/command-line/migrate/migrate-ui-api.ts @@ -135,15 +135,16 @@ export async function runSingleMigration( // 2. Bundled into Console, so the version is fixed to what we build Console with. const updatedMigrateModule = await import('./migrate.js'); - const fileChanges = await updatedMigrateModule.runNxOrAngularMigration( - workspacePath, - migration, - false, - configuration.createCommits, - configuration.commitPrefix || 'chore: [nx migration] ', - undefined, - true - ); + const { changes: fileChanges } = + await updatedMigrateModule.runNxOrAngularMigration( + workspacePath, + migration, + false, + configuration.createCommits, + configuration.commitPrefix || 'chore: [nx migration] ', + undefined, + true + ); const gitRefAfter = execSync('git rev-parse HEAD', { cwd: workspacePath, diff --git a/packages/nx/src/command-line/migrate/migrate.ts b/packages/nx/src/command-line/migrate/migrate.ts index 3242f5c54c..d0c0497971 100644 --- a/packages/nx/src/command-line/migrate/migrate.ts +++ b/packages/nx/src/command-line/migrate/migrate.ts @@ -1474,11 +1474,11 @@ export async function executeMigrations( logger.info(`- ${m.package}: ${m.name} (${m.description})`) ); logger.info(`---------------------------------------------------------\n`); - + const allNextSteps: string[] = []; for (const m of sortedMigrations) { logger.info(`Running migration ${m.package}: ${m.name}`); try { - const changes = await runNxOrAngularMigration( + const { changes, nextSteps } = await runNxOrAngularMigration( root, m, isVerbose, @@ -1486,6 +1486,7 @@ export async function executeMigrations( commitPrefix, () => changedDepInstaller.installDepsIfChanged() ); + allNextSteps.push(...nextSteps); if (changes.length === 0) { migrationsWithNoChanges.push(m); } @@ -1502,7 +1503,7 @@ export async function executeMigrations( changedDepInstaller.installDepsIfChanged(); } - return migrationsWithNoChanges; + return { migrationsWithNoChanges, nextSteps: allNextSteps }; } class ChangedDepInstaller { @@ -1533,7 +1534,7 @@ export async function runNxOrAngularMigration( commitPrefix: string, installDepsIfChanged?: () => void, handleInstallDeps = false -): Promise { +): Promise<{ changes: FileChange[]; nextSteps: string[] }> { if (!installDepsIfChanged) { const changedDepInstaller = new ChangedDepInstaller(root); installDepsIfChanged = () => changedDepInstaller.installDepsIfChanged(); @@ -1543,19 +1544,20 @@ export async function runNxOrAngularMigration( root ); let changes: FileChange[] = []; + let nextSteps: string[] = []; if (!isAngularMigration(collection, migration.name)) { - changes = await runNxMigration( + ({ nextSteps, changes } = await runNxMigration( root, collectionPath, collection, migration.name - ); + )); logger.info(`Ran ${migration.name} from ${migration.package}`); logger.info(` ${migration.description}\n`); if (changes.length < 1) { logger.info(`No changes were made\n`); - return []; + return { changes, nextSteps }; } logger.info('Changes:'); @@ -1576,7 +1578,7 @@ export async function runNxOrAngularMigration( logger.info(` ${migration.description}\n`); if (!madeChanges) { logger.info(`No changes were made\n`); - return []; + return { changes, nextSteps }; } logger.info('Changes:'); @@ -1608,7 +1610,7 @@ export async function runNxOrAngularMigration( installDepsIfChanged(); } - return changes; + return { changes, nextSteps }; } async function runMigrations( @@ -1662,7 +1664,7 @@ async function runMigrations( version: string; }[] = readJsonFile(join(root, opts.runMigrations)).migrations; - const migrationsWithNoChanges = await executeMigrations( + const { migrationsWithNoChanges, nextSteps } = await executeMigrations( root, migrations, isVerbose, @@ -1679,6 +1681,12 @@ async function runMigrations( title: `No changes were made from running '${opts.runMigrations}'. This workspace is up to date!`, }); } + if (nextSteps.length > 0) { + output.log({ + title: `Some migrations have additional information, see below.`, + bodyLines: nextSteps.map((line) => `- ${line}`), + }); + } } function getStringifiedPackageJsonDeps(root: string): string { @@ -1712,11 +1720,18 @@ async function runNxMigration( process.env.NX_VERBOSE_LOGGING === 'true', `migration ${collection.name}:${name}` ); - await fn(host, {}); + let nextSteps = await fn(host, {}); + // This accounts for migrations that mistakenly return a generator callback + // from a migration. We've never executed these, so its not a breaking change that + // we don't call them now... but currently shipping a migration with one wouldn't break + // the migrate flow, so we are being cautious. + if (!isStringArray(nextSteps)) { + nextSteps = []; + } host.lock(); const changes = host.listChanges(); flushChanges(root, changes); - return changes; + return { changes, nextSteps }; } export async function migrate( @@ -1905,3 +1920,10 @@ const getNgCompatLayer = (() => { return _ngCliAdapter; }; })(); + +function isStringArray(value: unknown): value is string[] { + if (!Array.isArray(value)) { + return false; + } + return value.every((v) => typeof v === 'string'); +} diff --git a/packages/nx/src/command-line/repair/repair.ts b/packages/nx/src/command-line/repair/repair.ts index 6c9ba1682b..e90f319a26 100644 --- a/packages/nx/src/command-line/repair/repair.ts +++ b/packages/nx/src/command-line/repair/repair.ts @@ -25,7 +25,7 @@ export async function repair( ); const migrations = [...nxMigrations, ...extraMigrations]; - const migrationsThatMadeNoChanges = await executeMigrations( + const { migrationsWithNoChanges, nextSteps } = await executeMigrations( process.cwd(), migrations, args.verbose, @@ -33,7 +33,7 @@ export async function repair( '' ); - if (migrationsThatMadeNoChanges.length < migrations.length) { + if (migrationsWithNoChanges.length < migrations.length) { output.success({ title: `Successfully repaired your configuration. This workspace is up to date!`, }); @@ -42,5 +42,11 @@ export async function repair( title: `No changes were necessary. This workspace is up to date!`, }); } + if (nextSteps.length) { + output.log({ + title: 'Some repairs have additional information, see below.', + bodyLines: nextSteps.map((line) => ` - ${line}`), + }); + } }); } diff --git a/packages/nx/src/command-line/report/report.ts b/packages/nx/src/command-line/report/report.ts index 8e88be1de6..d0d5c8aecc 100644 --- a/packages/nx/src/command-line/report/report.ts +++ b/packages/nx/src/command-line/report/report.ts @@ -303,7 +303,7 @@ export async function getReportData(): Promise { } } - let cache = dbCacheEnabled(nxJson) + let cache = dbCacheEnabled() ? { max: nxJson.maxCacheSize !== undefined diff --git a/packages/nx/src/config/misc-interfaces.ts b/packages/nx/src/config/misc-interfaces.ts index 50ecc66f9a..40453e047d 100644 --- a/packages/nx/src/config/misc-interfaces.ts +++ b/packages/nx/src/config/misc-interfaces.ts @@ -7,7 +7,8 @@ import { } from './workspace-json-project-json'; import type { NxJsonConfiguration } from './nx-json'; -import { Schema } from '../utils/params'; +import type { Schema } from '../utils/params'; +import type { Tree } from '../generators/tree'; /** * A callback function that is executed after changes are made to the file system */ @@ -66,6 +67,16 @@ export type PackageJsonUpdates = { }; }; +/** + * Represents a migration that is executed when running `nx migrate`. + * + * Returning a string[] from the migration function will be interpreted as + * a list of next steps to be displayed to the user. + */ +export type Migration = ( + tree: Tree +) => void | Promise | string[] | Promise; + export interface MigrationsJsonEntry { version: string; description?: string; diff --git a/packages/nx/src/config/nx-json.ts b/packages/nx/src/config/nx-json.ts index c7cc44a60a..61899510e2 100644 --- a/packages/nx/src/config/nx-json.ts +++ b/packages/nx/src/config/nx-json.ts @@ -651,11 +651,6 @@ export interface NxJsonConfiguration { */ sync?: NxSyncConfiguration; - /** - * Use the legacy file system cache instead of the db cache - */ - useLegacyCache?: boolean; - /** * Sets the maximum size of the local cache. Accepts a number followed by a unit (e.g. 100MB). Accepted units are B, KB, MB, and GB. */ diff --git a/packages/nx/src/devkit-exports.ts b/packages/nx/src/devkit-exports.ts index 44151f6d88..64251338bd 100644 --- a/packages/nx/src/devkit-exports.ts +++ b/packages/nx/src/devkit-exports.ts @@ -26,6 +26,7 @@ export type { */ export type { Generator, + Migration, GeneratorCallback, PromiseExecutor, AsyncIteratorExecutor, diff --git a/packages/nx/src/migrations/update-20-0-1/use-legacy-cache.ts b/packages/nx/src/migrations/update-20-0-1/use-legacy-cache.ts index f7340aac63..9a348819a7 100644 --- a/packages/nx/src/migrations/update-20-0-1/use-legacy-cache.ts +++ b/packages/nx/src/migrations/update-20-0-1/use-legacy-cache.ts @@ -14,7 +14,9 @@ export default async function update(tree: Tree) { if ((nxJson as any).enableDbCache) { delete (nxJson as any).enableDbCache; } else { - nxJson.useLegacyCache = true; + ( + nxJson as NxJsonConfiguration & { useLegacyCache: boolean } + ).useLegacyCache = true; } updateNxJson(tree, nxJson); diff --git a/packages/nx/src/migrations/update-21-0-0/remove-custom-tasks-runner.md b/packages/nx/src/migrations/update-21-0-0/remove-custom-tasks-runner.md new file mode 100644 index 0000000000..2a6b8f3144 --- /dev/null +++ b/packages/nx/src/migrations/update-21-0-0/remove-custom-tasks-runner.md @@ -0,0 +1,33 @@ +#### Remove Custom Tasks Runners + +Removes `tasksRunnerOptions` entries from `nx.json` that contain custom tasks runners. In Nx 21, custom tasks runners are no longer functional. See /deprecated/custom-tasks-runner for more information. + +#### Sample Code Changes + +Removes custom task runner configuration from `nx.json`. + +{% tabs %} +{% tab label="Before" %} + +```json {% fileName="nx.json" %} +{ + "targetDefaults": {}, + "tasksRunnerOptions": { + "default": { + "runner": "custom-task-runner" + } + } +} +``` + +{% /tab %} +{% tab label="After" %} + +```json {% fileName="nx.json" %} +{ + "targetDefaults": {} +} +``` + +{% /tab %} +{% /tabs %} diff --git a/packages/nx/src/migrations/update-21-0-0/remove-custom-tasks-runner.spec.ts b/packages/nx/src/migrations/update-21-0-0/remove-custom-tasks-runner.spec.ts new file mode 100644 index 0000000000..01da16a3c3 --- /dev/null +++ b/packages/nx/src/migrations/update-21-0-0/remove-custom-tasks-runner.spec.ts @@ -0,0 +1,140 @@ +import { createTreeWithEmptyWorkspace } from '../../generators/testing-utils/create-tree-with-empty-workspace'; +import { Tree } from '../../generators/tree'; + +import update from './remove-custom-tasks-runner'; +import { readNxJson, updateNxJson } from '../../generators/utils/nx-json'; + +describe('remove custom tasks runners', () => { + let tree: Tree; + + beforeEach(() => { + tree = createTreeWithEmptyWorkspace(); + }); + + it('should remove all tasks runners that contain a custom runner', async () => { + updateNxJson(tree, { + tasksRunnerOptions: { + default: { + runner: 'nx-cloud', + options: { + cacheableOperations: ['build', 'lint'], + }, + }, + other: { + runner: 'some-other-runner', + options: { + cacheableOperations: ['test'], + }, + }, + custom: { + runner: 'custom-runner', + options: { + cacheableOperations: ['build', 'lint'], + }, + }, + }, + }); + await update(tree); + + expect(readNxJson(tree)).toMatchInlineSnapshot(` + { + "tasksRunnerOptions": { + "default": { + "options": { + "cacheableOperations": [ + "build", + "lint", + ], + }, + "runner": "nx-cloud", + }, + }, + } + `); + }); + + it('should remove whole tasksRunnerOptions if all runners are removed', async () => { + updateNxJson(tree, { + tasksRunnerOptions: { + default: { + runner: 'custom-runner', + options: { + cacheableOperations: ['build', 'lint'], + }, + }, + }, + }); + await update(tree); + expect(readNxJson(tree)).toMatchInlineSnapshot(`{}`); + }); + + it('should provide a link to the migration guide for nx-aws-cache', async () => { + updateNxJson(tree, { + tasksRunnerOptions: { + default: { + runner: '@nx-aws-cache/nx-aws-cache', + options: { + cacheableOperations: ['build', 'lint'], + }, + }, + }, + }); + const nextSteps = await update(tree); + expect(nextSteps).toMatchInlineSnapshot(` + [ + "Nx 21 removed support for custom task runners. For more information, please check: https://nx.dev/deprecated/custom-tasks-runner#migrating-from-nxawsplugin", + ] + `); + }); + + it('should not remove tasks runner if it is not custom', async () => { + updateNxJson(tree, { + tasksRunnerOptions: { + default: { + runner: 'nx-cloud', + options: { + cacheableOperations: ['build', 'lint'], + }, + }, + }, + }); + const nextSteps = await update(tree); + + expect(readNxJson(tree)).toMatchInlineSnapshot(` + { + "tasksRunnerOptions": { + "default": { + "options": { + "cacheableOperations": [ + "build", + "lint", + ], + }, + "runner": "nx-cloud", + }, + }, + } + `); + expect(nextSteps).toHaveLength(0); + }); + + it('should provide a link to the migration guide for other custom runners', async () => { + updateNxJson(tree, { + tasksRunnerOptions: { + default: { + runner: 'custom-runner', + options: { + cacheableOperations: ['build', 'lint'], + }, + }, + }, + }); + const nextSteps = await update(tree); + expect(nextSteps).toMatchInlineSnapshot(` + [ + "Nx 21 removed support for custom task runners. For more information, please check: https://nx.dev/deprecated/custom-tasks-runner", + ] + `); + expect(readNxJson(tree)).toMatchInlineSnapshot(`{}`); + }); +}); diff --git a/packages/nx/src/migrations/update-21-0-0/remove-custom-tasks-runner.ts b/packages/nx/src/migrations/update-21-0-0/remove-custom-tasks-runner.ts new file mode 100644 index 0000000000..888d46d60e --- /dev/null +++ b/packages/nx/src/migrations/update-21-0-0/remove-custom-tasks-runner.ts @@ -0,0 +1,47 @@ +import { Tree } from '../../generators/tree'; +import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available'; +import { readNxJson, updateNxJson } from '../../generators/utils/nx-json'; +import { NxJsonConfiguration } from '../../config/nx-json'; + +function isCustomRunnerPath(modulePath: string) { + return !['nx-cloud', '@nrwl/nx-cloud', 'nx/tasks-runners/default'].includes( + modulePath + ); +} + +export default async function update(tree: Tree) { + const nxJson = readNxJson(tree) as NxJsonConfiguration; + + if (!nxJson?.tasksRunnerOptions) { + return; + } + + const nextSteps: string[] = []; + + for (const key in nxJson.tasksRunnerOptions) { + const runner = nxJson.tasksRunnerOptions[key].runner; + + if (runner && isCustomRunnerPath(runner)) { + let nextStepText = + 'Nx 21 removed support for custom task runners. For more information, please check: '; + if (runner === '@nx-aws-cache/nx-aws-cache') { + nextStepText += + 'https://nx.dev/deprecated/custom-tasks-runner#migrating-from-nxawsplugin'; + } else { + nextStepText += 'https://nx.dev/deprecated/custom-tasks-runner'; + } + if (nextSteps.length === 0) { + nextSteps.push(nextStepText); + } + delete nxJson.tasksRunnerOptions[key]; + } + } + if (Object.keys(nxJson.tasksRunnerOptions).length === 0) { + delete nxJson.tasksRunnerOptions; + } + + updateNxJson(tree, nxJson); + + await formatChangedFilesWithPrettierIfAvailable(tree); + return nextSteps; +} diff --git a/packages/nx/src/migrations/update-21-0-0/remove-legacy-cache.md b/packages/nx/src/migrations/update-21-0-0/remove-legacy-cache.md new file mode 100644 index 0000000000..e98709c031 --- /dev/null +++ b/packages/nx/src/migrations/update-21-0-0/remove-legacy-cache.md @@ -0,0 +1,27 @@ +#### Use Legacy Cache + +Removes `useLegacyCache` from `nx.json` as it is no longer functional in Nx 21 + +#### Sample Code Changes + +{% tabs %} +{% tab label="Before" %} + +```json {% fileName="nx.json" %} +{ + "targetDefaults": {}, + "useLegacyCache": true +} +``` + +{% /tab %} +{% tab label="After" %} + +```json {% fileName="nx.json" %} +{ + "targetDefaults": {} +} +``` + +{% /tab %} +{% /tabs %} diff --git a/packages/nx/src/migrations/update-21-0-0/remove-legacy-cache.ts b/packages/nx/src/migrations/update-21-0-0/remove-legacy-cache.ts new file mode 100644 index 0000000000..89ec3aaca6 --- /dev/null +++ b/packages/nx/src/migrations/update-21-0-0/remove-legacy-cache.ts @@ -0,0 +1,21 @@ +import { Tree } from '../../generators/tree'; +import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available'; +import { readNxJson, updateNxJson } from '../../generators/utils/nx-json'; +import { NxJsonConfiguration } from '../../config/nx-json'; + +export default async function update(tree: Tree) { + const nxJson = readNxJson(tree) as NxJsonConfiguration; + + if (!nxJson) { + return; + } + + // If workspaces had `useLegacyCache` we can just delete the property as the property is not functional in nx v21 + if ((nxJson as any).useLegacyCache) { + delete (nxJson as any).useLegacyCache; + } + + updateNxJson(tree, nxJson); + + await formatChangedFilesWithPrettierIfAvailable(tree); +} diff --git a/packages/nx/src/tasks-runner/cache.ts b/packages/nx/src/tasks-runner/cache.ts index 41cd3bedaa..105792a798 100644 --- a/packages/nx/src/tasks-runner/cache.ts +++ b/packages/nx/src/tasks-runner/cache.ts @@ -37,32 +37,7 @@ export type CachedResult = { export type TaskWithCachedResult = { task: Task; cachedResult: CachedResult }; // This function is called once during tasks runner initialization. It checks if the db cache is enabled and logs a warning if it is not. -export function dbCacheEnabled(nxJson: NxJsonConfiguration = readNxJson()) { - // If the user has explicitly disabled the db cache, we can warn... - if ( - nxJson.useLegacyCache || - process.env.NX_DISABLE_DB === 'true' || - process.env.NX_DB_CACHE === 'false' - ) { - let readMoreLink = 'https://nx.dev/deprecated/legacy-cache'; - if ( - nxJson.tasksRunnerOptions?.default?.runner && - !['nx-cloud', 'nx/tasks-runners/default', '@nrwl/nx-cloud'].includes( - nxJson.tasksRunnerOptions.default.runner - ) - ) { - readMoreLink += '#tasksrunneroptions'; - } else if ( - process.env.NX_REJECT_UNKNOWN_LOCAL_CACHE === '0' || - process.env.NX_REJECT_UNKNOWN_LOCAL_CACHE === 'false' - ) { - readMoreLink += '#nxrejectunknownlocalcache'; - } - logger.warn( - `Nx is configured to use the legacy cache. This cache will be removed in Nx 21. Read more at ${readMoreLink}.` - ); - return false; - } +export function dbCacheEnabled() { // ...but if on wasm and the the db cache isnt supported we shouldn't warn if (IS_WASM) { return false; @@ -85,7 +60,7 @@ export function dbCacheEnabled(nxJson: NxJsonConfiguration = readNxJson()) { // Do not change the order of these arguments as this function is used by nx cloud export function getCache(options: DefaultTasksRunnerOptions): DbCache | Cache { const nxJson = readNxJson(); - return dbCacheEnabled(nxJson) + return dbCacheEnabled() ? new DbCache({ // Remove this in Nx 21 nxCloudRemoteCache: isNxCloudUsed(nxJson) ? options.remoteCache : null, diff --git a/packages/nx/src/tasks-runner/run-command.spec.ts b/packages/nx/src/tasks-runner/run-command.spec.ts index 3ba3648d88..57f07a4fa7 100644 --- a/packages/nx/src/tasks-runner/run-command.spec.ts +++ b/packages/nx/src/tasks-runner/run-command.spec.ts @@ -15,66 +15,6 @@ describe('getRunner', () => { mockRunner = jest.fn(); }); - it('gets a custom task runner', () => { - jest.mock('custom-runner', () => mockRunner, { - virtual: true, - }); - - nxJson.tasksRunnerOptions = { - custom: { - runner: 'custom-runner', - }, - }; - - const { tasksRunner, runnerOptions } = getRunner( - { runner: 'custom' }, - nxJson - ); - - expect(tasksRunner).toEqual(mockRunner); - }); - - it('gets a custom task runner with options', () => { - jest.mock('custom-runner2', () => mockRunner, { - virtual: true, - }); - - nxJson.tasksRunnerOptions = { - custom: { - runner: 'custom-runner2', - options: { - runnerOption: 'runner-option', - }, - }, - }; - - const { tasksRunner, runnerOptions } = getRunner( - { runner: 'custom' }, - nxJson - ); - expect(tasksRunner).toBe(mockRunner); - expect(runnerOptions).toEqual({ - runner: 'custom', - runnerOption: 'runner-option', - }); - }); - - it('gets a custom defined default task runner', () => { - jest.mock('custom-default-runner', () => mockRunner, { - virtual: true, - }); - - nxJson.tasksRunnerOptions = { - default: { - runner: 'custom-default-runner', - }, - }; - - const { tasksRunner } = getRunner({}, nxJson); - - expect(tasksRunner).toEqual(mockRunner); - }); - it('uses default runner when no tasksRunnerOptions are present', () => { jest.mock(join(__dirname, './default-tasks-runner.ts'), () => mockRunner); diff --git a/packages/nx/src/tasks-runner/run-command.ts b/packages/nx/src/tasks-runner/run-command.ts index 7913806d9a..76d46c62a4 100644 --- a/packages/nx/src/tasks-runner/run-command.ts +++ b/packages/nx/src/tasks-runner/run-command.ts @@ -1064,15 +1064,6 @@ export function getRunner( const modulePath: string = getTasksRunnerPath(runner, nxJson); try { - if (isCustomRunnerPath(modulePath)) { - output.warn({ - title: `Custom task runners will be replaced by a new API starting with Nx 21.`, - bodyLines: [ - `For more information, see https://nx.dev/deprecated/custom-tasks-runner`, - ], - }); - } - const tasksRunner = loadTasksRunner(modulePath); return { @@ -1095,20 +1086,14 @@ function getTasksRunnerPath( runner: string, nxJson: NxJsonConfiguration ) { - let modulePath: string = nxJson.tasksRunnerOptions?.[runner]?.runner; - - if (modulePath) { - if (isRelativePath(modulePath)) { - return join(workspaceRoot, modulePath); - } - return modulePath; - } - const isCloudRunner = // No tasksRunnerOptions for given --runner nxJson.nxCloudAccessToken || // No runner prop in tasks runner options, check if access token is set. nxJson.tasksRunnerOptions?.[runner]?.options?.accessToken || + ['nx-cloud', '@nrwl/nx-cloud'].includes( + nxJson.tasksRunnerOptions?.[runner]?.runner + ) || // Cloud access token specified in env var. process.env.NX_CLOUD_ACCESS_TOKEN || // Nx Cloud ID specified in nxJson @@ -1177,12 +1162,3 @@ export function getRunnerOptions( return result; } - -function isCustomRunnerPath(modulePath: string) { - return ![ - 'nx-cloud', - '@nrwl/nx-cloud', - 'nx/tasks-runners/default', - defaultTasksRunnerPath, - ].includes(modulePath); -} diff --git a/packages/nx/src/tasks-runner/task-orchestrator.ts b/packages/nx/src/tasks-runner/task-orchestrator.ts index c08607dac5..75a8f13f82 100644 --- a/packages/nx/src/tasks-runner/task-orchestrator.ts +++ b/packages/nx/src/tasks-runner/task-orchestrator.ts @@ -290,7 +290,7 @@ export class TaskOrchestrator { // No output files to restore !!outputs.length && // Remote caches are restored to output dirs when applied and using db cache - (!cachedResult.remote || !dbCacheEnabled(this.nxJson)) && + (!cachedResult.remote || !dbCacheEnabled()) && // Output files have not been touched since last run (await this.shouldCopyOutputsFromCache(outputs, task.hash)); if (shouldCopyOutputsFromCache) {