From 529df9ac2338478eecefe1fa5098ffff500ae1e8 Mon Sep 17 00:00:00 2001 From: David Michon Date: Wed, 20 Aug 2025 01:11:27 +0000 Subject: [PATCH] [rush] Fix performance in findOrphanedProjects --- .../rush/tune-prepare-async_2025-08-20-01-11.json | 10 ++++++++++ .../rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts | 12 ++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 common/changes/@microsoft/rush/tune-prepare-async_2025-08-20-01-11.json diff --git a/common/changes/@microsoft/rush/tune-prepare-async_2025-08-20-01-11.json b/common/changes/@microsoft/rush/tune-prepare-async_2025-08-20-01-11.json new file mode 100644 index 00000000000..1c81c3b8f20 --- /dev/null +++ b/common/changes/@microsoft/rush/tune-prepare-async_2025-08-20-01-11.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush", + "comment": "Fix poor performance scaling during `rush install` when identifying projects in the lockfile that no longer exist.", + "type": "none" + } + ], + "packageName": "@microsoft/rush" +} \ No newline at end of file diff --git a/libraries/rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts b/libraries/rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts index 6f03421a064..e6ba5b3a8d0 100644 --- a/libraries/rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts +++ b/libraries/rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts @@ -42,6 +42,7 @@ import type { ResolvedDependencies } from '@pnpm/lockfile.types'; import { convertLockfileV9ToLockfileObject } from './PnpmShrinkWrapFileConverters'; +import type { IReadonlyLookupByPath } from '@rushstack/lookup-by-path'; const yamlModule: typeof import('js-yaml') = Import.lazy('js-yaml', require); @@ -812,12 +813,15 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { return super.findOrphanedProjects(rushConfiguration, subspace); } + const subspaceTempFolder: string = subspace.getSubspaceTempFolderPath(); + const lookup: IReadonlyLookupByPath = + rushConfiguration.getProjectLookupForRoot(subspaceTempFolder); + const orphanedProjectPaths: string[] = []; for (const importerKey of this.getImporterKeys()) { - // PNPM importer keys are relative paths from the workspace root, which is the common temp folder - const rushProjectPath: string = path.resolve(subspace.getSubspaceTempFolderPath(), importerKey); - if (!rushConfiguration.tryGetProjectForPath(rushProjectPath)) { - orphanedProjectPaths.push(rushProjectPath); + if (!lookup.findChildPath(importerKey)) { + // PNPM importer keys are relative paths from the workspace root, which is the common temp folder + orphanedProjectPaths.push(path.resolve(subspaceTempFolder, importerKey)); } } return orphanedProjectPaths;