From 2c0b91d6b976c7be9655d472dedecf38c497860e Mon Sep 17 00:00:00 2001 From: Scarab Systems Date: Wed, 10 Jun 2026 05:46:23 -0400 Subject: [PATCH] fix(exec): skip deps auto-install without manifest (#12301) --- .changeset/deps-status-no-manifest.md | 6 ++ exec/commands/src/runDepsStatusCheck.ts | 3 +- exec/commands/test/runDepsStatusCheck.test.ts | 75 +++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 .changeset/deps-status-no-manifest.md create mode 100644 exec/commands/test/runDepsStatusCheck.test.ts diff --git a/.changeset/deps-status-no-manifest.md b/.changeset/deps-status-no-manifest.md new file mode 100644 index 0000000000..8a4e524167 --- /dev/null +++ b/.changeset/deps-status-no-manifest.md @@ -0,0 +1,6 @@ +--- +"@pnpm/exec.commands": patch +"pnpm": patch +--- + +Avoid running dependency-status auto-install when the dependency status is unavailable without a project manifest. diff --git a/exec/commands/src/runDepsStatusCheck.ts b/exec/commands/src/runDepsStatusCheck.ts index 85f1f97c64..37de0897cd 100644 --- a/exec/commands/src/runDepsStatusCheck.ts +++ b/exec/commands/src/runDepsStatusCheck.ts @@ -18,7 +18,8 @@ export async function runDepsStatusCheck (opts: RunDepsStatusCheckOptions): Prom opts.ignoredWorkspaceStateSettings = ignoredWorkspaceStateSettings const { upToDate, issue, workspaceState } = await checkDepsStatus(opts) - if (upToDate) return + if (upToDate === true) return + if (upToDate === undefined && opts.allProjects == null && opts.rootProjectManifest == null) return const command = ['install', ...createInstallArgs(workspaceState?.settings)] const install = runPnpmCli.bind(null, command, { cwd: opts.dir, reporter: opts.reporter }) diff --git a/exec/commands/test/runDepsStatusCheck.test.ts b/exec/commands/test/runDepsStatusCheck.test.ts new file mode 100644 index 0000000000..df0b4070c0 --- /dev/null +++ b/exec/commands/test/runDepsStatusCheck.test.ts @@ -0,0 +1,75 @@ +import { beforeEach, expect, jest, test } from '@jest/globals' +import type { checkDepsStatus as checkDepsStatusFn } from '@pnpm/deps.status' +import type { runPnpmCli as runPnpmCliFn } from '@pnpm/exec.pnpm-cli-runner' + +const checkDepsStatus = jest.fn() +const runPnpmCli = jest.fn() + +jest.unstable_mockModule('@pnpm/deps.status', () => ({ + checkDepsStatus, +})) + +jest.unstable_mockModule('@pnpm/exec.pnpm-cli-runner', () => ({ + runPnpmCli, +})) + +jest.unstable_mockModule('@pnpm/logger', () => ({ + globalWarn: jest.fn(), +})) + +jest.unstable_mockModule('@inquirer/prompts', () => ({ + confirm: jest.fn(), +})) + +const { runDepsStatusCheck } = await import('../src/runDepsStatusCheck.js') + +beforeEach(() => { + checkDepsStatus.mockReset() + runPnpmCli.mockReset() +}) + +test('does not install when dependency status is unavailable without a project manifest', async () => { + checkDepsStatus.mockResolvedValue({ + upToDate: undefined, + issue: 'No package manifest found. Skipping check.', + workspaceState: undefined, + }) + + await runDepsStatusCheck({ + dir: process.cwd(), + excludeLinksFromLockfile: false, + linkWorkspacePackages: false, + preferWorkspacePackages: false, + pnpmfile: [], + rootProjectManifestDir: process.cwd(), + verifyDepsBeforeRun: 'install', + }) + + expect(runPnpmCli).not.toHaveBeenCalled() +}) + +test('installs when dependency status is unavailable for an unexpected reason', async () => { + checkDepsStatus.mockResolvedValue({ + upToDate: undefined, + issue: 'Cannot verify dependency status', + workspaceState: undefined, + }) + + await runDepsStatusCheck({ + dir: process.cwd(), + excludeLinksFromLockfile: false, + linkWorkspacePackages: false, + pnpmfile: [], + preferWorkspacePackages: false, + rootProjectManifest: { + name: 'root', + }, + rootProjectManifestDir: process.cwd(), + verifyDepsBeforeRun: 'install', + }) + + expect(runPnpmCli).toHaveBeenCalledWith(['install'], { + cwd: process.cwd(), + reporter: undefined, + }) +})