mirror of
https://github.com/pnpm/pnpm.git
synced 2026-01-01 11:38:21 -05:00
fix: self-update should not read pnpm settings from current package.json (#9196)
close #9188 close #9183
This commit is contained in:
7
.changeset/lucky-flies-rescue.md
Normal file
7
.changeset/lucky-flies-rescue.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@pnpm/tools.plugin-commands-self-updater": patch
|
||||
"@pnpm/plugin-commands-installation": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
`pnpm self-update` should not read the pnpm settings from the `package.json` file in the current working directory.
|
||||
5
.changeset/quick-bikes-agree.md
Normal file
5
.changeset/quick-bikes-agree.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/tools.plugin-commands-self-updater": minor
|
||||
---
|
||||
|
||||
Export `installPnpmToTools`.
|
||||
5
.changeset/thirty-donkeys-complain.md
Normal file
5
.changeset/thirty-donkeys-complain.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-script-runners": patch
|
||||
---
|
||||
|
||||
Pass onlyBuiltDependencies as a direct option to add.handler.
|
||||
@@ -62,11 +62,13 @@ export async function getConfig (opts: {
|
||||
checkUnknownSetting?: boolean
|
||||
env?: Record<string, string | undefined>
|
||||
ignoreNonAuthSettingsFromLocal?: boolean
|
||||
ignoreLocalSettings?: boolean
|
||||
}): Promise<{ config: Config, warnings: string[] }> {
|
||||
if (opts.ignoreNonAuthSettingsFromLocal) {
|
||||
const { ignoreNonAuthSettingsFromLocal: _, ...authOpts } = opts
|
||||
const globalCfgOpts: typeof authOpts = {
|
||||
...authOpts,
|
||||
ignoreLocalSettings: true,
|
||||
cliOptions: {
|
||||
...authOpts.cliOptions,
|
||||
dir: os.homedir(),
|
||||
@@ -318,7 +320,9 @@ export async function getConfig (opts: {
|
||||
pnpmConfig.virtualStoreDir = '.pnpm'
|
||||
} else {
|
||||
pnpmConfig.dir = cwd
|
||||
pnpmConfig.bin = path.join(pnpmConfig.dir, 'node_modules', '.bin')
|
||||
if (!pnpmConfig.bin) {
|
||||
pnpmConfig.bin = path.join(pnpmConfig.dir, 'node_modules', '.bin')
|
||||
}
|
||||
}
|
||||
if (opts.cliOptions['save-peer']) {
|
||||
if (opts.cliOptions['save-prod']) {
|
||||
@@ -480,25 +484,27 @@ export async function getConfig (opts: {
|
||||
|
||||
pnpmConfig.workspaceConcurrency = getWorkspaceConcurrency(pnpmConfig.workspaceConcurrency)
|
||||
|
||||
if (!pnpmConfig.ignorePnpmfile) {
|
||||
pnpmConfig.hooks = requireHooks(pnpmConfig.lockfileDir ?? pnpmConfig.dir, pnpmConfig)
|
||||
}
|
||||
pnpmConfig.rootProjectManifestDir = pnpmConfig.lockfileDir ?? pnpmConfig.workspaceDir ?? pnpmConfig.dir
|
||||
pnpmConfig.rootProjectManifest = await safeReadProjectManifestOnly(pnpmConfig.rootProjectManifestDir) ?? undefined
|
||||
if (pnpmConfig.rootProjectManifest != null) {
|
||||
if (pnpmConfig.rootProjectManifest.workspaces?.length && !pnpmConfig.workspaceDir) {
|
||||
warnings.push('The "workspaces" field in package.json is not supported by pnpm. Create a "pnpm-workspace.yaml" file instead.')
|
||||
if (!opts.ignoreLocalSettings) {
|
||||
if (!pnpmConfig.ignorePnpmfile) {
|
||||
pnpmConfig.hooks = requireHooks(pnpmConfig.lockfileDir ?? pnpmConfig.dir, pnpmConfig)
|
||||
}
|
||||
if (pnpmConfig.rootProjectManifest.packageManager) {
|
||||
pnpmConfig.wantedPackageManager = parsePackageManager(pnpmConfig.rootProjectManifest.packageManager)
|
||||
pnpmConfig.rootProjectManifestDir = pnpmConfig.lockfileDir ?? pnpmConfig.workspaceDir ?? pnpmConfig.dir
|
||||
pnpmConfig.rootProjectManifest = await safeReadProjectManifestOnly(pnpmConfig.rootProjectManifestDir) ?? undefined
|
||||
if (pnpmConfig.rootProjectManifest != null) {
|
||||
if (pnpmConfig.rootProjectManifest.workspaces?.length && !pnpmConfig.workspaceDir) {
|
||||
warnings.push('The "workspaces" field in package.json is not supported by pnpm. Create a "pnpm-workspace.yaml" file instead.')
|
||||
}
|
||||
if (pnpmConfig.rootProjectManifest.packageManager) {
|
||||
pnpmConfig.wantedPackageManager = parsePackageManager(pnpmConfig.rootProjectManifest.packageManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pnpmConfig.workspaceDir != null) {
|
||||
const workspaceManifest = await readWorkspaceManifest(pnpmConfig.workspaceDir)
|
||||
if (pnpmConfig.workspaceDir != null) {
|
||||
const workspaceManifest = await readWorkspaceManifest(pnpmConfig.workspaceDir)
|
||||
|
||||
pnpmConfig.workspacePackagePatterns = cliOptions['workspace-packages'] as string[] ?? workspaceManifest?.packages
|
||||
pnpmConfig.catalogs = getCatalogsFromWorkspaceManifest(workspaceManifest)
|
||||
pnpmConfig.workspacePackagePatterns = cliOptions['workspace-packages'] as string[] ?? workspaceManifest?.packages
|
||||
pnpmConfig.catalogs = getCatalogsFromWorkspaceManifest(workspaceManifest)
|
||||
}
|
||||
}
|
||||
|
||||
pnpmConfig.failedToLoadBuiltInConfig = failedToLoadBuiltInConfig
|
||||
|
||||
@@ -10,7 +10,6 @@ import { add } from '@pnpm/plugin-commands-installation'
|
||||
import { readPackageJsonFromDir } from '@pnpm/read-package-json'
|
||||
import { getBinsFromPackageManifest } from '@pnpm/package-bins'
|
||||
import execa from 'execa'
|
||||
import omit from 'ramda/src/omit'
|
||||
import pick from 'ramda/src/pick'
|
||||
import renderHelp from 'render-help'
|
||||
import symlinkDir from 'symlink-dir'
|
||||
@@ -81,9 +80,7 @@ export async function handler (
|
||||
if (!cacheExists) {
|
||||
fs.mkdirSync(cachedDir, { recursive: true })
|
||||
await add.handler({
|
||||
// Ideally the config reader should ignore these settings when the dlx command is executed.
|
||||
// This is a temporary solution until "@pnpm/config" is refactored.
|
||||
...omit(['workspaceDir', 'rootProjectManifest', 'symlink'], opts),
|
||||
...opts,
|
||||
bin: path.join(cachedDir, 'node_modules/.bin'),
|
||||
dir: cachedDir,
|
||||
lockfileDir: cachedDir,
|
||||
@@ -92,6 +89,8 @@ export async function handler (
|
||||
saveDev: false,
|
||||
saveOptional: false,
|
||||
savePeer: false,
|
||||
symlink: true,
|
||||
workspaceDir: undefined,
|
||||
}, pkgs)
|
||||
try {
|
||||
await symlinkDir(cachedDir, cacheLink, { overwrite: true })
|
||||
|
||||
@@ -295,6 +295,7 @@ export type InstallCommandOptions = Pick<Config,
|
||||
| 'sort'
|
||||
| 'sharedWorkspaceLockfile'
|
||||
| 'tag'
|
||||
| 'onlyBuiltDependencies'
|
||||
| 'optional'
|
||||
| 'virtualStoreDir'
|
||||
| 'workspaceConcurrency'
|
||||
@@ -318,7 +319,7 @@ export type InstallCommandOptions = Pick<Config,
|
||||
workspace?: boolean
|
||||
includeOnlyPackageFiles?: boolean
|
||||
confirmModulesPurge?: boolean
|
||||
} & Partial<Pick<Config, 'modulesCacheMaxAge' | 'pnpmHomeDir' | 'preferWorkspacePackages' | 'useLockfile'>>
|
||||
} & Partial<Pick<Config, 'modulesCacheMaxAge' | 'pnpmHomeDir' | 'preferWorkspacePackages' | 'useLockfile' | 'symlink'>>
|
||||
|
||||
export async function handler (opts: InstallCommandOptions): Promise<void> {
|
||||
const include = {
|
||||
|
||||
17
pnpm-lock.yaml
generated
17
pnpm-lock.yaml
generated
@@ -24,6 +24,9 @@ catalogs:
|
||||
'@pnpm/exec':
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
'@pnpm/exec.pnpm-cli-runner':
|
||||
specifier: 1000.0.0
|
||||
version: 1000.0.0
|
||||
'@pnpm/fs.packlist':
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
@@ -7555,6 +7558,9 @@ importers:
|
||||
'@pnpm/error':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/error
|
||||
'@pnpm/exec.pnpm-cli-runner':
|
||||
specifier: 'catalog:'
|
||||
version: 1000.0.0
|
||||
'@pnpm/link-bins':
|
||||
specifier: workspace:*
|
||||
version: link:../../pkg-manager/link-bins
|
||||
@@ -7564,9 +7570,6 @@ importers:
|
||||
'@pnpm/pick-registry-for-package':
|
||||
specifier: workspace:*
|
||||
version: link:../../config/pick-registry-for-package
|
||||
'@pnpm/plugin-commands-installation':
|
||||
specifier: workspace:*
|
||||
version: link:../../pkg-manager/plugin-commands-installation
|
||||
'@pnpm/read-project-manifest':
|
||||
specifier: workspace:*
|
||||
version: link:../../pkg-manifest/read-project-manifest
|
||||
@@ -8870,6 +8873,10 @@ packages:
|
||||
resolution: {integrity: sha512-OIYhG7HQh4zUFh2s8/6bp7glVRjNxms7bpzXVOLV7pyRa+rSYFmqJ8zDsBC64k58nuaxS85Ip+SCDjFxsFGeOg==}
|
||||
engines: {node: '>=18.12'}
|
||||
|
||||
'@pnpm/exec.pnpm-cli-runner@1000.0.0':
|
||||
resolution: {integrity: sha512-5oRH9X7S1UKozhkOxMfn7i7H7fZSWRFlX6R/xXoTnLCIe7ab2tU3EN98D739areH53thhjk8bq9osklcOZGM7g==}
|
||||
engines: {node: '>=18.12'}
|
||||
|
||||
'@pnpm/exec@2.0.0':
|
||||
resolution: {integrity: sha512-b5ALfWEOFQprWKntN7MF8XWCyslBk2c8u20GEDcDDQOs6c0HyHlWxX5lig8riQKdS000U6YyS4L4b32NOleXAQ==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -15881,6 +15888,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@pnpm/constants': 10.0.0
|
||||
|
||||
'@pnpm/exec.pnpm-cli-runner@1000.0.0':
|
||||
dependencies:
|
||||
execa: safe-execa@0.1.2
|
||||
|
||||
'@pnpm/exec@2.0.0':
|
||||
dependencies:
|
||||
'@pnpm/self-installer': 2.2.1
|
||||
|
||||
@@ -45,6 +45,7 @@ catalog:
|
||||
"@pnpm/colorize-semver-diff": ^1.0.1
|
||||
"@pnpm/config.env-replace": 3.0.0
|
||||
"@pnpm/exec": ^2.0.0
|
||||
"@pnpm/exec.pnpm-cli-runner": 1000.0.0
|
||||
"@pnpm/fs.packlist": 2.0.0
|
||||
"@pnpm/log.group": 3.0.0
|
||||
"@pnpm/meta-updater": 2.0.3
|
||||
|
||||
@@ -104,7 +104,7 @@ export async function main (inputArgv: string[]): Promise<void> {
|
||||
rcOptionsTypes,
|
||||
workspaceDir,
|
||||
checkUnknownSetting: false,
|
||||
ignoreNonAuthSettingsFromLocal: isDlxCommand,
|
||||
ignoreNonAuthSettingsFromLocal: isDlxCommand || cmd === 'self-update',
|
||||
}) as typeof config
|
||||
if (!isExecutedByCorepack() && cmd !== 'setup' && config.wantedPackageManager != null) {
|
||||
if (config.managePackageManagerVersions && config.wantedPackageManager?.name === 'pnpm') {
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { type Config } from '@pnpm/config'
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import { globalWarn } from '@pnpm/logger'
|
||||
import { getCurrentPackageName, packageManager } from '@pnpm/cli-meta'
|
||||
import { packageManager } from '@pnpm/cli-meta'
|
||||
import { prependDirsToPath } from '@pnpm/env.path'
|
||||
import { getToolDirPath } from '@pnpm/tools.path'
|
||||
import { installPnpmToTools } from '@pnpm/tools.plugin-commands-self-updater'
|
||||
import spawn from 'cross-spawn'
|
||||
import semver from 'semver'
|
||||
import { pnpmCmds } from './cmd'
|
||||
|
||||
export async function switchCliVersion (config: Config): Promise<void> {
|
||||
const pm = config.wantedPackageManager
|
||||
@@ -22,28 +20,7 @@ export async function switchCliVersion (config: Config): Promise<void> {
|
||||
globalWarn(`Cannot switch to pnpm@${pm.version}: you need to specify the version as "${pmVersion}"`)
|
||||
return
|
||||
}
|
||||
const pkgName = getCurrentPackageName()
|
||||
const dir = getToolDirPath({
|
||||
pnpmHomeDir: config.pnpmHomeDir,
|
||||
tool: {
|
||||
name: pkgName,
|
||||
version: pmVersion,
|
||||
},
|
||||
})
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true })
|
||||
fs.writeFileSync(path.join(dir, 'package.json'), '{}')
|
||||
await pnpmCmds.add(
|
||||
{
|
||||
...config,
|
||||
dir,
|
||||
lockfileDir: dir,
|
||||
bin: path.join(dir, 'bin'),
|
||||
},
|
||||
[`${pkgName}@${pmVersion}`]
|
||||
)
|
||||
}
|
||||
const wantedPnpmBinDir = path.join(dir, 'bin')
|
||||
const { binDir: wantedPnpmBinDir } = await installPnpmToTools(pmVersion, config)
|
||||
const pnpmEnv = prependDirsToPath([wantedPnpmBinDir])
|
||||
if (!pnpmEnv.updated) {
|
||||
// We throw this error to prevent an infinite recursive call of the same pnpm version.
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
"@pnpm/client": "workspace:*",
|
||||
"@pnpm/config": "workspace:*",
|
||||
"@pnpm/error": "workspace:*",
|
||||
"@pnpm/exec.pnpm-cli-runner": "catalog:",
|
||||
"@pnpm/link-bins": "workspace:*",
|
||||
"@pnpm/pick-registry-for-package": "workspace:*",
|
||||
"@pnpm/plugin-commands-installation": "workspace:*",
|
||||
"@pnpm/read-project-manifest": "workspace:*",
|
||||
"@pnpm/tools.path": "workspace:*",
|
||||
"@zkochan/rimraf": "catalog:",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as selfUpdate from './selfUpdate'
|
||||
export { installPnpmToTools } from './installPnpmToTools'
|
||||
|
||||
export { selfUpdate }
|
||||
|
||||
64
tools/plugin-commands-self-updater/src/installPnpmToTools.ts
Normal file
64
tools/plugin-commands-self-updater/src/installPnpmToTools.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { getCurrentPackageName } from '@pnpm/cli-meta'
|
||||
import { runPnpmCli } from '@pnpm/exec.pnpm-cli-runner'
|
||||
import { getToolDirPath } from '@pnpm/tools.path'
|
||||
import { sync as rimraf } from '@zkochan/rimraf'
|
||||
import { fastPathTemp as pathTemp } from 'path-temp'
|
||||
import renameOverwrite from 'rename-overwrite'
|
||||
import { type SelfUpdateCommandOptions } from './selfUpdate'
|
||||
|
||||
export interface InstallPnpmToToolsResult {
|
||||
binDir: string
|
||||
baseDir: string
|
||||
alreadyExisted: boolean
|
||||
}
|
||||
|
||||
export async function installPnpmToTools (pnpmVersion: string, opts: SelfUpdateCommandOptions): Promise<InstallPnpmToToolsResult> {
|
||||
const currentPkgName = getCurrentPackageName()
|
||||
const dir = getToolDirPath({
|
||||
pnpmHomeDir: opts.pnpmHomeDir,
|
||||
tool: {
|
||||
name: currentPkgName,
|
||||
version: pnpmVersion,
|
||||
},
|
||||
})
|
||||
|
||||
const binDir = path.join(dir, 'bin')
|
||||
const alreadyExisted = fs.existsSync(binDir)
|
||||
if (alreadyExisted) {
|
||||
return {
|
||||
alreadyExisted,
|
||||
baseDir: dir,
|
||||
binDir,
|
||||
}
|
||||
}
|
||||
const stage = pathTemp(dir)
|
||||
fs.mkdirSync(stage, { recursive: true })
|
||||
fs.writeFileSync(path.join(stage, 'package.json'), '{}')
|
||||
try {
|
||||
// The reason we don't just run add.handler is that at this point we might have settings from local config files
|
||||
// that we don't want to use while installing the pnpm CLI.
|
||||
runPnpmCli([
|
||||
'add',
|
||||
`${currentPkgName}@${pnpmVersion}`,
|
||||
'--loglevel=error',
|
||||
'--allow-build=@pnpm/exe',
|
||||
// We want to avoid symlinks because of the rename step,
|
||||
// which breaks the junctions on Windows.
|
||||
'--config.node-linker=hoisted',
|
||||
`--config.bin=${path.join(stage, 'bin')}`,
|
||||
], { cwd: stage })
|
||||
renameOverwrite.sync(stage, dir)
|
||||
} catch (err: unknown) {
|
||||
try {
|
||||
rimraf(stage)
|
||||
} catch {} // eslint-disable-line:no-empty
|
||||
throw err
|
||||
}
|
||||
return {
|
||||
alreadyExisted,
|
||||
baseDir: dir,
|
||||
binDir,
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,16 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { docsUrl } from '@pnpm/cli-utils'
|
||||
import { getCurrentPackageName, packageManager, isExecutedByCorepack } from '@pnpm/cli-meta'
|
||||
import { packageManager, isExecutedByCorepack } from '@pnpm/cli-meta'
|
||||
import { createResolver } from '@pnpm/client'
|
||||
import { pickRegistryForPackage } from '@pnpm/pick-registry-for-package'
|
||||
import { type Config, types as allTypes } from '@pnpm/config'
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import { globalWarn } from '@pnpm/logger'
|
||||
import { add, type InstallCommandOptions } from '@pnpm/plugin-commands-installation'
|
||||
import { readProjectManifest } from '@pnpm/read-project-manifest'
|
||||
import { getToolDirPath } from '@pnpm/tools.path'
|
||||
import { linkBins } from '@pnpm/link-bins'
|
||||
import { sync as rimraf } from '@zkochan/rimraf'
|
||||
import { fastPathTemp as pathTemp } from 'path-temp'
|
||||
import pick from 'ramda/src/pick'
|
||||
import renameOverwrite from 'rename-overwrite'
|
||||
import renderHelp from 'render-help'
|
||||
import { installPnpmToTools } from './installPnpmToTools'
|
||||
|
||||
export function rcOptionsTypes (): Record<string, unknown> {
|
||||
return pick([], allTypes)
|
||||
@@ -43,7 +38,18 @@ export function help (): string {
|
||||
})
|
||||
}
|
||||
|
||||
export type SelfUpdateCommandOptions = InstallCommandOptions & Pick<Config, 'wantedPackageManager' | 'managePackageManagerVersions'>
|
||||
export type SelfUpdateCommandOptions = Pick<Config,
|
||||
| 'cacheDir'
|
||||
| 'dir'
|
||||
| 'lockfileDir'
|
||||
| 'managePackageManagerVersions'
|
||||
| 'modulesDir'
|
||||
| 'pnpmHomeDir'
|
||||
| 'rawConfig'
|
||||
| 'registries'
|
||||
| 'rootProjectManifestDir'
|
||||
| 'wantedPackageManager'
|
||||
>
|
||||
|
||||
export async function handler (
|
||||
opts: SelfUpdateCommandOptions,
|
||||
@@ -75,49 +81,13 @@ export async function handler (
|
||||
return `The current project has been updated to use pnpm v${resolution.manifest.version}`
|
||||
}
|
||||
|
||||
const currentPkgName = getCurrentPackageName()
|
||||
const dir = getToolDirPath({
|
||||
pnpmHomeDir: opts.pnpmHomeDir,
|
||||
tool: {
|
||||
name: currentPkgName,
|
||||
version: resolution.manifest.version,
|
||||
},
|
||||
})
|
||||
const alreadyExists = fs.existsSync(dir)
|
||||
if (!alreadyExists) {
|
||||
const stage = pathTemp(dir)
|
||||
fs.mkdirSync(stage, { recursive: true })
|
||||
fs.writeFileSync(path.join(stage, 'package.json'), '{}')
|
||||
try {
|
||||
await add.handler(
|
||||
{
|
||||
...opts,
|
||||
dir: stage,
|
||||
lockfileDir: stage,
|
||||
// We want to avoid symlinks because of the rename step,
|
||||
// which breaks the junctions on Windows.
|
||||
nodeLinker: 'hoisted',
|
||||
// This won't be used but there is currently no way to skip the bin creation
|
||||
// and we can't create the bin shims in the pnpm home directory
|
||||
// because the stage directory will be renamed.
|
||||
bin: path.join(stage, 'node_modules/.bin'),
|
||||
},
|
||||
[`${currentPkgName}@${resolution.manifest.version}`]
|
||||
)
|
||||
renameOverwrite.sync(stage, dir)
|
||||
} catch (err: unknown) {
|
||||
try {
|
||||
rimraf(stage)
|
||||
} catch {} // eslint-disable-line:no-empty
|
||||
throw err
|
||||
}
|
||||
}
|
||||
await linkBins(path.join(dir, opts.modulesDir ?? 'node_modules'), opts.pnpmHomeDir,
|
||||
const { baseDir, alreadyExisted } = await installPnpmToTools(resolution.manifest.version, opts)
|
||||
await linkBins(path.join(baseDir, opts.modulesDir ?? 'node_modules'), opts.pnpmHomeDir,
|
||||
{
|
||||
warn: globalWarn,
|
||||
}
|
||||
)
|
||||
return alreadyExists
|
||||
? `The ${pref} version, v${resolution.manifest.version}, is already present on the system. It was activated by linking it from ${dir}.`
|
||||
return alreadyExisted
|
||||
? `The ${pref} version, v${resolution.manifest.version}, is already present on the system. It was activated by linking it from ${baseDir}.`
|
||||
: undefined
|
||||
}
|
||||
|
||||
@@ -149,7 +149,9 @@ test('self-update links pnpm that is already present on the disk', async () => {
|
||||
.get('/pnpm')
|
||||
.reply(200, createMetadata('9.2.0', opts.registries.default))
|
||||
|
||||
const latestPnpmDir = path.join(opts.pnpmHomeDir, '.tools/pnpm/9.2.0/node_modules/pnpm')
|
||||
const baseDir = path.join(opts.pnpmHomeDir, '.tools/pnpm/9.2.0')
|
||||
fs.mkdirSync(path.join(baseDir, 'bin'), { recursive: true })
|
||||
const latestPnpmDir = path.join(baseDir, 'node_modules/pnpm')
|
||||
fs.mkdirSync(latestPnpmDir, { recursive: true })
|
||||
fs.writeFileSync(path.join(latestPnpmDir, 'package.json'), JSON.stringify({ name: 'pnpm', bin: 'bin.js' }), 'utf8')
|
||||
fs.writeFileSync(path.join(latestPnpmDir, 'bin.js'), `#!/usr/bin/env node
|
||||
|
||||
@@ -36,9 +36,6 @@
|
||||
{
|
||||
"path": "../../pkg-manager/link-bins"
|
||||
},
|
||||
{
|
||||
"path": "../../pkg-manager/plugin-commands-installation"
|
||||
},
|
||||
{
|
||||
"path": "../../pkg-manifest/read-project-manifest"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user