diff --git a/.changeset/fix-verify-deps-silent-install.md b/.changeset/fix-verify-deps-silent-install.md new file mode 100644 index 0000000000..32306f6c5e --- /dev/null +++ b/.changeset/fix-verify-deps-silent-install.md @@ -0,0 +1,7 @@ +--- +"@pnpm/exec.commands": patch +"@pnpm/exec.pnpm-cli-runner": patch +"pnpm": patch +--- + +Honor `--silent` when `verifyDepsBeforeRun: install` auto-installs dependencies before `pnpm run` or `pnpm exec`, preventing install output from being written to stdout [#11636](https://github.com/pnpm/pnpm/issues/11636). diff --git a/exec/commands/src/exec.ts b/exec/commands/src/exec.ts index 330f0ad89e..b11736395d 100644 --- a/exec/commands/src/exec.ts +++ b/exec/commands/src/exec.ts @@ -156,6 +156,7 @@ export type ExecOpts = Required> & | 'nodeOptions' | 'pnpmHomeDir' | 'recursive' +| 'reporter' | 'reporterHidePrefix' | 'userAgent' | 'verifyDepsBeforeRun' diff --git a/exec/commands/src/runDepsStatusCheck.ts b/exec/commands/src/runDepsStatusCheck.ts index 900fcc7189..136db411ba 100644 --- a/exec/commands/src/runDepsStatusCheck.ts +++ b/exec/commands/src/runDepsStatusCheck.ts @@ -1,4 +1,4 @@ -import type { VerifyDepsBeforeRun } from '@pnpm/config.reader' +import type { Config, VerifyDepsBeforeRun } from '@pnpm/config.reader' import { checkDepsStatus, type CheckDepsStatusOptions, type WorkspaceStateSettings } from '@pnpm/deps.status' import { PnpmError } from '@pnpm/error' import { runPnpmCli } from '@pnpm/exec.pnpm-cli-runner' @@ -7,6 +7,7 @@ import enquirer from 'enquirer' export interface RunDepsStatusCheckOptions extends CheckDepsStatusOptions { dir: string + reporter?: Config['reporter'] verifyDepsBeforeRun?: VerifyDepsBeforeRun } @@ -20,7 +21,7 @@ export async function runDepsStatusCheck (opts: RunDepsStatusCheckOptions): Prom if (upToDate) return const command = ['install', ...createInstallArgs(workspaceState?.settings)] - const install = runPnpmCli.bind(null, command, { cwd: opts.dir }) + const install = runPnpmCli.bind(null, command, { cwd: opts.dir, reporter: opts.reporter }) switch (opts.verifyDepsBeforeRun) { case 'install': diff --git a/exec/pnpm-cli-runner/src/index.ts b/exec/pnpm-cli-runner/src/index.ts index 9161af10bd..9df02756f4 100644 --- a/exec/pnpm-cli-runner/src/index.ts +++ b/exec/pnpm-cli-runner/src/index.ts @@ -2,17 +2,23 @@ import path from 'node:path' import { sync as execSync } from 'execa' -export function runPnpmCli (command: string[], { cwd }: { cwd: string }): void { +export interface RunPnpmCliOptions { + cwd: string + reporter?: string +} + +export function runPnpmCli (command: string[], { cwd, reporter }: RunPnpmCliOptions): void { const execOpts = { cwd, stdio: 'inherit' as const, } + const cliCommand = reporter ? [...command, `--reporter=${reporter}`] : command const execFileName = path.basename(process.execPath).toLowerCase() if (execFileName === 'pnpm' || execFileName === 'pnpm.exe') { - execSync(process.execPath, command, execOpts) + execSync(process.execPath, cliCommand, execOpts) } else if (path.basename(process.argv[1]) === 'pnpm.mjs') { - execSync(process.execPath, [process.argv[1], ...command], execOpts) + execSync(process.execPath, [process.argv[1], ...cliCommand], execOpts) } else { - execSync('pnpm', command, execOpts) + execSync('pnpm', cliCommand, execOpts) } } diff --git a/pnpm/test/exec.ts b/pnpm/test/exec.ts index eb4cc883b1..08023d63b9 100644 --- a/pnpm/test/exec.ts +++ b/pnpm/test/exec.ts @@ -3,6 +3,7 @@ import path from 'node:path' import { expect, test } from '@jest/globals' import { prepare } from '@pnpm/prepare' +import { writeYamlFileSync } from 'write-yaml-file' import { execPnpm, execPnpmSync } from './utils/index.js' @@ -30,3 +31,17 @@ test("exec should respect the caller's current working directory", async () => { expect(fs.readFileSync(cmdFilePath, 'utf8')).toBe(subdirPath) }) + +test('silent exec does not print verifyDepsBeforeRun install output', async () => { + prepare({}) + writeYamlFileSync('pnpm-workspace.yaml', { + verifyDepsBeforeRun: 'install', + }) + + const result = execPnpmSync(['--silent', 'exec', 'node', '-e', 'process.stdout.write("hi")'], { + expectSuccess: true, + omitEnvDefaults: ['pnpm_config_silent'], + }) + + expect(result.stdout.toString()).toBe('hi') +}) diff --git a/pnpm/test/run.ts b/pnpm/test/run.ts index 5a2fa4e9fd..e531c7d5de 100644 --- a/pnpm/test/run.ts +++ b/pnpm/test/run.ts @@ -140,6 +140,24 @@ test('silent run only prints the output of the child process', async () => { expect(result.stdout.toString().trim()).toBe('hi') }) +test('silent run does not print verifyDepsBeforeRun install output', async () => { + prepare({ + scripts: { + hi: 'echo hi', + }, + }) + writeYamlFileSync('pnpm-workspace.yaml', { + verifyDepsBeforeRun: 'install', + }) + + const result = execPnpmSync(['run', '--silent', 'hi'], { + expectSuccess: true, + omitEnvDefaults: ['pnpm_config_silent'], + }) + + expect(result.stdout.toString().trim()).toBe('hi') +}) + testOnPosix('pnpm run with preferSymlinkedExecutables true', async () => { prepare({ scripts: {