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:
Zoltan Kochan authored and GitHub committed 2024-08-22 11:16:08 +02:00
1 parent ba9409ffce
commit 840e2000b5
7 files changed
+76 -59

No files matched your search

+3 -1
View File
@@ -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.
+3
View File
@@ -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
View File
@@ -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"
}