feat: self-update should update pnpm in the packageManager field (#8449)
* feat: self-update should update pnpm in the packageManager field * fix: self-update should update packageManager in package.json * fix: verify package manager name * refactor: test
This commit is contained in:
1 parent
ba9409ffce
commit
840e2000b5
7 files changed
+76
-59
No files matched your search
@@ -7,4 +7,6 @@
|
||||
"pnpm": minor
|
||||
---
|
||||
|
||||
Added a new command for upgrading pnpm itself, when it isn't managed by Corepack: `pnpm self-update`. This command will work, when pnpm was installed via the standalone script from the [pnpm installation page](https://pnpm.io/installation#using-a-standalone-script) [#8424](https://github.com/pnpm/pnpm/pull/8424).
|
||||
Added a new command for upgrading pnpm itself when it isn't managed by Corepack: `pnpm self-update`. This command will work, when pnpm was installed via the standalone script from the [pnpm installation page](https://pnpm.io/installation#using-a-standalone-script) [#8424](https://github.com/pnpm/pnpm/pull/8424).
|
||||
|
||||
When executed in a project that has a `packageManager` field in its `package.json` file, pnpm will update its version in the `packageManager` field.
|
||||
Generated
+3
@@ -7326,6 +7326,9 @@ importers:
|
||||
'@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
|
||||
'@pnpm/tools.path':
|
||||
specifier: workspace:*
|
||||
version: link:../path
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ export async function main (inputArgv: string[]): Promise<void> {
|
||||
checkUnknownSetting: false,
|
||||
ignoreNonAuthSettingsFromLocal: isDlxCommand,
|
||||
}) as typeof config
|
||||
if (!isExecutedByCorepack() && cmd !== 'setup' && cmd !== 'self-update' && config.wantedPackageManager != null) {
|
||||
if (!isExecutedByCorepack() && cmd !== 'setup' && config.wantedPackageManager != null) {
|
||||
if (config.managePackageManagerVersions) {
|
||||
await switchCliVersion(config)
|
||||
} else {
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
"@pnpm/link-bins": "workspace:*",
|
||||
"@pnpm/pick-registry-for-package": "workspace:*",
|
||||
"@pnpm/plugin-commands-installation": "workspace:*",
|
||||
"@pnpm/read-project-manifest": "workspace:*",
|
||||
"@pnpm/tools.path": "workspace:*",
|
||||
"ramda": "catalog:",
|
||||
"render-help": "catalog:"
|
||||
|
||||
@@ -4,10 +4,11 @@ import { docsUrl } from '@pnpm/cli-utils'
|
||||
import { getCurrentPackageName, packageManager, isExecutedByCorepack } from '@pnpm/cli-meta'
|
||||
import { createResolver } from '@pnpm/client'
|
||||
import { pickRegistryForPackage } from '@pnpm/pick-registry-for-package'
|
||||
import { types as allTypes } from '@pnpm/config'
|
||||
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 pick from 'ramda/src/pick'
|
||||
@@ -34,7 +35,7 @@ export function help (): string {
|
||||
})
|
||||
}
|
||||
|
||||
export type SelfUpdateCommandOptions = InstallCommandOptions
|
||||
export type SelfUpdateCommandOptions = InstallCommandOptions & Pick<Config, 'wantedPackageManager' | 'managePackageManagerVersions'>
|
||||
|
||||
export async function handler (
|
||||
opts: SelfUpdateCommandOptions
|
||||
@@ -57,6 +58,13 @@ export async function handler (
|
||||
return `The currently active ${packageManager.name} v${packageManager.version} is already "latest" and doesn't need an update`
|
||||
}
|
||||
|
||||
if (opts.wantedPackageManager?.name === packageManager.name && opts.managePackageManagerVersions) {
|
||||
const { manifest, writeProjectManifest } = await readProjectManifest(opts.rootProjectManifestDir)
|
||||
manifest.packageManager = `pnpm@${resolution.manifest.version}`
|
||||
await writeProjectManifest(manifest)
|
||||
return `The current project has been updated to use pnpm v${resolution.manifest.version}`
|
||||
}
|
||||
|
||||
const currentPkgName = getCurrentPackageName()
|
||||
const dir = getToolDirPath({
|
||||
pnpmHomeDir: opts.pnpmHomeDir,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { prependDirsToPath } from '@pnpm/env.path'
|
||||
import { tempDir } from '@pnpm/prepare'
|
||||
import { tempDir, prepare as prepareWithPkg } from '@pnpm/prepare'
|
||||
import { selfUpdate } from '@pnpm/tools.plugin-commands-self-updater'
|
||||
import spawn from 'cross-spawn'
|
||||
import nock from 'nock'
|
||||
@@ -29,6 +29,10 @@ beforeEach(() => {
|
||||
|
||||
function prepare () {
|
||||
const dir = tempDir(false)
|
||||
return prepareOptions(dir)
|
||||
}
|
||||
|
||||
function prepareOptions (dir: string) {
|
||||
return {
|
||||
argv: {
|
||||
original: [],
|
||||
@@ -51,6 +55,26 @@ function prepare () {
|
||||
cacheDir: path.join(dir, '.cache'),
|
||||
virtualStoreDirMaxLength: 120,
|
||||
dir: process.cwd(),
|
||||
managePackageManagerVersions: false,
|
||||
}
|
||||
}
|
||||
|
||||
function createMetadata (latest: string, registry: string) {
|
||||
return {
|
||||
name: 'pnpm',
|
||||
'dist-tags': { latest },
|
||||
versions: {
|
||||
[latest]: {
|
||||
name: 'pnpm',
|
||||
version: latest,
|
||||
dist: {
|
||||
shasum: '217063ce3fcbf44f3051666f38b810f1ddefee4a',
|
||||
tarball: `${registry}pnpm/-/pnpm-${latest}.tgz`,
|
||||
fileCount: 880,
|
||||
integrity: 'sha512-Z/WHmRapKT5c8FnCOFPVcb6vT3U8cH9AyyK+1fsVeMaq07bEEHzLO6CzW+AD62IaFkcayDbIe+tT+dVLtGEnJA==',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,24 +82,7 @@ test('self-update', async () => {
|
||||
const opts = prepare()
|
||||
nock(opts.registries.default)
|
||||
.get('/pnpm')
|
||||
.reply(200, {
|
||||
name: 'pnpm',
|
||||
'dist-tags': {
|
||||
latest: '9.1.0',
|
||||
},
|
||||
versions: {
|
||||
'9.1.0': {
|
||||
name: 'pnpm',
|
||||
version: '9.1.0',
|
||||
dist: {
|
||||
shasum: '217063ce3fcbf44f3051666f38b810f1ddefee4a',
|
||||
tarball: `${opts.registries.default}pnpm/-/pnpm-9.1.0.tgz`,
|
||||
fileCount: 880,
|
||||
integrity: 'sha512-Z/WHmRapKT5c8FnCOFPVcb6vT3U8cH9AyyK+1fsVeMaq07bEEHzLO6CzW+AD62IaFkcayDbIe+tT+dVLtGEnJA==',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
.reply(200, createMetadata('9.1.0', opts.registries.default))
|
||||
nock(opts.registries.default)
|
||||
.get('/pnpm/-/pnpm-9.1.0.tgz')
|
||||
.replyWithFile(200, path.join(__dirname, 'pnpm-9.1.0.tgz'))
|
||||
@@ -100,24 +107,7 @@ test('self-update does nothing when pnpm is up to date', async () => {
|
||||
const opts = prepare()
|
||||
nock(opts.registries.default)
|
||||
.get('/pnpm')
|
||||
.reply(200, {
|
||||
name: 'pnpm',
|
||||
'dist-tags': {
|
||||
latest: '9.0.0',
|
||||
},
|
||||
versions: {
|
||||
'9.0.0': {
|
||||
name: 'pnpm',
|
||||
version: '9.0.0',
|
||||
dist: {
|
||||
shasum: '217063ce3fcbf44f3051666f38b810f1ddefee4a',
|
||||
tarball: `${opts.registries.default}pnpm/-/pnpm-9.1.0.tgz`,
|
||||
fileCount: 880,
|
||||
integrity: 'sha512-Z/WHmRapKT5c8FnCOFPVcb6vT3U8cH9AyyK+1fsVeMaq07bEEHzLO6CzW+AD62IaFkcayDbIe+tT+dVLtGEnJA==',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
.reply(200, createMetadata('9.0.0', opts.registries.default))
|
||||
|
||||
const output = await selfUpdate.handler(opts)
|
||||
|
||||
@@ -128,24 +118,7 @@ test('self-update links pnpm that is already present on the disk', async () => {
|
||||
const opts = prepare()
|
||||
nock(opts.registries.default)
|
||||
.get('/pnpm')
|
||||
.reply(200, {
|
||||
name: 'pnpm',
|
||||
'dist-tags': {
|
||||
latest: '9.2.0',
|
||||
},
|
||||
versions: {
|
||||
'9.2.0': {
|
||||
name: 'pnpm',
|
||||
version: '9.2.0',
|
||||
dist: {
|
||||
shasum: '217063ce3fcbf44f3051666f38b810f1ddefee4a',
|
||||
tarball: `${opts.registries.default}pnpm/-/pnpm-9.2.0.tgz`,
|
||||
fileCount: 880,
|
||||
integrity: 'sha512-Z/WHmRapKT5c8FnCOFPVcb6vT3U8cH9AyyK+1fsVeMaq07bEEHzLO6CzW+AD62IaFkcayDbIe+tT+dVLtGEnJA==',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
.reply(200, createMetadata('9.2.0', opts.registries.default))
|
||||
|
||||
const latestPnpmDir = path.join(opts.pnpmHomeDir, '.tools/pnpm/9.2.0/node_modules/pnpm')
|
||||
fs.mkdirSync(latestPnpmDir, { recursive: true })
|
||||
@@ -166,3 +139,30 @@ console.log('9.2.0')`, 'utf8')
|
||||
expect(status).toBe(0)
|
||||
expect(stdout.toString().trim()).toBe('9.2.0')
|
||||
})
|
||||
|
||||
test('self-update updates the packageManager field in package.json', async () => {
|
||||
prepareWithPkg({
|
||||
packageManager: 'pnpm@9.0.0',
|
||||
})
|
||||
const opts = {
|
||||
...prepareOptions(process.cwd()),
|
||||
managePackageManagerVersions: true,
|
||||
wantedPackageManager: {
|
||||
name: 'pnpm',
|
||||
version: '9.0.0',
|
||||
},
|
||||
}
|
||||
nock(opts.registries.default)
|
||||
.get('/pnpm')
|
||||
.reply(200, createMetadata('9.1.0', opts.registries.default))
|
||||
nock(opts.registries.default)
|
||||
.get('/pnpm/-/pnpm-9.1.0.tgz')
|
||||
.replyWithFile(200, path.join(__dirname, 'pnpm-9.1.0.tgz'))
|
||||
|
||||
const output = await selfUpdate.handler(opts)
|
||||
|
||||
expect(output).toBe('The current project has been updated to use pnpm v9.1.0')
|
||||
|
||||
const pkgJson = JSON.parse(fs.readFileSync(path.resolve('package.json'), 'utf8'))
|
||||
expect(pkgJson.packageManager).toBe('pnpm@9.1.0')
|
||||
})
|
||||
@@ -39,6 +39,9 @@
|
||||
{
|
||||
"path": "../../pkg-manager/plugin-commands-installation"
|
||||
},
|
||||
{
|
||||
"path": "../../pkg-manifest/read-project-manifest"
|
||||
},
|
||||
{
|
||||
"path": "../path"
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user