mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-23 23:29:17 -05:00
fix: use single global config file for all npm/pnpm versions (#3873)
This commit is contained in:
5
.changeset/heavy-schools-own.md
Normal file
5
.changeset/heavy-schools-own.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/config": minor
|
||||
---
|
||||
|
||||
New setting: `configDir`.
|
||||
5
.changeset/silly-flowers-cough.md
Normal file
5
.changeset/silly-flowers-cough.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-env": minor
|
||||
---
|
||||
|
||||
`pnpm env use` sets the `globalconfig` for npm CLI. The global config is located in a centralized place, so it persists after switching to a different Node.js or npm version.
|
||||
@@ -91,6 +91,7 @@ export interface Config {
|
||||
|
||||
// pnpm specific configs
|
||||
cacheDir: string
|
||||
configDir: string
|
||||
stateDir: string
|
||||
storeDir?: string
|
||||
virtualStoreDir?: string
|
||||
|
||||
@@ -60,3 +60,24 @@ export function getDataDir (
|
||||
}
|
||||
return path.join(os.homedir(), '.pnpm')
|
||||
}
|
||||
|
||||
export function getConfigDir (
|
||||
opts: {
|
||||
env: NodeJS.ProcessEnv
|
||||
platform: string
|
||||
}
|
||||
) {
|
||||
if (opts.env.XDG_CONFIG_HOME) {
|
||||
return path.join(opts.env.XDG_CONFIG_HOME, 'pnpm')
|
||||
}
|
||||
if (opts.platform === 'darwin') {
|
||||
return path.join(os.homedir(), 'Library/Preferences/pnpm')
|
||||
}
|
||||
if (opts.platform !== 'win32') {
|
||||
return path.join(os.homedir(), '.config/pnpm')
|
||||
}
|
||||
if (opts.env.LOCALAPPDATA) {
|
||||
return path.join(opts.env.LOCALAPPDATA, 'pnpm/config')
|
||||
}
|
||||
return path.join(os.homedir(), '.config/pnpm')
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import realpathMissing from 'realpath-missing'
|
||||
import whichcb from 'which'
|
||||
import getScopeRegistries, { normalizeRegistry } from './getScopeRegistries'
|
||||
import findBestGlobalPrefix from './findBestGlobalPrefix'
|
||||
import { getCacheDir, getDataDir, getStateDir } from './dirs'
|
||||
import { getCacheDir, getConfigDir, getDataDir, getStateDir } from './dirs'
|
||||
import {
|
||||
Config,
|
||||
ConfigWithDeprecatedSettings,
|
||||
@@ -39,6 +39,7 @@ export const types = Object.assign({
|
||||
'cache-dir': String,
|
||||
'child-concurrency': Number,
|
||||
color: ['always', 'auto', 'never'],
|
||||
'config-dir': String,
|
||||
dev: [null, true],
|
||||
dir: String,
|
||||
'enable-modules-dir': Boolean,
|
||||
@@ -396,6 +397,9 @@ export default async (
|
||||
if (!pnpmConfig.stateDir) {
|
||||
pnpmConfig.stateDir = getStateDir(process)
|
||||
}
|
||||
if (!pnpmConfig.configDir) {
|
||||
pnpmConfig.configDir = getConfigDir(process)
|
||||
}
|
||||
if (pnpmConfig['hoist'] === false) {
|
||||
delete pnpmConfig.hoistPattern
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import os from 'os'
|
||||
import path from 'path'
|
||||
import { getCacheDir, getDataDir, getStateDir } from '../lib/dirs'
|
||||
import { getCacheDir, getConfigDir, getDataDir, getStateDir } from '../lib/dirs'
|
||||
|
||||
test('getCacheDir()', () => {
|
||||
expect(getCacheDir({
|
||||
@@ -82,3 +82,30 @@ test('getDataDir()', () => {
|
||||
platform: 'win32',
|
||||
})).toBe(path.join(os.homedir(), '.pnpm'))
|
||||
})
|
||||
|
||||
test('getConfigDir()', () => {
|
||||
expect(getConfigDir({
|
||||
env: {
|
||||
XDG_CONFIG_HOME: '/home/foo/config',
|
||||
},
|
||||
platform: 'linux',
|
||||
})).toBe(path.join('/home/foo/config', 'pnpm'))
|
||||
expect(getConfigDir({
|
||||
env: {},
|
||||
platform: 'linux',
|
||||
})).toBe(path.join(os.homedir(), '.config/pnpm'))
|
||||
expect(getConfigDir({
|
||||
env: {},
|
||||
platform: 'darwin',
|
||||
})).toBe(path.join(os.homedir(), 'Library/Preferences/pnpm'))
|
||||
expect(getConfigDir({
|
||||
env: {
|
||||
LOCALAPPDATA: '/localappdata',
|
||||
},
|
||||
platform: 'win32',
|
||||
})).toBe(path.join('/localappdata', 'pnpm/config'))
|
||||
expect(getConfigDir({
|
||||
env: {},
|
||||
platform: 'win32',
|
||||
})).toBe(path.join(os.homedir(), '.config/pnpm'))
|
||||
})
|
||||
|
||||
@@ -75,10 +75,16 @@ export async function handler (opts: NvmNodeCommandOptions, params: string[]) {
|
||||
if (process.platform !== 'win32') {
|
||||
npmDir = path.join(npmDir, 'lib')
|
||||
}
|
||||
npmDir = path.join(npmDir, 'node_modules/npm/bin')
|
||||
npmDir = path.join(npmDir, 'node_modules/npm')
|
||||
if (opts.configDir) {
|
||||
// We want the global npm settings to persist when Node.js or/and npm is changed to a different version,
|
||||
// so we tell npm to read the global config from centralized place that is outside of npm's directory.
|
||||
await fs.writeFile(path.join(npmDir, 'npmrc'), `globalconfig=${path.join(opts.configDir, 'npmrc')}`, 'utf-8')
|
||||
}
|
||||
const npmBinDir = path.join(npmDir, 'bin')
|
||||
const cmdShimOpts = { createPwshFile: false }
|
||||
await cmdShim(path.join(npmDir, 'npm-cli.js'), path.join(opts.bin, 'npm'), cmdShimOpts)
|
||||
await cmdShim(path.join(npmDir, 'npx-cli.js'), path.join(opts.bin, 'npx'), cmdShimOpts)
|
||||
await cmdShim(path.join(npmBinDir, 'npm-cli.js'), path.join(opts.bin, 'npm'), cmdShimOpts)
|
||||
await cmdShim(path.join(npmBinDir, 'npx-cli.js'), path.join(opts.bin, 'npx'), cmdShimOpts)
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export type NvmNodeCommandOptions = Pick<Config,
|
||||
| 'storeDir'
|
||||
| 'useNodeVersion'
|
||||
| 'pnpmHomeDir'
|
||||
>
|
||||
> & Partial<Pick<Config, 'configDir'>>
|
||||
|
||||
export async function getNodeBinDir (opts: NvmNodeCommandOptions) {
|
||||
const nodeDir = await getNodeDir(opts)
|
||||
|
||||
@@ -8,9 +8,11 @@ import PATH from 'path-name'
|
||||
|
||||
test('install Node (and npm, npx) by exact version of Node.js', async () => {
|
||||
tempDir()
|
||||
const configDir = path.resolve('config')
|
||||
|
||||
await env.handler({
|
||||
bin: process.cwd(),
|
||||
configDir,
|
||||
global: true,
|
||||
pnpmHomeDir: process.cwd(),
|
||||
rawConfig: {},
|
||||
@@ -20,6 +22,7 @@ test('install Node (and npm, npx) by exact version of Node.js', async () => {
|
||||
env: {
|
||||
[PATH]: `${process.cwd()}${path.delimiter}${process.env[PATH] as string}`,
|
||||
},
|
||||
extendEnv: false,
|
||||
}
|
||||
|
||||
{
|
||||
@@ -39,6 +42,11 @@ test('install Node (and npm, npx) by exact version of Node.js', async () => {
|
||||
|
||||
const dirs = fs.readdirSync(path.resolve('nodejs'))
|
||||
expect(dirs).toEqual(['16.4.0'])
|
||||
|
||||
{
|
||||
const { stdout } = execa.sync('npm', ['config', 'get', 'globalconfig'], opts)
|
||||
expect(stdout.toString()).toBe(path.join(configDir, 'npmrc'))
|
||||
}
|
||||
})
|
||||
|
||||
test('install Node by version range', async () => {
|
||||
|
||||
Reference in New Issue
Block a user