|
1 |
| -import { promises as fs, realpathSync, statSync } from 'node:fs' |
| 1 | +import { existsSync, promises as fs, realpathSync, statSync } from 'node:fs' |
2 | 2 | import path from 'node:path'
|
3 | 3 | import process from 'node:process'
|
4 | 4 |
|
@@ -191,30 +191,39 @@ export function findBinPathDetailsSync(binName: string): {
|
191 | 191 | }
|
192 | 192 |
|
193 | 193 | export function findNpmPathSync(npmBinPath: string): string | undefined {
|
194 |
| - let curPath = npmBinPath |
| 194 | + let thePath = npmBinPath |
195 | 195 | while (true) {
|
| 196 | + const nmPath = path.join(thePath, NODE_MODULES) |
196 | 197 | if (
|
197 | 198 | // npm bin paths may look like:
|
198 | 199 | // /usr/local/share/npm/bin/npm
|
199 | 200 | // /Users/SomeUsername/.nvm/versions/node/vX.X.X/bin/npm
|
200 | 201 | // C:\Users\SomeUsername\AppData\Roaming\npm\bin\npm.cmd
|
201 | 202 | // OR
|
202 | 203 | // C:\Program Files\nodejs\npm.cmd
|
203 |
| - path.basename(curPath) === NPM || |
| 204 | + // |
204 | 205 | // In all cases the npm path contains a node_modules folder:
|
205 | 206 | // /usr/local/share/npm/bin/npm/node_modules
|
206 | 207 | // 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`)))) |
210 | 219 | ) {
|
211 |
| - return curPath |
| 220 | + return thePath |
212 | 221 | }
|
213 |
| - const parent = path.dirname(curPath) |
214 |
| - if (parent === curPath) { |
| 222 | + const parent = path.dirname(thePath) |
| 223 | + if (parent === thePath) { |
215 | 224 | return undefined
|
216 | 225 | }
|
217 |
| - curPath = parent |
| 226 | + thePath = parent |
218 | 227 | }
|
219 | 228 | }
|
220 | 229 |
|
|
0 commit comments