Skip to content

Commit 9013f2b

Browse files
committed
Fix findNpmPathSync resolution
1 parent 21f5f8e commit 9013f2b

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

src/utils/path-resolve.ts

+19-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { promises as fs, realpathSync, statSync } from 'node:fs'
1+
import { existsSync, promises as fs, realpathSync, statSync } from 'node:fs'
22
import path from 'node:path'
33
import process from 'node:process'
44

@@ -191,30 +191,39 @@ export function findBinPathDetailsSync(binName: string): {
191191
}
192192

193193
export function findNpmPathSync(npmBinPath: string): string | undefined {
194-
let curPath = npmBinPath
194+
let thePath = npmBinPath
195195
while (true) {
196+
const nmPath = path.join(thePath, NODE_MODULES)
196197
if (
197198
// npm bin paths may look like:
198199
// /usr/local/share/npm/bin/npm
199200
// /Users/SomeUsername/.nvm/versions/node/vX.X.X/bin/npm
200201
// C:\Users\SomeUsername\AppData\Roaming\npm\bin\npm.cmd
201202
// OR
202203
// C:\Program Files\nodejs\npm.cmd
203-
path.basename(curPath) === NPM ||
204+
//
204205
// In all cases the npm path contains a node_modules folder:
205206
// /usr/local/share/npm/bin/npm/node_modules
206207
// C:\Program Files\nodejs\node_modules
207-
statSync(path.join(curPath, NODE_MODULES), {
208-
throwIfNoEntry: false
209-
})?.isDirectory()
208+
//
209+
// Use existsSync here because statsSync, even with { throwIfNoEntry: false },
210+
// will throw an ENOTDIR error for paths like ./a-file-that-exists/a-directory-that-does-not.
211+
// See https://github.com/nodejs/node/issues/56993.
212+
existsSync(nmPath) &&
213+
statSync(nmPath, { throwIfNoEntry: false })?.isDirectory() &&
214+
// Optimistically look for the default location.
215+
(path.basename(thePath) === NPM ||
216+
// Chocolatey installs npm bins in the same directory as node bins.
217+
// Lazily access constants.WIN32.
218+
(constants.WIN32 && existsSync(path.join(thePath, `${NPM}.cmd`))))
210219
) {
211-
return curPath
220+
return thePath
212221
}
213-
const parent = path.dirname(curPath)
214-
if (parent === curPath) {
222+
const parent = path.dirname(thePath)
223+
if (parent === thePath) {
215224
return undefined
216225
}
217-
curPath = parent
226+
thePath = parent
218227
}
219228
}
220229

0 commit comments

Comments
 (0)