From 20a0a03bb7a1556146c0d043305b47afa01a9ddd Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Mon, 14 Aug 2023 15:09:20 -0700 Subject: [PATCH] fix!: pin corepack version BREAKING CHANGE: This package now requires a minimum Node.js of v16.20.0. `corepack` v0.17.0 which ships with Node.js v16 seems completely broken (at least on my machine!) so we can't rely on the version shipped with Node.js. This adds `corepack` as a dev dependency, and since the minimum version is Node.js v16.20.0, we have to bump our minimum version as well. This also simplifies finding the `corepack` executable. --- README.md | 2 +- package-lock.json | 141 +++++++++++++++++++++------------- package.json | 3 +- src/pm/corepack.ts | 33 +++----- test/unit/pm/corepack.spec.ts | 5 +- 5 files changed, 103 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index a9486e222..3a8264bbe 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ It's recommended to install `midnight-smoker` as a dev dependency, if you want t Run `npm install midnight-smoker --save-dev`. -- Node.js versions supported: `^16.13.0 || ^18.0.0 || ^20.0.0` +- Node.js versions supported: `^16.20.0 || ^18.0.0 || ^20.0.0` - Minimum `npm` version supported: `v7.0.0` While odd-numbered Node.js releases _may_ work, they are not tested on and not officially supported. diff --git a/package-lock.json b/package-lock.json index a26efc472..b388ba2c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@types/semver": "7.5.0", "chalk": "4.1.2", + "corepack": "0.19.0", "debug": "4.3.4", "execa": "5.1.1", "lilconfig": "2.1.0", @@ -64,7 +65,7 @@ "unexpected-sinon": "11.1.0" }, "engines": { - "node": "^16.13.0 || ^18.0.0 || ^20.0.0", + "node": "^16.20.0 || ^18.0.0 || ^20.0.0", "npm": ">=7" } }, @@ -550,20 +551,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "dev": true, @@ -1035,8 +1022,9 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1051,8 +1039,9 @@ }, "node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1087,6 +1076,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "license": "MIT", @@ -1724,8 +1725,9 @@ }, "node_modules/cli-truncate": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", "dev": true, - "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^5.0.0" @@ -1739,8 +1741,9 @@ }, "node_modules/cli-truncate/node_modules/ansi-regex": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -1750,13 +1753,15 @@ }, "node_modules/cli-truncate/node_modules/emoji-regex": { "version": "9.2.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/cli-truncate/node_modules/string-width": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, - "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -1770,9 +1775,10 @@ } }, "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.0.1", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1924,6 +1930,21 @@ "dev": true, "license": "MIT" }, + "node_modules/corepack": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/corepack/-/corepack-0.19.0.tgz", + "integrity": "sha512-mG4nu1zM5autGOSxl+rrpbx7+ZBhn3gsgXh0bJQVUg3HOo9RTKQvdj7gmp+CDj5clIySRrnWUtZROGfQPGROyg==", + "bin": { + "corepack": "dist/corepack.js", + "pnpm": "dist/pnpm.js", + "pnpx": "dist/pnpx.js", + "yarn": "dist/yarn.js", + "yarnpkg": "dist/yarnpkg.js" + }, + "engines": { + "node": ">=16.20.0" + } + }, "node_modules/cosmiconfig": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", @@ -2247,8 +2268,9 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/elliptic": { "version": "6.5.4", @@ -2718,6 +2740,19 @@ "node": ">=10" } }, + "node_modules/eslint/node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -2735,7 +2770,6 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -2749,9 +2783,10 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.1", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2875,8 +2910,9 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -3130,9 +3166,10 @@ } }, "node_modules/globals": { - "version": "13.19.0", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -3143,17 +3180,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globals/node_modules/type-fest": { - "version": "0.20.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/globalthis": { "version": "1.0.3", "dev": true, @@ -3910,8 +3936,9 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -6013,8 +6040,9 @@ }, "node_modules/rfdc": { "version": "1.3.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true }, "node_modules/rimraf": { "version": "3.0.2", @@ -6247,8 +6275,9 @@ }, "node_modules/slice-ansi": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" @@ -6261,9 +6290,10 @@ } }, "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.1.0", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -6273,8 +6303,9 @@ }, "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -6825,9 +6856,9 @@ } }, "node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { "node": ">=10" diff --git a/package.json b/package.json index aed3eb28d..5e46a0f63 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ "dependencies": { "@types/semver": "7.5.0", "chalk": "4.1.2", + "corepack": "0.19.0", "debug": "4.3.4", "execa": "5.1.1", "lilconfig": "2.1.0", @@ -133,7 +134,7 @@ "unexpected-sinon": "11.1.0" }, "engines": { - "node": "^16.13.0 || ^18.0.0 || ^20.0.0", + "node": "^16.20.0 || ^18.0.0 || ^20.0.0", "npm": ">=7" }, "overrides": { diff --git a/src/pm/corepack.ts b/src/pm/corepack.ts index 0d379e8a2..aaf0baf58 100644 --- a/src/pm/corepack.ts +++ b/src/pm/corepack.ts @@ -1,13 +1,6 @@ import {node as execa, type Options as ExecaOptions} from 'execa'; -import which from 'which'; -import type {Executor, ExecOpts, ExecResult} from './executor'; - -/** - * Cached path to `corepack`. - * - * This should persist between instantiations, so here it is. - */ -let corepackPath: string | undefined; +import path from 'node:path'; +import type {ExecOpts, ExecResult, Executor} from './executor'; /** * Disables the strict `packageManager` field in `package.json`. @@ -25,18 +18,18 @@ const DEFAULT_ENV = { * @see {@link https://github.com/nodejs/corepack} */ export class CorepackExecutor implements Executor { + protected readonly corepackPath: string; + /** * @param pmId The package manager ID (`@`) to use as the first argument to `corepack`. */ - public constructor(private readonly pmId: string) {} - - protected async getCorepackPath(): Promise { - if (corepackPath) { - return corepackPath; - } - // TODO: handle missing corepack - corepackPath = await which('corepack'); - return corepackPath; + public constructor(private readonly pmId: string) { + this.corepackPath = path.resolve( + path.dirname(require.resolve('corepack/package.json')), + '..', + '.bin', + 'corepack', + ); } public async exec( @@ -44,9 +37,7 @@ export class CorepackExecutor implements Executor { execaOpts: ExecaOptions = {}, execOpts: ExecOpts = {}, ): Promise { - const corepack = await this.getCorepackPath(); - - const proc = execa(corepack, [this.pmId, ...args], { + const proc = execa(this.corepackPath, [this.pmId, ...args], { env: {...DEFAULT_ENV, ...execaOpts.env}, ...execaOpts, }); diff --git a/test/unit/pm/corepack.spec.ts b/test/unit/pm/corepack.spec.ts index 129a0f3d6..ab1330b23 100644 --- a/test/unit/pm/corepack.spec.ts +++ b/test/unit/pm/corepack.spec.ts @@ -24,7 +24,6 @@ describe('midnight-smoker', function () { ({CorepackExecutor} = rewiremock.proxy( () => require('../../../src/pm/corepack'), { - which: sandbox.stub().resolves('/usr/bin/phony/corepack'), execa: execaMock, }, )); @@ -57,7 +56,7 @@ describe('midnight-smoker', function () { expect( execaMock.node, 'was called with', - '/usr/bin/phony/corepack', + expect.it('to match', /corepack$/), ).and('was called once'); }); }); @@ -77,7 +76,7 @@ describe('midnight-smoker', function () { expect( execaMock.node, 'was called with', - '/usr/bin/phony/corepack', + expect.it('to match', /corepack$/), ).and('was called once'); }); });