Skip to content

Commit 892749d

Browse files
committed
fixup
1 parent 7bfe707 commit 892749d

3 files changed

Lines changed: 112 additions & 29 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ same major line. Should you need to upgrade to a new major, use an explicit
300300
instruct Corepack to skip integrity checks, or to a JSON string containing
301301
custom keys.
302302

303+
- `COREPACK_DEV_ENGINE_${UPPER_CASE_PACKAGE_MANAGER_NAME}` can be set to give
304+
Corepack a specific version matching the range defined in `package.json`'s
305+
`devEngines.packageManager` field.
306+
303307
## Troubleshooting
304308

305309
The environment variable `DEBUG` can be set to `corepack` to enable additional debug logging.

sources/specUtils.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,17 @@ function parsePackageJSON(packageJSONContent: CorepackPackageJSON, localEnv?: Lo
8181
if (!semverSatisfies(localEnvVersion, version))
8282
throw new UsageError(`Local env key ${localEnvKey} defines a value of ${localEnvVersion} which does not match the version defined in package.json devEngines.packageManager of ${version}`);
8383

84-
debugUtils.log(`Using ${localEnvVersion} defined in .corepack.env`);
84+
debugUtils.log(`Using ${localEnvVersion} from the environment as it matches ${version} defined in project manifest`);
8585
version = localEnvVersion;
8686
} else {
8787
const {packageManager: pm} = packageJSONContent;
88-
if (pm?.startsWith(`${packageManager.name}@`) && semverSatisfies(pm.slice(packageManager.name.length + 1), version)) {
88+
if (pm) {
89+
if (!pm.startsWith(`${packageManager.name}@`))
90+
throw new UsageError(`"packageManager" field is set to ${JSON.stringify(pm)} which does not match the "devEngines.packageManager" field set to ${JSON.stringify(packageManager.name)}`);
91+
92+
if (!semverSatisfies(pm.slice(packageManager.name.length + 1), version))
93+
throw new UsageError(`"packageManager" field is set to ${JSON.stringify(pm)} which does not match the value defined in "devEngines.packageManager" for ${JSON.stringify(packageManager.name)} of ${JSON.stringify(version)}`);
94+
8995
return pm;
9096
}
9197
}

tests/main.test.ts

Lines changed: 100 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,49 @@ beforeEach(async () => {
1616
process.env.COREPACK_DEFAULT_TO_LATEST = `0`;
1717
});
1818

19-
it(`should refuse to download a package manager if the hash doesn't match`, async () => {
20-
await xfs.mktempPromise(async cwd => {
21-
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
22-
packageManager: `yarn@1.22.4+sha1.deadbeef`,
19+
describe(`should refuse to download a package manager if the hash doesn't match`, () => {
20+
it(`the one defined in "devEngines.packageManager" field`, async () => {
21+
await xfs.mktempPromise(async cwd => {
22+
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
23+
devEngines: {
24+
packageManager: {name: `yarn`, version: `1.22.4+sha1.deadbeef`},
25+
},
26+
});
27+
28+
await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({
29+
exitCode: 1,
30+
stderr: /Mismatch hashes/,
31+
stdout: ``,
32+
});
2333
});
34+
});
35+
it(`the one defined in env variable`, async () => {
36+
await xfs.mktempPromise(async cwd => {
37+
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
38+
devEngines: {
39+
packageManager: {name: `yarn`, version: `1.x`},
40+
},
41+
});
2442

25-
await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({
26-
exitCode: 1,
27-
stderr: /Mismatch hashes/,
28-
stdout: ``,
43+
process.env.COREPACK_DEV_ENGINES_YARN = `1.22.4+sha1.deadbeef`;
44+
await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({
45+
exitCode: 1,
46+
stderr: /Mismatch hashes/,
47+
stdout: ``,
48+
});
49+
});
50+
});
51+
it(`the one defined in "packageManager" field`, async () => {
52+
await xfs.mktempPromise(async cwd => {
53+
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
54+
packageManager: `yarn@1.22.4+sha1.deadbeef`,
55+
});
56+
57+
await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({
58+
exitCode: 1,
59+
stderr: /Mismatch hashes/,
60+
stdout: ``,
61+
});
2962
});
3063
});
3164
});
@@ -241,14 +274,14 @@ it(`should ignore the packageManager field when found within a node_modules vend
241274
});
242275
});
243276

244-
it(`should prefer devEngines to packageManager`, async () => {
277+
it(`should use hash from "packageManager" even when "devEngines" defines a different one`, async () => {
245278
await xfs.mktempPromise(async cwd => {
246279
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as PortablePath), {
247-
packageManager: `yarn@1.22.4`,
280+
packageManager: `yarn@3.0.0-rc.2+sha224.f83f6d1cbfac10ba6b516a62ccd2a72ccd857aa6c514d1cd7185ec60`,
248281
devEngines: {
249282
packageManager: {
250283
name: `yarn`,
251-
version: `3.0.0-rc.2+sha224.f83f6d1cbfac10ba6b516a62ccd2a72ccd857aa6c514d1cd7185ec60`,
284+
version: `3.0.0-rc.2+sha224.deadbeef`,
252285
},
253286
},
254287
});
@@ -287,7 +320,7 @@ describe(`should accept range in devEngines only if a specific version is provid
287320
});
288321
});
289322
});
290-
it(`either in env`, async() => {
323+
it(`either in an env variable`, async() => {
291324
await xfs.mktempPromise(async cwd => {
292325
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as PortablePath), {
293326
devEngines: {
@@ -311,7 +344,7 @@ describe(`should accept range in devEngines only if a specific version is provid
311344
});
312345
});
313346
});
314-
it(`either in package.json#packageManager`, async() => {
347+
it(`either in package.json#packageManager field`, async() => {
315348
await xfs.mktempPromise(async cwd => {
316349
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as PortablePath), {
317350
devEngines: {
@@ -345,22 +378,62 @@ describe(`should accept range in devEngines only if a specific version is provid
345378
});
346379
});
347380

348-
it(`should reject if range in devEngines does not match version provided in .corepack.env`, async () => {
349-
await xfs.mktempPromise(async cwd => {
350-
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as PortablePath), {
351-
devEngines: {
352-
packageManager: {
353-
name: `pnpm`,
354-
version: `10.x`,
381+
describe(`should reject if range in devEngines does not match version provided`, () => {
382+
it(`in .corepack.env`, async () => {
383+
await xfs.mktempPromise(async cwd => {
384+
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as PortablePath), {
385+
devEngines: {
386+
packageManager: {
387+
name: `pnpm`,
388+
version: `10.x`,
389+
},
355390
},
356-
},
391+
});
392+
await xfs.writeFilePromise(ppath.join(cwd, `.corepack.env` as PortablePath),
393+
`COREPACK_DEV_ENGINES_PNPM=6.6.2+sha224.eb5c0acad3b0f40ecdaa2db9aa5a73134ad256e17e22d1419a2ab073\n`);
394+
await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({
395+
exitCode: 1,
396+
stderr: `Local env key COREPACK_DEV_ENGINES_PNPM defines a value of 6.6.2+sha224.eb5c0acad3b0f40ecdaa2db9aa5a73134ad256e17e22d1419a2ab073 which does not match the version defined in package.json devEngines.packageManager of 10.x\n`,
397+
stdout: ``,
398+
});
357399
});
358-
await xfs.writeFilePromise(ppath.join(cwd, `.corepack.env` as PortablePath),
359-
`COREPACK_DEV_ENGINES_PNPM=6.6.2+sha224.eb5c0acad3b0f40ecdaa2db9aa5a73134ad256e17e22d1419a2ab073\n`);
360-
await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({
361-
exitCode: 1,
362-
stderr: `Local env key COREPACK_DEV_ENGINES_PNPM defines a value of 6.6.2+sha224.eb5c0acad3b0f40ecdaa2db9aa5a73134ad256e17e22d1419a2ab073 which does not match the version defined in package.json devEngines.packageManager of 10.x\n`,
363-
stdout: ``,
400+
});
401+
402+
it(`in an env variable`, async () => {
403+
await xfs.mktempPromise(async cwd => {
404+
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as PortablePath), {
405+
devEngines: {
406+
packageManager: {
407+
name: `pnpm`,
408+
version: `10.x`,
409+
},
410+
},
411+
});
412+
process.env.COREPACK_DEV_ENGINES_PNPM = `6.6.2+sha224.eb5c0acad3b0f40ecdaa2db9aa5a73134ad256e17e22d1419a2ab073`;
413+
await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({
414+
exitCode: 1,
415+
stderr: `Local env key COREPACK_DEV_ENGINES_PNPM defines a value of 6.6.2+sha224.eb5c0acad3b0f40ecdaa2db9aa5a73134ad256e17e22d1419a2ab073 which does not match the version defined in package.json devEngines.packageManager of 10.x\n`,
416+
stdout: ``,
417+
});
418+
});
419+
});
420+
421+
it(`in package.json#packageManager field`, async () => {
422+
await xfs.mktempPromise(async cwd => {
423+
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as PortablePath), {
424+
devEngines: {
425+
packageManager: {
426+
name: `pnpm`,
427+
version: `10.x`,
428+
},
429+
},
430+
packageManager: `pnpm@6.6.2+sha224.eb5c0acad3b0f40ecdaa2db9aa5a73134ad256e17e22d1419a2ab073`,
431+
});
432+
await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({
433+
exitCode: 1,
434+
stderr: `"packageManager" field is set to "pnpm@6.6.2+sha224.eb5c0acad3b0f40ecdaa2db9aa5a73134ad256e17e22d1419a2ab073" which does not match the value defined in "devEngines.packageManager" for "pnpm" of "10.x"\n`,
435+
stdout: ``,
436+
});
364437
});
365438
});
366439
});

0 commit comments

Comments
 (0)