Skip to content

Commit 52d1b8e

Browse files
authored
Merge pull request #966 from lolmaus/pnpm-resoultion-mode
ember-try: Enforce resolution-mode=highest for pnpm versions 8.0.0 to 8.6.*
2 parents 2438dca + cb5f1a1 commit 52d1b8e

5 files changed

Lines changed: 449 additions & 6 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ If you include `useYarn: true` in your `ember-try` config, all npm scenarios wil
215215

216216
If you include `usePnpm: true` in your `ember-try` config, all npm scenarios will use `pnpm` for install with the `--no-lockfile` options. At cleanup, your dependencies will be restored to their prior state.
217217

218+
> ⚠ pnpm versions from 8.0.0 to 8.6.x have the default value of [resolution-mode](https://pnpm.io/npmrc#resolution-mode) setting changed to `lowest-direct`. This violates `ember-try` expectations as `resolution-mode` is expected to be `highest`, like in `npm` and `pnpm` versions < 8.0.0 and >= 8.7.0.
219+
>
220+
> If you run into this issue, we recommend to upgrade pnpm to latest version. If you are unable to upgrade, you can set `resolution-mode = highest` in the `.npmrc` file.
218221
219222
##### A note on npm scenarios with lockfiles
220223

lib/dependency-manager-adapters/pnpm.js

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const fs = require('fs-extra');
55
const path = require('path');
66
const debug = require('debug')('ember-try:dependency-manager-adapter:pnpm');
77
const Backup = require('../utils/backup');
8+
const semverLt = require('semver/functions/lt');
9+
const semverGte = require('semver/functions/gte');
810

911
const PACKAGE_JSON = 'package.json';
1012
const PNPM_LOCKFILE = 'pnpm-lock.yaml';
@@ -21,12 +23,12 @@ module.exports = CoreObject.extend({
2123
},
2224

2325
async setup() {
26+
await this._throwOnResolutionMode();
2427
await this.backup.addFiles([PACKAGE_JSON, PNPM_LOCKFILE]);
2528
},
2629

2730
async changeToDependencySet(depSet) {
2831
await this.applyDependencySet(depSet);
29-
3032
await this._install(depSet);
3133

3234
let deps = Object.assign({}, depSet.dependencies, depSet.devDependencies);
@@ -63,6 +65,49 @@ module.exports = CoreObject.extend({
6365
}
6466
},
6567

68+
/**
69+
* pnpm versions 8.0.0 through 8.6.* have the `resolution-mode` setting inverted to
70+
* `lowest-direct`, which breaks ember-try. This method throws a helpful error in the following
71+
* case: pnpm version is within dangerous range and `pnpm config get resolution-mode` reports an
72+
* empty value.
73+
*
74+
* @returns Promise<void>
75+
*/
76+
async _throwOnResolutionMode() {
77+
let version = await this._getPnpmVersion();
78+
let resolutionMode = await this._getResolutionMode();
79+
80+
if (this._isResolutionModeWrong(version, resolutionMode)) {
81+
throw new Error(
82+
'You are using an old version of pnpm that uses wrong resolution mode that violates ember-try expectations. Please either upgrade pnpm or set `resolution-mode` to `highest` in `.npmrc`.'
83+
);
84+
}
85+
},
86+
87+
async _getPnpmVersion() {
88+
let result = await this.run('pnpm', ['--version'], { cwd: this.cwd, stdio: 'pipe' });
89+
return result.stdout.split('\n')[0];
90+
},
91+
92+
async _getResolutionMode() {
93+
let result = await this.run('pnpm', ['config', 'get', 'resolution-mode'], {
94+
cwd: this.cwd,
95+
stdio: 'pipe',
96+
});
97+
98+
return result.stdout.split('\n')[0];
99+
},
100+
101+
_isResolutionModeWrong(versionStr, resolutionMode) {
102+
// The `resolution-mode` is not set explicitly, and the current pnpm version makes it default
103+
// to `lowest-direct`
104+
if (!resolutionMode.length && semverGte(versionStr, '8.0.0') && semverLt(versionStr, '8.7.0')) {
105+
return true;
106+
}
107+
108+
return false;
109+
},
110+
66111
async _install(depSet) {
67112
let mgrOptions = this.managerOptions || [];
68113

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
},
4545
"devDependencies": {
4646
"chai": "^4.3.4",
47+
"chai-as-promised": "^7.1.1",
4748
"codecov": "^3.8.3",
4849
"ember-cli": "~3.22.0",
4950
"eslint": "^7.31.0",
@@ -59,6 +60,7 @@
5960
"release-it": "^14.11.6",
6061
"release-it-lerna-changelog": "^3.1.0",
6162
"rsvp": "^4.7.0",
63+
"sinon": "^15.2.0",
6264
"tmp-sync": "^1.1.0"
6365
},
6466
"engines": {

0 commit comments

Comments
 (0)