From 19c4b4f9737491acaf1a80ac8a1e65f66e7d5351 Mon Sep 17 00:00:00 2001 From: Steven Petryk Date: Mon, 12 Feb 2024 10:52:18 -0800 Subject: [PATCH] fix(get-context): avoid excess purge prompts (#7639) * fix(get-context): avoid excess purge prompts pnpm sometimes needs to purge modules folders (node_modules) when certain configuration changes (in other words, when it needs to start from scratch). This prompt, problematically, was getting triggered asynchronously for each importer in the workspace that needed a purge, which would sometimes lead to gargantuan prompts instead of one consolidated prompt. The fix is to queue up which importers need a purge, then fire the prompter all at once. Closes #7320 * fix: reuse ImporterToPurge type * refactor: apply suggestions from code review --------- Co-authored-by: Zoltan Kochan --- .changeset/lemon-windows-tickle.md | 6 +++++ pkg-manager/get-context/src/index.ts | 38 +++++++++++++++------------- 2 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 .changeset/lemon-windows-tickle.md diff --git a/.changeset/lemon-windows-tickle.md b/.changeset/lemon-windows-tickle.md new file mode 100644 index 0000000000..a82c7f97f6 --- /dev/null +++ b/.changeset/lemon-windows-tickle.md @@ -0,0 +1,6 @@ +--- +"@pnpm/get-context": patch +"pnpm": patch +--- + +When purging multiple node_modules folders, pnpm will no longer print multiple prompts simultaneously. diff --git a/pkg-manager/get-context/src/index.ts b/pkg-manager/get-context/src/index.ts index 4d206930b9..a1b7c753e8 100644 --- a/pkg-manager/get-context/src/index.ts +++ b/pkg-manager/get-context/src/index.ts @@ -101,6 +101,10 @@ export interface GetContextOptions { forcePublicHoistPattern?: boolean global?: boolean } +interface ImporterToPurge { + modulesDir: string + rootDir: string +} export async function getContext ( opts: GetContextOptions @@ -243,7 +247,9 @@ async function validateModules ( ' Run "pnpm install" to recreate the modules directory.' ) } - let purged = false + + const importersToPurge: ImporterToPurge[] = [] + if (opts.forceHoistPattern && (rootProject != null)) { try { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing @@ -256,11 +262,10 @@ async function validateModules ( } } catch (err: any) { // eslint-disable-line if (!opts.forceNewModules) throw err - await purgeModulesDirsOfImporter(opts, rootProject) - purged = true + importersToPurge.push(rootProject) } } - await Promise.all(projects.map(async (project) => { + for (const project of projects) { try { checkCompatibility(modules, { modulesDir: project.modulesDir, @@ -279,16 +284,21 @@ async function validateModules ( } } catch (err: any) { // eslint-disable-line if (!opts.forceNewModules) throw err - await purgeModulesDirsOfImporter(opts, project) - purged = true + importersToPurge.push(project) } - })) - if (purged && (rootProject == null)) { - await purgeModulesDirsOfImporter(opts, { + } + if (importersToPurge.length > 0 && (rootProject == null)) { + importersToPurge.push({ modulesDir: path.join(opts.lockfileDir, opts.modulesDir), rootDir: opts.lockfileDir, }) } + + const purged = importersToPurge.length > 0 + if (purged) { + await purgeModulesDirsOfImporters(opts, importersToPurge) + } + return { purged } } @@ -297,10 +307,7 @@ async function purgeModulesDirsOfImporter ( confirmModulesPurge?: boolean virtualStoreDir: string }, - importer: { - modulesDir: string - rootDir: string - } + importer: ImporterToPurge ) { return purgeModulesDirsOfImporters(opts, [importer]) } @@ -310,10 +317,7 @@ async function purgeModulesDirsOfImporters ( confirmModulesPurge?: boolean virtualStoreDir: string }, - importers: Array<{ - modulesDir: string - rootDir: string - }> + importers: ImporterToPurge[] ) { if (opts.confirmModulesPurge ?? true) { const confirmed = await enquirer.prompt({