mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-24 07:38:12 -05:00
feat(config): support custom global bin dir (#3762)
New setting supported: `global-bin-dir`
This commit is contained in:
5
.changeset/cuddly-ads-camp.md
Normal file
5
.changeset/cuddly-ads-camp.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/config": minor
|
||||
---
|
||||
|
||||
New setting added: `global-bin-dir`. `global-bin-dir` allows to set the target directory for the bin files of globally installed packages.
|
||||
@@ -49,6 +49,7 @@ export const types = Object.assign({
|
||||
'frozen-lockfile': Boolean,
|
||||
'frozen-shrinkwrap': Boolean,
|
||||
'git-checks': Boolean,
|
||||
'global-bin-dir': String,
|
||||
'global-dir': String,
|
||||
'global-path': String,
|
||||
'global-pnpmfile': String,
|
||||
@@ -275,13 +276,19 @@ export default async (
|
||||
: path.join(firstWithWriteAccess([npmGlobalPrefix, os.homedir()]), PNPM_GLOBAL)
|
||||
pnpmConfig.dir = path.join(globalDirRoot, LAYOUT_VERSION.toString())
|
||||
|
||||
pnpmConfig.bin = cliOptions.dir
|
||||
? (
|
||||
process.platform === 'win32'
|
||||
? cliOptions.dir
|
||||
: path.resolve(cliOptions.dir, 'bin')
|
||||
)
|
||||
: globalBinDir(knownGlobalBinDirCandidates, { shouldAllowWrite: opts.globalDirShouldAllowWrite === true })
|
||||
const npmConfigGlobalBinDir = npmConfig.get('global-bin-dir')
|
||||
if (typeof npmConfigGlobalBinDir === 'string') {
|
||||
fs.mkdirSync(npmConfigGlobalBinDir, { recursive: true })
|
||||
pnpmConfig.bin = npmConfigGlobalBinDir
|
||||
} else {
|
||||
pnpmConfig.bin = cliOptions.dir
|
||||
? (
|
||||
process.platform === 'win32'
|
||||
? cliOptions.dir
|
||||
: path.resolve(cliOptions.dir, 'bin')
|
||||
)
|
||||
: globalBinDir(knownGlobalBinDirCandidates, { shouldAllowWrite: opts.globalDirShouldAllowWrite === true })
|
||||
}
|
||||
pnpmConfig.save = true
|
||||
pnpmConfig.allowNew = true
|
||||
pnpmConfig.ignoreCurrentPrefs = true
|
||||
|
||||
1
packages/config/test/global-bin-dir-windows/etc/npmrc
Normal file
1
packages/config/test/global-bin-dir-windows/etc/npmrc
Normal file
@@ -0,0 +1 @@
|
||||
global-bin-dir=${HOME}\.local\pnpm
|
||||
1
packages/config/test/global-bin-dir/etc/npmrc
Normal file
1
packages/config/test/global-bin-dir/etc/npmrc
Normal file
@@ -0,0 +1 @@
|
||||
global-bin-dir=${HOME}/.local/pnpm
|
||||
57
packages/config/test/globalBinDir.test.ts
Normal file
57
packages/config/test/globalBinDir.test.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
/// <reference path="../../../typings/index.d.ts"/>
|
||||
import path from 'path'
|
||||
import { homedir } from 'os'
|
||||
import getConfig from '@pnpm/config'
|
||||
|
||||
const isWindows = process.platform === 'win32'
|
||||
|
||||
jest.mock('@zkochan/npm-conf/lib/conf', () => {
|
||||
const originalModule = jest.requireActual('@zkochan/npm-conf/lib/conf')
|
||||
class MockedConf extends originalModule {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
constructor (base: any, types: any) {
|
||||
super(base, types)
|
||||
const globalPrefixDirName = isWindows ? 'global-bin-dir-windows' : 'global-bin-dir'
|
||||
this.prefix = this.globalPrefix = path.join(__dirname, globalPrefixDirName)
|
||||
this.localPrefix = __dirname
|
||||
}
|
||||
|
||||
get (name: string) {
|
||||
if (name === 'prefix') {
|
||||
return this.prefix
|
||||
} else {
|
||||
return super.get(name)
|
||||
}
|
||||
}
|
||||
|
||||
loadPrefix () {}
|
||||
}
|
||||
return MockedConf
|
||||
})
|
||||
|
||||
test('respects global-bin-dir in npmrc', async () => {
|
||||
const { config } = await getConfig({
|
||||
cliOptions: {
|
||||
global: true,
|
||||
},
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: '1.0.0',
|
||||
},
|
||||
})
|
||||
expect(config.bin).toBe(path.join(homedir(), '.local', 'pnpm'))
|
||||
})
|
||||
|
||||
test('respects global-bin-dir rather than dir', async () => {
|
||||
const { config } = await getConfig({
|
||||
cliOptions: {
|
||||
global: true,
|
||||
dir: __dirname,
|
||||
},
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: '1.0.0',
|
||||
},
|
||||
})
|
||||
expect(config.bin).toBe(path.join(homedir(), '.local', 'pnpm'))
|
||||
})
|
||||
@@ -41,7 +41,7 @@ export async function handler (
|
||||
},
|
||||
params: string[]
|
||||
) {
|
||||
const prefix = path.join(os.tmpdir(), `dlx-${process.pid.toString()}`)
|
||||
const prefix = path.join(fs.realpathSync(os.tmpdir()), `dlx-${process.pid.toString()}`)
|
||||
const bins = process.platform === 'win32'
|
||||
? prefix
|
||||
: path.join(prefix, 'bin')
|
||||
|
||||
Reference in New Issue
Block a user