mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-06 08:18:16 -05:00
fix(exec): pnpm exec should return the correct exit code (#3996)
close #3994
This commit is contained in:
6
.changeset/gorgeous-suns-add.md
Normal file
6
.changeset/gorgeous-suns-add.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-script-runners": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
`pnpm exec` should exit with the exit code of the child process. This fixes a regression introduced in pnpm v6.20.4 via [#3951](https://github.com/pnpm/pnpm/pull/3951).
|
||||
@@ -110,6 +110,7 @@ export async function handler (
|
||||
const existsPnp = existsInDir.bind(null, '.pnp.cjs')
|
||||
const workspacePnpPath = opts.workspaceDir && await existsPnp(opts.workspaceDir)
|
||||
|
||||
let exitCode = 0
|
||||
for (const chunk of chunks) {
|
||||
await Promise.all(chunk.map(async (prefix: string) =>
|
||||
limitRun(async () => {
|
||||
@@ -135,9 +136,8 @@ export async function handler (
|
||||
result.passes++
|
||||
} catch (err: any) { // eslint-disable-line
|
||||
if (!opts.recursive && typeof err.exitCode === 'number') {
|
||||
return {
|
||||
exitCode: err.exitCode,
|
||||
}
|
||||
exitCode = err.exitCode
|
||||
return
|
||||
}
|
||||
logger.info(err)
|
||||
|
||||
@@ -156,10 +156,10 @@ export async function handler (
|
||||
/* eslint-enable @typescript-eslint/dot-notation */
|
||||
throw err
|
||||
}
|
||||
return { exitCode: 0 }
|
||||
}
|
||||
)))
|
||||
}
|
||||
|
||||
throwOnCommandFail('pnpm recursive exec', result)
|
||||
return { exitCode }
|
||||
}
|
||||
|
||||
@@ -135,8 +135,7 @@ export async function handler (
|
||||
const [scriptName, ...passedThruArgs] = params
|
||||
if (opts.recursive) {
|
||||
if (scriptName || Object.keys(opts.selectedProjectsGraph).length > 1) {
|
||||
await runRecursive(params, opts)
|
||||
return
|
||||
return runRecursive(params, opts)
|
||||
}
|
||||
dir = Object.keys(opts.selectedProjectsGraph)[0]
|
||||
} else {
|
||||
@@ -153,11 +152,10 @@ export async function handler (
|
||||
if (opts.ifPresent) return
|
||||
if (opts.fallbackCommandUsed) {
|
||||
if (opts.argv == null) throw new Error('Could not fallback because opts.argv.original was not passed to the script runner')
|
||||
await exec({
|
||||
return exec({
|
||||
selectedProjectsGraph: {},
|
||||
...opts,
|
||||
}, opts.argv.original.slice(1))
|
||||
return
|
||||
}
|
||||
if (opts.workspaceDir) {
|
||||
const { manifest: rootManifest } = await tryReadProjectManifest(opts.workspaceDir, opts)
|
||||
|
||||
@@ -2,7 +2,7 @@ import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import PnpmError from '@pnpm/error'
|
||||
import { readProjects } from '@pnpm/filter-workspace-packages'
|
||||
import { exec } from '@pnpm/plugin-commands-script-runners'
|
||||
import { exec, run } from '@pnpm/plugin-commands-script-runners'
|
||||
import prepare, { prepareEmpty, preparePackages } from '@pnpm/prepare'
|
||||
import rimraf from '@zkochan/rimraf'
|
||||
import execa from 'execa'
|
||||
@@ -370,6 +370,36 @@ test('pnpm exec on single project', async () => {
|
||||
expect(outputs).toStrictEqual([])
|
||||
})
|
||||
|
||||
test('pnpm exec on single project should return non-zero exit code when the process fails', async () => {
|
||||
prepare({})
|
||||
|
||||
{
|
||||
const { exitCode } = await exec.handler({
|
||||
...DEFAULT_OPTS,
|
||||
dir: process.cwd(),
|
||||
recursive: false,
|
||||
selectedProjectsGraph: {},
|
||||
}, ['node', '-e', 'process.exitCode=1'])
|
||||
|
||||
expect(exitCode).toBe(1)
|
||||
}
|
||||
|
||||
{
|
||||
const runResult = await run.handler({
|
||||
...DEFAULT_OPTS,
|
||||
argv: {
|
||||
original: ['pnpm', 'node', '-e', 'process.exitCode=1'],
|
||||
},
|
||||
dir: process.cwd(),
|
||||
fallbackCommandUsed: true,
|
||||
recursive: false,
|
||||
selectedProjectsGraph: {},
|
||||
}, ['node'])
|
||||
|
||||
expect(runResult['exitCode']).toBe(1)
|
||||
}
|
||||
})
|
||||
|
||||
test('pnpm exec outside of projects', async () => {
|
||||
prepareEmpty()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user