mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-10 18:18:56 -04:00
5
.changeset/lemon-lizards-sneeze.md
Normal file
5
.changeset/lemon-lizards-sneeze.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/global-bin-dir": patch
|
||||
---
|
||||
|
||||
When searching a suitable global executables directory, take any directory from the PATH that has a node, pnpm, or npm command in it.
|
||||
@@ -1,5 +1,6 @@
|
||||
import PnpmError from '@pnpm/error'
|
||||
import { sync as canWriteToDir } from 'can-write-to-dir'
|
||||
import fs = require('fs')
|
||||
import path = require('path')
|
||||
import PATH = require('path-name')
|
||||
|
||||
@@ -28,7 +29,8 @@ function pickBestGlobalBinDir (dirs: string[], knownCandidates: string[]) {
|
||||
isUnderDir('nodejs', lowCaseDir) ||
|
||||
isUnderDir('npm', lowCaseDir) ||
|
||||
isUnderDir('pnpm', lowCaseDir) ||
|
||||
knownCandidates.some((candidate) => areDirsEqual(candidate, dir))
|
||||
knownCandidates.some((candidate) => areDirsEqual(candidate, dir)) ||
|
||||
dirHasNodeRelatedCommand(dir)
|
||||
) {
|
||||
if (canWriteToDirAndExists(dir)) return dir
|
||||
noWriteAccessDirs.push(dir)
|
||||
@@ -45,6 +47,18 @@ ${noWriteAccessDirs.join('\n')}`,
|
||||
})
|
||||
}
|
||||
|
||||
const NODE_RELATED_COMMANDS = new Set(['pnpm', 'npm', 'node'])
|
||||
|
||||
function dirHasNodeRelatedCommand (dir: string) {
|
||||
try {
|
||||
const files = fs.readdirSync(dir)
|
||||
return files.map((file) => file.toLowerCase())
|
||||
.some((file) => NODE_RELATED_COMMANDS.has(file.split('.')[0]))
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function isUnderDir (dir: string, target: string) {
|
||||
target = target.endsWith(path.sep) ? target : `${target}${path.sep}`
|
||||
return target.includes(`${path.sep}${dir}${path.sep}`) ||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import PnpmError from '@pnpm/error'
|
||||
import { sync as _canWriteToDir } from 'can-write-to-dir'
|
||||
import fs = require('fs')
|
||||
import isWindows = require('is-windows')
|
||||
import path = require('path')
|
||||
import proxiquire = require('proxyquire')
|
||||
@@ -11,12 +12,16 @@ const makePath =
|
||||
: (...paths: string[]) => `/${path.join(...paths)}`
|
||||
|
||||
let canWriteToDir!: typeof _canWriteToDir
|
||||
let readdirSync = (dir: string) => [] as string[]
|
||||
const FAKE_PATH = 'FAKE_PATH'
|
||||
|
||||
const globalBinDir = proxiquire('../lib/index.js', {
|
||||
'can-write-to-dir': {
|
||||
sync: (dir: string) => canWriteToDir(dir),
|
||||
},
|
||||
'fs': {
|
||||
readdirSync: (dir: string) => readdirSync(dir),
|
||||
},
|
||||
'path-name': FAKE_PATH,
|
||||
}).default
|
||||
|
||||
@@ -130,3 +135,37 @@ test('prefer a directory that has "Node" in the path', (t) => {
|
||||
process.env[FAKE_PATH] = pathEnv
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('select a directory that has a node command in it', (t) => {
|
||||
const dir1 = makePath('foo')
|
||||
const dir2 = makePath('bar')
|
||||
const pathEnv = process.env[FAKE_PATH]
|
||||
process.env[FAKE_PATH] = [
|
||||
dir1,
|
||||
dir2,
|
||||
].join(path.delimiter)
|
||||
|
||||
canWriteToDir = () => true
|
||||
readdirSync = (dir) => dir === dir2 ? ['node'] : []
|
||||
t.equal(globalBinDir(), dir2)
|
||||
|
||||
process.env[FAKE_PATH] = pathEnv
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('select a directory that has a node.bat command in it', (t) => {
|
||||
const dir1 = makePath('foo')
|
||||
const dir2 = makePath('bar')
|
||||
const pathEnv = process.env[FAKE_PATH]
|
||||
process.env[FAKE_PATH] = [
|
||||
dir1,
|
||||
dir2,
|
||||
].join(path.delimiter)
|
||||
|
||||
canWriteToDir = () => true
|
||||
readdirSync = (dir) => dir === dir2 ? ['node.bat'] : []
|
||||
t.equal(globalBinDir(), dir2)
|
||||
|
||||
process.env[FAKE_PATH] = pathEnv
|
||||
t.end()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user