fix: misleading "command not found" error message (#6952)

It was caused by `which` not working correctly

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
Khải
2023-08-17 20:44:44 +07:00
committed by GitHub
parent 512d712540
commit ce3f1712b2
2 changed files with 25 additions and 10 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/plugin-commands-script-runners": patch
---
Fix misleading "command not found" error message.

View File

@@ -8,6 +8,7 @@ import { sortPackages } from '@pnpm/sort-packages'
import { type Project, type ProjectsGraph } from '@pnpm/types'
import execa from 'execa'
import pLimit from 'p-limit'
import PATH from 'path-name'
import pick from 'ramda/src/pick'
import renderHelp from 'render-help'
import { existsInDir } from './existsInDir'
@@ -180,6 +181,10 @@ export async function handler (
const workspacePnpPath = opts.workspaceDir && await existsPnp(opts.workspaceDir)
let exitCode = 0
const prependPaths = [
'./node_modules/.bin',
...opts.extraBinPaths,
]
for (const chunk of chunks) {
// eslint-disable-next-line no-await-in-loop
await Promise.all(chunk.map(async (prefix: string) =>
@@ -197,10 +202,7 @@ export async function handler (
...extraEnv,
PNPM_PACKAGE_NAME: opts.selectedProjectsGraph[prefix]?.package.manifest.name,
},
prependPaths: [
'./node_modules/.bin',
...opts.extraBinPaths,
],
prependPaths,
userAgent: opts.userAgent,
})
await execa(params[0], params.slice(1), {
@@ -212,7 +214,7 @@ export async function handler (
result[prefix].status = 'passed'
result[prefix].duration = getExecutionDuration(startTime)
} catch (err: any) { // eslint-disable-line
if (await isErrorCommandNotFound(params[0], err)) {
if (isErrorCommandNotFound(params[0], err, prependPaths)) {
err.message = `Command "${params[0]}" not found`
err.hint = await createExecCommandNotFoundHint(params[0], {
implicitlyFellbackFromRun: opts.implicitlyFellbackFromRun ?? false,
@@ -306,13 +308,21 @@ interface CommandError extends Error {
shortMessage: string
}
async function isErrorCommandNotFound (command: string, error: CommandError) {
function isErrorCommandNotFound (command: string, error: CommandError, prependPaths: string[]) {
// Mac/Linux
if (error.originalMessage === `spawn ${command} ENOENT`) {
return true
if (process.platform === 'linux' || process.platform === 'darwin') {
return error.originalMessage === `spawn ${command} ENOENT`
}
// Windows
return error.shortMessage === `Command failed with exit code 1: ${command}` &&
!(await which(command, { nothrow: true }))
if (process.platform === 'win32') {
const prepend = prependPaths.join(path.delimiter)
const whichPath = process.env[PATH] ? `${prepend}${path.delimiter}${process.env[PATH] as string}` : prepend
return !which.sync(command, {
nothrow: true,
path: whichPath,
})
}
return false
}