@pnpm/engine.pm.commands 1101.0.2 → 1101.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,11 +2,11 @@ import path from 'node:path';
2
2
  import { linkBins } from '@pnpm/bins.linker';
3
3
  import { isExecutedByCorepack, packageManager } from '@pnpm/cli.meta';
4
4
  import { docsUrl } from '@pnpm/cli.utils';
5
- import { types as allTypes } from '@pnpm/config.reader';
5
+ import { parsePackageManager, types as allTypes } from '@pnpm/config.reader';
6
6
  import { PnpmError } from '@pnpm/error';
7
7
  import { createResolver } from '@pnpm/installing.client';
8
8
  import { resolvePackageManagerIntegrities } from '@pnpm/installing.env-installer';
9
- import { globalWarn } from '@pnpm/logger';
9
+ import { globalInfo, globalWarn } from '@pnpm/logger';
10
10
  import { whichVersionIsPinned } from '@pnpm/resolving.npm-resolver';
11
11
  import { createStoreController } from '@pnpm/store.connection-manager';
12
12
  import { readProjectManifest } from '@pnpm/workspace.project-manifest-reader';
@@ -23,6 +23,13 @@ export function cliOptionsTypes() {
23
23
  };
24
24
  }
25
25
  export const commandNames = ['self-update'];
26
+ // Migration guidance printed once when `pnpm self-update` crosses a major
27
+ // boundary. Add an entry here for each future major that ships breaking
28
+ // changes users need to act on.
29
+ const MAJOR_UPGRADE_HINTS = {
30
+ 11: 'pnpm v11 removed or renamed several v10 settings. ' +
31
+ 'See https://pnpm.io/11.x/migration for migration instructions.',
32
+ };
26
33
  export const skipPackageManagerCheck = true;
27
34
  export function help() {
28
35
  return renderHelp({
@@ -41,6 +48,7 @@ export async function handler(opts, params) {
41
48
  if (isExecutedByCorepack()) {
42
49
  throw new PnpmError('CANT_SELF_UPDATE_IN_COREPACK', 'You should update pnpm with corepack');
43
50
  }
51
+ globalInfo('Checking for updates...');
44
52
  const { resolve } = createResolver({ ...opts, configByUri: opts.configByUri });
45
53
  const pkgName = 'pnpm';
46
54
  const bareSpecifier = params[0] ?? 'latest';
@@ -52,27 +60,68 @@ export async function handler(opts, params) {
52
60
  if (!resolution?.manifest) {
53
61
  throw new PnpmError('CANNOT_RESOLVE_PNPM', `Cannot find "${bareSpecifier}" version of pnpm`);
54
62
  }
63
+ // Determine the "previous" pnpm version being upgraded FROM. If the
64
+ // project pins pnpm via `packageManager`/`devEngines.packageManager`,
65
+ // the pin is the source of truth — the running pnpm binary may already
66
+ // be at a newer major (e.g. a globally-installed v11 operating on a
67
+ // project still pinned to v10). Otherwise fall back to the running
68
+ // binary. Skip the hint entirely on a no-op (target === previous).
69
+ const targetVersion = resolution.manifest.version;
70
+ let previousVersion;
71
+ if (opts.wantedPackageManager?.name === packageManager.name) {
72
+ if (opts.wantedPackageManager.version !== targetVersion) {
73
+ previousVersion = opts.wantedPackageManager.version;
74
+ }
75
+ }
76
+ else if (packageManager.version !== targetVersion) {
77
+ previousVersion = packageManager.version;
78
+ }
79
+ const previousMajor = previousVersion != null
80
+ ? semver.coerce(previousVersion)?.major
81
+ : undefined;
82
+ const targetMajor = semver.major(targetVersion);
83
+ if (previousMajor != null && targetMajor > previousMajor) {
84
+ const hint = MAJOR_UPGRADE_HINTS[targetMajor];
85
+ if (hint)
86
+ globalWarn(hint);
87
+ }
55
88
  if (opts.wantedPackageManager?.name === packageManager.name) {
56
89
  if (opts.wantedPackageManager?.version !== resolution.manifest.version) {
57
90
  const { manifest, writeProjectManifest } = await readProjectManifest(opts.rootProjectManifestDir);
58
91
  if (manifest.devEngines?.packageManager) {
59
- if (Array.isArray(manifest.devEngines.packageManager)) {
60
- const pnpmEntry = manifest.devEngines.packageManager.find((e) => e.name === 'pnpm');
61
- if (pnpmEntry) {
62
- const updated = updateVersionConstraint(pnpmEntry.version, resolution.manifest.version);
63
- if (updated !== pnpmEntry.version) {
64
- pnpmEntry.version = updated;
65
- await writeProjectManifest(manifest);
66
- }
92
+ let manifestChanged = false;
93
+ // If "packageManager" pins pnpm, treat both fields as the user's
94
+ // single source of truth for the active pnpm version: rewrite both
95
+ // to the new exact version (dropping any range operator in
96
+ // devEngines and any integrity hash on the legacy field). When only
97
+ // devEngines is set, preserve the user's range style and let the
98
+ // lockfile pin the exact version.
99
+ const legacyPm = manifest.packageManager != null
100
+ ? parsePackageManager(manifest.packageManager)
101
+ : undefined;
102
+ const legacyPinsPnpm = legacyPm?.name === 'pnpm' && legacyPm.version != null;
103
+ const devEnginesPm = manifest.devEngines.packageManager;
104
+ const pnpmEntry = Array.isArray(devEnginesPm)
105
+ ? devEnginesPm.find((e) => e.name === 'pnpm')
106
+ : devEnginesPm.name === 'pnpm' ? devEnginesPm : undefined;
107
+ if (pnpmEntry) {
108
+ const updated = legacyPinsPnpm
109
+ ? resolution.manifest.version
110
+ : updateVersionConstraint(pnpmEntry.version, resolution.manifest.version);
111
+ if (updated !== pnpmEntry.version) {
112
+ pnpmEntry.version = updated;
113
+ manifestChanged = true;
67
114
  }
68
115
  }
69
- else if (manifest.devEngines.packageManager.name === 'pnpm') {
70
- const updated = updateVersionConstraint(manifest.devEngines.packageManager.version, resolution.manifest.version);
71
- if (updated !== manifest.devEngines.packageManager.version) {
72
- manifest.devEngines.packageManager.version = updated;
73
- await writeProjectManifest(manifest);
116
+ if (legacyPinsPnpm) {
117
+ const newLegacy = `pnpm@${resolution.manifest.version}`;
118
+ if (manifest.packageManager !== newLegacy) {
119
+ manifest.packageManager = newLegacy;
120
+ manifestChanged = true;
74
121
  }
75
122
  }
123
+ if (manifestChanged)
124
+ await writeProjectManifest(manifest);
76
125
  const store = await createStoreController(opts);
77
126
  await resolvePackageManagerIntegrities(resolution.manifest.version, {
78
127
  registries: opts.registries,
@@ -94,6 +143,7 @@ export async function handler(opts, params) {
94
143
  if (resolution.manifest.version === packageManager.version) {
95
144
  return `The currently active ${packageManager.name} v${packageManager.version} is already "${bareSpecifier}" and doesn't need an update`;
96
145
  }
146
+ globalInfo(`Updating pnpm from v${packageManager.version} to v${resolution.manifest.version}...`);
97
147
  const store = await createStoreController(opts);
98
148
  // Resolve integrities and write env lockfile to pnpm-lock.yaml
99
149
  const envLockfile = await resolvePackageManagerIntegrities(resolution.manifest.version, {
@@ -113,7 +163,7 @@ export async function handler(opts, params) {
113
163
  if (alreadyExisted) {
114
164
  return `The ${bareSpecifier} version, v${resolution.manifest.version}, is already present on the system. It was activated by linking it from ${baseDir}.`;
115
165
  }
116
- return undefined;
166
+ return `Successfully updated pnpm to v${resolution.manifest.version}`;
117
167
  }
118
168
  /**
119
169
  * Returns the updated version constraint for devEngines.packageManager.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/engine.pm.commands",
3
- "version": "1101.0.2",
3
+ "version": "1101.1.1",
4
4
  "description": "pnpm commands for self-updating and setting up pnpm",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -32,25 +32,25 @@
32
32
  "render-help": "^2.0.0",
33
33
  "semver": "^7.7.2",
34
34
  "symlink-dir": "^10.0.1",
35
- "@pnpm/cli.meta": "1100.0.1",
36
35
  "@pnpm/bins.linker": "1100.0.2",
37
- "@pnpm/building.policy": "1100.0.1",
36
+ "@pnpm/cli.meta": "1100.0.1",
38
37
  "@pnpm/cli.utils": "1101.0.0",
39
38
  "@pnpm/deps.graph-hasher": "1100.1.1",
40
- "@pnpm/global.commands": "1100.0.4",
39
+ "@pnpm/building.policy": "1100.0.1",
40
+ "@pnpm/global.commands": "1100.0.6",
41
+ "@pnpm/config.reader": "1101.1.2",
41
42
  "@pnpm/global.packages": "1100.0.1",
42
- "@pnpm/config.reader": "1101.1.1",
43
- "@pnpm/installing.client": "1100.0.4",
44
- "@pnpm/installing.deps-restorer": "1101.0.0",
45
- "@pnpm/lockfile.types": "1100.0.2",
46
- "@pnpm/shell.path": "1100.0.0",
47
- "@pnpm/store.connection-manager": "1100.0.4",
48
- "@pnpm/installing.env-installer": "1101.0.0",
49
- "@pnpm/resolving.npm-resolver": "1101.0.0",
43
+ "@pnpm/installing.client": "1100.0.6",
50
44
  "@pnpm/error": "1100.0.0",
51
- "@pnpm/types": "1101.0.0",
45
+ "@pnpm/installing.deps-restorer": "1101.0.1",
46
+ "@pnpm/installing.env-installer": "1101.0.1",
47
+ "@pnpm/resolving.npm-resolver": "1101.0.0",
48
+ "@pnpm/shell.path": "1100.0.0",
49
+ "@pnpm/lockfile.types": "1100.0.2",
52
50
  "@pnpm/store.controller": "1101.0.0",
53
- "@pnpm/workspace.project-manifest-reader": "1100.0.2"
51
+ "@pnpm/types": "1101.0.0",
52
+ "@pnpm/workspace.project-manifest-reader": "1100.0.2",
53
+ "@pnpm/store.connection-manager": "1100.0.6"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "@pnpm/logger": ">=1001.0.0 <1002.0.0"
@@ -61,11 +61,11 @@
61
61
  "@types/ramda": "0.31.1",
62
62
  "@types/semver": "7.7.1",
63
63
  "@pnpm/constants": "1100.0.0",
64
+ "@pnpm/engine.pm.commands": "1101.1.1",
65
+ "@pnpm/logger": "1100.0.0",
64
66
  "@pnpm/error": "1100.0.0",
65
- "@pnpm/engine.pm.commands": "1101.0.2",
66
- "@pnpm/testing.mock-agent": "1100.0.1",
67
67
  "@pnpm/prepare": "1100.0.3",
68
- "@pnpm/logger": "1100.0.0"
68
+ "@pnpm/testing.mock-agent": "1100.0.1"
69
69
  },
70
70
  "engines": {
71
71
  "node": ">=22.13"