diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index f1d11a508..7073d0ef5 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -22,16 +22,12 @@ jobs: run: | LATEST_BERRY_VERSION=$(curl https://repo.yarnpkg.com/tags | jq -r '.latest.stable') - LATEST_NPM=$(curl https://registry.npmjs.org/npm | jq '.["dist-tags"].latest + "+sha1." + .versions[.["dist-tags"].latest].dist.shasum') LATEST_PNPM=$(curl https://registry.npmjs.org/pnpm | jq '.["dist-tags"].latest + "+sha1." + .versions[.["dist-tags"].latest].dist.shasum') LATEST_YARN=$(curl https://registry.npmjs.org/yarn | jq '.["dist-tags"].latest + "+sha1." + .versions[.["dist-tags"].latest].dist.shasum') LATEST_BERRY=$(jq -n '$version + "+sha224." + $checksum' --arg version "$LATEST_BERRY_VERSION" --arg checksum "$(curl https://repo.yarnpkg.com/"$LATEST_BERRY_VERSION"/packages/yarnpkg-cli/bin/yarn.js | openssl dgst -sha224 | cut -d' ' -f2)") git --no-pager show HEAD:config.json | jq '. * '"{ definitions: { - npm: { - default: $LATEST_NPM, - }, pnpm: { default: $LATEST_PNPM, }, diff --git a/README.md b/README.md index 4d65c2b1a..2b4d9ce1b 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ Corepack is a zero-runtime-dependency Node.js script that acts as a bridge between Node.js projects and the package managers they are intended to be used -with during development. In practical terms, **Corepack lets you use Yarn, npm, -and pnpm without having to install them**. +with during development. In practical terms, **Corepack lets you use Yarn and pnpm +without having to install them**. ## How to Install @@ -50,8 +50,8 @@ See [`CONTRIBUTING.md`](./CONTRIBUTING.md). ### When Building Packages Just use your package managers as you usually would. Run `yarn install` in Yarn -projects, `pnpm install` in pnpm projects, and `npm` in npm projects. Corepack -will catch these calls, and depending on the situation: +projects and `pnpm install` in pnpm projects. Corepack will catch these calls, +and depending on the situation: - **If the local project is configured for the package manager you're using**, Corepack will silently download and cache the latest compatible version. @@ -79,7 +79,7 @@ Here, `yarn` is the name of the package manager, specified at version `3.2.3`, along with the SHA-224 hash of this version for validation. `packageManager@x.y.z` is required. The hash is optional but strongly recommended as a security practice. Permitted values for the package manager are -`yarn`, `npm`, and `pnpm`. +`yarn` and `pnpm`. You can also provide a URL to a `.js` file (which will be interpreted as a CommonJS module) or a `.tgz` file (which will be interpreted as a package, and @@ -148,9 +148,7 @@ Clears the local `COREPACK_HOME` cache directory. This command will detect where Corepack is installed and will create shims next to it for each of the specified package managers (or all of them if the command -is called without parameters). Note that the npm shims will not be installed -unless explicitly requested, as npm is currently distributed with Node.js -through other means. +is called without parameters). If the file system where the `corepack` binary is located is read-only, this command will fail. A workaround is to add the binaries as alias in your @@ -161,8 +159,6 @@ alias yarn="corepack yarn" alias yarnpkg="corepack yarnpkg" alias pnpm="corepack pnpm" alias pnpx="corepack pnpx" -alias npm="corepack npm" -alias npx="corepack npx" ``` On Windows PowerShell, you can add functions using the `$PROFILE` automatic @@ -173,8 +169,6 @@ echo "function yarn { corepack yarn `$args }" >> $PROFILE echo "function yarnpkg { corepack yarnpkg `$args }" >> $PROFILE echo "function pnpm { corepack pnpm `$args }" >> $PROFILE echo "function pnpx { corepack pnpx `$args }" >> $PROFILE -echo "function npm { corepack npm `$args }" >> $PROFILE -echo "function npx { corepack npx `$args }" >> $PROFILE ``` ### `corepack disable [... name]` @@ -250,7 +244,7 @@ same major line. Should you need to upgrade to a new major, use an explicit ask for user input before starting the download. - `COREPACK_ENABLE_UNSAFE_CUSTOM_URLS` can be set to `1` to allow use of - custom URLs to load a package manager known by Corepack (`yarn`, `npm`, and + custom URLs to load a package manager known by Corepack (`yarn` and `pnpm`). - `COREPACK_ENABLE_NETWORK` can be set to `0` to prevent Corepack from accessing diff --git a/config.json b/config.json index cb7449f62..d6409bdf0 100644 --- a/config.json +++ b/config.json @@ -1,42 +1,5 @@ { "definitions": { - "npm": { - "default": "10.4.0+sha1.904025b4d932cfaed8799e644a1c5ae7f02729fc", - "fetchLatestFrom": { - "type": "npm", - "package": "npm" - }, - "transparent": { - "commands": [ - [ - "npm", - "init" - ], - [ - "npx" - ] - ] - }, - "ranges": { - "*": { - "url": "https://registry.npmjs.org/npm/-/npm-{}.tgz", - "bin": { - "npm": "./bin/npm-cli.js", - "npx": "./bin/npx-cli.js" - }, - "registry": { - "type": "npm", - "package": "npm" - }, - "commands": { - "use": [ - "npm", - "install" - ] - } - } - } - }, "pnpm": { "default": "8.15.3+sha1.64838798f519c18029c1e8a1310e16101fc2eda0", "fetchLatestFrom": { diff --git a/package.json b/package.json index c48a883f4..0bfef6554 100644 --- a/package.json +++ b/package.json @@ -83,10 +83,6 @@ "./dist/yarn.js", "./dist/yarnpkg.js", "./dist/corepack.js", - "./shims/npm", - "./shims/npm.ps1", - "./shims/npx", - "./shims/npx.ps1", "./shims/pnpm", "./shims/pnpm.ps1", "./shims/pnpx", diff --git a/sources/commands/Base.ts b/sources/commands/Base.ts index 0067ae716..ef7c0e4c8 100644 --- a/sources/commands/Base.ts +++ b/sources/commands/Base.ts @@ -1,10 +1,8 @@ import {Command, UsageError} from 'clipanion'; -import fs from 'fs'; import {PreparedPackageManagerInfo} from '../Engine'; import * as corepackUtils from '../corepackUtils'; import {Context} from '../main'; -import * as nodeUtils from '../nodeUtils'; import * as specUtils from '../specUtils'; export abstract class BaseCommand extends Command { diff --git a/sources/commands/Disable.ts b/sources/commands/Disable.ts index 68a99e6bd..b3086da5f 100644 --- a/sources/commands/Disable.ts +++ b/sources/commands/Disable.ts @@ -1,11 +1,11 @@ -import {Command, Option, UsageError} from 'clipanion'; -import fs from 'fs'; -import path from 'path'; -import which from 'which'; +import {Command, Option, UsageError} from 'clipanion'; +import fs from 'fs'; +import path from 'path'; +import which from 'which'; -import {Context} from '../main'; -import type {NodeError} from '../nodeUtils'; -import {isSupportedPackageManager, SupportedPackageManagerSetWithoutNpm} from '../types'; +import {Context} from '../main'; +import type {NodeError} from '../nodeUtils'; +import {SupportedPackageManagerSet, isSupportedPackageManager} from '../types'; export class DisableCommand extends Command { static paths = [ @@ -47,7 +47,7 @@ export class DisableCommand extends Command { installDirectory = path.dirname(await which(`corepack`)); const names = this.names.length === 0 - ? SupportedPackageManagerSetWithoutNpm + ? SupportedPackageManagerSet : this.names; for (const name of new Set(names)) { diff --git a/sources/commands/Enable.ts b/sources/commands/Enable.ts index 195087d30..aa1480fcb 100644 --- a/sources/commands/Enable.ts +++ b/sources/commands/Enable.ts @@ -1,11 +1,11 @@ -import cmdShim from '@zkochan/cmd-shim'; -import {Command, Option, UsageError} from 'clipanion'; -import fs from 'fs'; -import path from 'path'; -import which from 'which'; +import cmdShim from '@zkochan/cmd-shim'; +import {Command, Option, UsageError} from 'clipanion'; +import fs from 'fs'; +import path from 'path'; +import which from 'which'; -import {Context} from '../main'; -import {isSupportedPackageManager, SupportedPackageManagerSetWithoutNpm} from '../types'; +import {Context} from '../main'; +import {isSupportedPackageManager, SupportedPackageManagerSet} from '../types'; export class EnableCommand extends Command { static paths = [ @@ -57,7 +57,7 @@ export class EnableCommand extends Command { throw new Error(`Assertion failed: The stub folder doesn't exist`); const names = this.names.length === 0 - ? SupportedPackageManagerSetWithoutNpm + ? SupportedPackageManagerSet : this.names; for (const name of new Set(names)) { diff --git a/sources/corepackUtils.ts b/sources/corepackUtils.ts index db040bc02..39676af16 100644 --- a/sources/corepackUtils.ts +++ b/sources/corepackUtils.ts @@ -350,13 +350,6 @@ export async function runVersion(locator: Locator, installSpec: InstallSpec & {s if (!binPath) throw new Error(`Assertion failed: Unable to locate path for bin '${binName}'`); - // Node.js segfaults when using npm@>=9.7.0 and v8-compile-cache - // $ docker run -it node:20.3.0-slim corepack npm@9.7.1 --version - // [SIGSEGV] - if (locator.name !== `npm` || semver.lt(locator.reference, `9.7.0`)) - // @ts-expect-error - No types - await import(`v8-compile-cache`); - // We load the binary into the current process, // while making it think it was spawned. diff --git a/sources/types.ts b/sources/types.ts index 20d66233e..dd2c5e9da 100644 --- a/sources/types.ts +++ b/sources/types.ts @@ -2,7 +2,6 @@ export type BinSpec = {[key: string]: string}; export type BinList = Array; export enum SupportedPackageManagers { - Npm = `npm`, Pnpm = `pnpm`, Yarn = `yarn`, } @@ -11,13 +10,6 @@ export const SupportedPackageManagerSet = new Set( Object.values(SupportedPackageManagers), ); -export const SupportedPackageManagerSetWithoutNpm = new Set( - Object.values(SupportedPackageManagers), -); - -// npm is distributed with Node as a builtin; we don't want Corepack to override it unless the npm team is on board -SupportedPackageManagerSetWithoutNpm.delete(SupportedPackageManagers.Npm); - export function isSupportedPackageManager(value: string): value is SupportedPackageManagers { return SupportedPackageManagerSet.has(value as SupportedPackageManagers); } diff --git a/tests/Disable.test.ts b/tests/Disable.test.ts index 682a6817c..34c4b9005 100644 --- a/tests/Disable.test.ts +++ b/tests/Disable.test.ts @@ -1,13 +1,13 @@ -import {describe, beforeEach, it, expect} from '@jest/globals'; -import {Filename, ppath, xfs, npath} from '@yarnpkg/fslib'; -import {delimiter} from 'node:path'; -import process from 'node:process'; +import {describe, beforeEach, it, expect} from '@jest/globals'; +import {Filename, ppath, xfs, npath} from '@yarnpkg/fslib'; +import {delimiter} from 'node:path'; +import process from 'node:process'; -import {Engine} from '../sources/Engine'; -import {SupportedPackageManagerSetWithoutNpm} from '../sources/types'; +import {Engine} from '../sources/Engine'; +import {SupportedPackageManagerSet} from '../sources/types'; -import {makeBin, getBinaryNames} from './_binHelpers'; -import {runCli} from './_runCli'; +import {makeBin, getBinaryNames} from './_binHelpers'; +import {runCli} from './_runCli'; const engine = new Engine(); @@ -22,7 +22,7 @@ describe(`DisableCommand`, () => { const corepackBin = await makeBin(cwd, `corepack` as Filename); const dontRemoveBin = await makeBin(cwd, `dont-remove` as Filename); - for (const packageManager of SupportedPackageManagerSetWithoutNpm) + for (const packageManager of SupportedPackageManagerSet) for (const binName of engine.getBinariesFor(packageManager)) for (const variant of getBinaryNames(binName)) await makeBin(cwd, variant as Filename, {ignorePlatform: true}); @@ -47,7 +47,7 @@ describe(`DisableCommand`, () => { await xfs.mktempPromise(async cwd => { const dontRemoveBin = await makeBin(cwd, `dont-remove` as Filename); - for (const packageManager of SupportedPackageManagerSetWithoutNpm) + for (const packageManager of SupportedPackageManagerSet) for (const binName of engine.getBinariesFor(packageManager)) for (const variant of getBinaryNames(binName)) await makeBin(cwd, variant as Filename, {ignorePlatform: true}); @@ -66,7 +66,7 @@ describe(`DisableCommand`, () => { await xfs.mktempPromise(async cwd => { const binNames = new Set(); - for (const packageManager of SupportedPackageManagerSetWithoutNpm) + for (const packageManager of SupportedPackageManagerSet) for (const binName of engine.getBinariesFor(packageManager)) for (const variant of getBinaryNames(binName)) binNames.add(variant); diff --git a/tests/Enable.test.ts b/tests/Enable.test.ts index b0f4e168f..fcaa5847b 100644 --- a/tests/Enable.test.ts +++ b/tests/Enable.test.ts @@ -1,13 +1,13 @@ -import {describe, beforeEach, it, expect} from '@jest/globals'; -import {Filename, ppath, xfs, npath} from '@yarnpkg/fslib'; -import {delimiter} from 'node:path'; -import process from 'node:process'; +import {describe, beforeEach, it, expect} from '@jest/globals'; +import {Filename, ppath, xfs, npath} from '@yarnpkg/fslib'; +import {delimiter} from 'node:path'; +import process from 'node:process'; -import {Engine} from '../sources/Engine'; -import {SupportedPackageManagers, SupportedPackageManagerSetWithoutNpm} from '../sources/types'; +import {Engine} from '../sources/Engine'; +import {SupportedPackageManagers, SupportedPackageManagerSet} from '../sources/types'; -import {makeBin, getBinaryNames} from './_binHelpers'; -import {runCli} from './_runCli'; +import {makeBin, getBinaryNames} from './_binHelpers'; +import {runCli} from './_runCli'; const engine = new Engine(); @@ -34,7 +34,7 @@ describe(`EnableCommand`, () => { }); const expectedEntries: Array = [ppath.basename(corepackBin)]; - for (const packageManager of SupportedPackageManagerSetWithoutNpm) + for (const packageManager of SupportedPackageManagerSet) for (const binName of engine.getBinariesFor(packageManager)) expectedEntries.push(...getBinaryNames(binName)); @@ -57,7 +57,7 @@ describe(`EnableCommand`, () => { }); const expectedEntries: Array = [ppath.basename(corepackBin)]; - for (const packageManager of SupportedPackageManagerSetWithoutNpm) + for (const packageManager of SupportedPackageManagerSet) for (const binName of engine.getBinariesFor(packageManager)) expectedEntries.push(...getBinaryNames(binName)); diff --git a/tests/_runCli.ts b/tests/_runCli.ts index 53077bacd..448938b2e 100644 --- a/tests/_runCli.ts +++ b/tests/_runCli.ts @@ -1,12 +1,14 @@ import {PortablePath, npath} from '@yarnpkg/fslib'; import {spawn} from 'child_process'; -export async function runCli(cwd: PortablePath, argv: Array): Promise<{exitCode: number | null, stdout: string, stderr: string}> { +export async function runCli(cwd: PortablePath, argv: Array, record: Boolean = true): Promise<{exitCode: number | null, stdout: string, stderr: string}> { const out: Array = []; const err: Array = []; return new Promise((resolve, reject) => { - const child = spawn(process.execPath, [`--no-warnings`, `-r`, require.resolve(`./recordRequests.js`), require.resolve(`../dist/corepack.js`), ...argv], { + const base = [require.resolve(`../dist/corepack.js`), ...argv]; + const args = (record) ? [`--no-warnings`, `-r`, require.resolve(`./recordRequests.js`), ...base] : base; + const child = spawn(process.execPath, args, { cwd: npath.fromPortablePath(cwd), env: process.env, stdio: `pipe`, diff --git a/tests/main.test.ts b/tests/main.test.ts index 41616c7fb..177c3e055 100644 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -8,7 +8,6 @@ import {SupportedPackageManagerSet} from '../sources/types'; import {runCli} from './_runCli'; - beforeEach(async () => { // `process.env` is reset after each tests in setupTests.js. process.env.COREPACK_HOME = npath.fromPortablePath(await xfs.mktempPromise()); @@ -125,9 +124,6 @@ const testedPackageManagers: Array<[string, string] | [string, string, string]> [`pnpm`, `6.6.2`], [`pnpm`, `6.6.2+sha1.7b4d6b176c1b93b5670ed94c24babb7d80c13854`], [`pnpm`, `6.6.2+sha224.eb5c0acad3b0f40ecdaa2db9aa5a73134ad256e17e22d1419a2ab073`], - [`npm`, `6.14.2`], - [`npm`, `6.14.2+sha1.f057d35cd4792c4c511bb1fa332edb43143d07b0`], - [`npm`, `6.14.2+sha224.50512c1eb404900ee78586faa6d756b8d867ff46a328e6fb4cdf3a87`], ]; for (const [name, version, expectedVersion = version.split(`+`, 1)[0]] of testedPackageManagers) { @@ -208,14 +204,6 @@ it(`should ignore the packageManager field when found within a node_modules vend packageManager: `yarn@1.22.4`, }); - await xfs.writeJsonPromise(ppath.join(cwd, `node_modules/foo/package.json` as PortablePath), { - packageManager: `npm@6.14.2`, - }); - - await xfs.writeJsonPromise(ppath.join(cwd, `node_modules/@foo/bar/package.json` as PortablePath), { - packageManager: `npm@6.14.2`, - }); - await expect(runCli(ppath.join(cwd, `node_modules/foo` as PortablePath), [`yarn`, `--version`])).resolves.toMatchObject({ exitCode: 0, stderr: ``, @@ -239,52 +227,26 @@ it(`should use the closest matching packageManager field`, async () => { }); await xfs.writeJsonPromise(ppath.join(cwd, `foo/package.json` as PortablePath), { - packageManager: `npm@6.14.2`, + packageManager: `yarn@2.4.3`, }); - await expect(runCli(ppath.join(cwd, `foo` as PortablePath), [`npm`, `--version`])).resolves.toMatchObject({ + await expect(runCli(ppath.join(cwd, `foo` as PortablePath), [`yarn`, `--version`])).resolves.toMatchObject({ exitCode: 0, stderr: ``, - stdout: `6.14.2\n`, + stdout: `2.4.3\n`, }); }); }); it(`should expose its root to spawned processes`, async () => { await xfs.mktempPromise(async cwd => { - await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { - packageManager: `npm@6.14.2`, - }); + await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {}); - await expect(runCli(cwd, [`npm`, `run`, `env`])).resolves.toMatchObject({ - exitCode: 0, - stdout: expect.stringContaining(`COREPACK_ROOT=${npath.dirname(__dirname)}`), - }); - }); -}); - -it(`shouldn't allow using regular Yarn commands on npm-configured projects`, async () => { - await xfs.mktempPromise(async cwd => { - await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { - packageManager: `npm@6.14.2`, - }); - - await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ - exitCode: 1, - stderr: ``, - }); - }); -}); - -it(`should allow using transparent commands on npm-configured projects`, async () => { - await xfs.mktempPromise(async cwd => { - await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { - packageManager: `npm@6.14.2`, - }); - - await expect(runCli(cwd, [`yarn`, `dlx`, `--help`])).resolves.toMatchObject({ - exitCode: 0, - stderr: ``, + await xfs.mktempPromise(async cwd => { + await expect(runCli(cwd, [`pnpm@8.15.4`, `exec`, `env`], false)).resolves.toMatchObject({ + exitCode: 0, + stdout: expect.stringContaining(`COREPACK_ROOT=${npath.dirname(__dirname)}`), + }); }); }); }); @@ -353,7 +315,7 @@ it(`should allow updating the pinned version using the "corepack install -g" com it(`should allow to call "corepack install -g" with a tag`, async () => { await xfs.mktempPromise(async cwd => { - await expect(runCli(cwd, [`install`, `-g`, `npm@latest-7`])).resolves.toMatchObject({ + await expect(runCli(cwd, [`install`, `-g`, `pnpm@latest-7`])).resolves.toMatchObject({ exitCode: 0, stderr: ``, }); @@ -362,7 +324,7 @@ it(`should allow to call "corepack install -g" with a tag`, async () => { // empty package.json file }); - await expect(runCli(cwd, [`npm`, `--version`])).resolves.toMatchObject({ + await expect(runCli(cwd, [`pnpm`, `--version`])).resolves.toMatchObject({ stdout: expect.stringMatching(/^7\./), exitCode: 0, }); diff --git a/tests/nocks.db b/tests/nocks.db index 74660b09e..bdd31a83f 100644 Binary files a/tests/nocks.db and b/tests/nocks.db differ