mirror of https://github.com/nodejs/corepack.git
Compare commits
13 Commits
Author | SHA1 | Date |
---|---|---|
|
15498ddb9a | |
|
9a1794a59f | |
|
783a42fbe3 | |
|
98fd966176 | |
|
5fc3691354 | |
|
b45b3a3244 | |
|
77fff3c1f3 | |
|
273237a110 | |
|
2b43f26135 | |
|
aefde28a63 | |
|
0b94797f96 | |
|
679bcefda5 | |
|
633764f7c4 |
|
@ -46,15 +46,21 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
node:
|
node:
|
||||||
- 18
|
|
||||||
- 20
|
- 20
|
||||||
- 22
|
- 22
|
||||||
- 23
|
- 24
|
||||||
platform:
|
platform:
|
||||||
- ubuntu-latest
|
- ubuntu-latest
|
||||||
- macos-latest
|
- macos-latest
|
||||||
- windows-latest
|
- windows-latest
|
||||||
|
|
||||||
|
# Temporarily skipping Node.js 24 under Windows due to issue
|
||||||
|
# https://github.com/nodejs/corepack/issues/715
|
||||||
|
# vitest fails "handle integrity checks" on Windows with Node.js 24.x
|
||||||
|
exclude:
|
||||||
|
- node: 24
|
||||||
|
platform: windows-latest
|
||||||
|
|
||||||
name: "${{matrix.platform}} w/ Node.js ${{matrix.node}}.x"
|
name: "${{matrix.platform}} w/ Node.js ${{matrix.node}}.x"
|
||||||
runs-on: ${{matrix.platform}}
|
runs-on: ${{matrix.platform}}
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,14 @@ env:
|
||||||
YARN_ENABLE_GLOBAL_CACHE: false
|
YARN_ENABLE_GLOBAL_CACHE: false
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: read
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release-please:
|
release-please:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
outputs:
|
outputs:
|
||||||
release_created: ${{ steps.release.outputs.release_created }}
|
release_created: ${{ steps.release.outputs.release_created }}
|
||||||
release_tag: ${{ steps.release.outputs.tag_name }}
|
release_tag: ${{ steps.release.outputs.tag_name }}
|
||||||
|
@ -29,6 +31,9 @@ jobs:
|
||||||
needs: release-please
|
needs: release-please
|
||||||
if: ${{ needs.release-please.outputs.release_created }}
|
if: ${{ needs.release-please.outputs.release_created }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
id-token: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
@ -48,10 +53,10 @@ jobs:
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{runner.os}}-yarn-
|
${{runner.os}}-yarn-
|
||||||
|
|
||||||
|
- run: corepack yarn install --immutable
|
||||||
|
|
||||||
- name: Publish to the npm registry
|
- name: Publish to the npm registry
|
||||||
run: |
|
run: corepack yarn npm publish --provenance
|
||||||
corepack yarn install --immutable
|
|
||||||
corepack yarn npm publish
|
|
||||||
env:
|
env:
|
||||||
YARN_NPM_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
YARN_NPM_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"**/.yarn": true,
|
"**/.yarn": true,
|
||||||
"**/.pnp.*": true
|
"**/.pnp.*": true
|
||||||
},
|
},
|
||||||
"eslint.experimental.useFlatConfig": true,
|
"eslint.useFlatConfig": true,
|
||||||
"eslint.nodePath": ".yarn/sdks",
|
"eslint.nodePath": ".yarn/sdks",
|
||||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
|
|
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,5 +1,18 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [0.33.0](https://github.com/nodejs/corepack/compare/v0.32.0...v0.33.0) (2025-06-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Adds guard to avoid stepping on Yarn's feet ([#714](https://github.com/nodejs/corepack/issues/714)) ([5fc3691](https://github.com/nodejs/corepack/commit/5fc3691354eb5bdeca17a9495b234584353f0151))
|
||||||
|
* update package manager versions ([#671](https://github.com/nodejs/corepack/issues/671)) ([b45b3a3](https://github.com/nodejs/corepack/commit/b45b3a3244bacfbaf65188ae8c04209a1e98307d))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* debug text typo ([#698](https://github.com/nodejs/corepack/issues/698)) ([0b94797](https://github.com/nodejs/corepack/commit/0b94797f96e30e46e466873fe7d437d0471cd92c))
|
||||||
|
|
||||||
## [0.32.0](https://github.com/nodejs/corepack/compare/v0.31.0...v0.32.0) (2025-02-28)
|
## [0.32.0](https://github.com/nodejs/corepack/compare/v0.31.0...v0.32.0) (2025-02-28)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ and pnpm without having to install them**.
|
||||||
|
|
||||||
### Default Installs
|
### Default Installs
|
||||||
|
|
||||||
Corepack is [distributed by default with all recent Node.js versions](https://nodejs.org/api/corepack.html).
|
Corepack is distributed with Node.js from version 14.19.0 up to (but not including) 25.0.0.
|
||||||
Run `corepack enable` to install the required Yarn and pnpm binaries on your path.
|
Run `corepack enable` to install the required Yarn and pnpm binaries on your path.
|
||||||
|
|
||||||
### Manual Installs
|
### Manual Installs
|
||||||
|
@ -286,8 +286,8 @@ same major line. Should you need to upgrade to a new major, use an explicit
|
||||||
package manager, and to not update the Last Known Good version when it
|
package manager, and to not update the Last Known Good version when it
|
||||||
downloads a new version of the same major line.
|
downloads a new version of the same major line.
|
||||||
|
|
||||||
- `COREPACK_ENABLE_AUTO_PIN` can be set to `0` to prevent Corepack from
|
- `COREPACK_ENABLE_AUTO_PIN` can be set to `1` to instruct Corepack to
|
||||||
updating the `packageManager` field when it detects that the local package
|
update the `packageManager` field when it detects that the local package
|
||||||
doesn't list it. In general we recommend to always list a `packageManager`
|
doesn't list it. In general we recommend to always list a `packageManager`
|
||||||
field (which you can easily set through `corepack use [name]@[version]`), as
|
field (which you can easily set through `corepack use [name]@[version]`), as
|
||||||
it ensures that your project installs are always deterministic.
|
it ensures that your project installs are always deterministic.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"npm": {
|
"npm": {
|
||||||
"default": "11.1.0+sha1.dba08f7d0f5301ebedaf968b4f74b2282f97a750",
|
"default": "11.4.1+sha1.80350af543069991de20657ebcd07d9624cfad06",
|
||||||
"fetchLatestFrom": {
|
"fetchLatestFrom": {
|
||||||
"type": "npm",
|
"type": "npm",
|
||||||
"package": "npm"
|
"package": "npm"
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"default": "10.5.2+sha1.ca68c0441df195b7e2992f1d1cb12fb731f82d78",
|
"default": "10.11.0+sha1.4048eeefd564ff1ab248fac3e2854d38245fe2f1",
|
||||||
"fetchLatestFrom": {
|
"fetchLatestFrom": {
|
||||||
"type": "npm",
|
"type": "npm",
|
||||||
"package": "pnpm"
|
"package": "pnpm"
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
"package": "yarn"
|
"package": "yarn"
|
||||||
},
|
},
|
||||||
"transparent": {
|
"transparent": {
|
||||||
"default": "4.6.0+sha224.acd0786f07ffc6c933940eb65fc1d627131ddf5455bddcc295dc90fd",
|
"default": "4.9.1+sha224.4285002185abb91fe2b781f27fd1e078086c37a7b095f6ea4ee25971",
|
||||||
"commands": [
|
"commands": [
|
||||||
[
|
[
|
||||||
"yarn",
|
"yarn",
|
||||||
|
|
|
@ -13,11 +13,13 @@ export default [
|
||||||
...yarnpkg,
|
...yarnpkg,
|
||||||
{
|
{
|
||||||
rules: {
|
rules: {
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
'no-restricted-globals': [`error`, {
|
'no-restricted-globals': [`error`, {
|
||||||
name: `fetch`,
|
name: `fetch`,
|
||||||
message: `Use fetch from sources/httpUtils.ts`,
|
message: `Use fetch from sources/httpUtils.ts`,
|
||||||
}],
|
}],
|
||||||
|
'@typescript-eslint/no-unused-vars': [`error`, {
|
||||||
|
caughtErrors: `none`,
|
||||||
|
}],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
10
package.json
10
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "corepack",
|
"name": "corepack",
|
||||||
"version": "0.32.0",
|
"version": "0.33.0",
|
||||||
"homepage": "https://github.com/nodejs/corepack#readme",
|
"homepage": "https://github.com/nodejs/corepack#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/nodejs/corepack/issues"
|
"url": "https://github.com/nodejs/corepack/issues"
|
||||||
|
@ -10,27 +10,27 @@
|
||||||
"url": "https://github.com/nodejs/corepack.git"
|
"url": "https://github.com/nodejs/corepack.git"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.17.1 || ^20.10.0 || >=22.11.0"
|
"node": "^20.10.0 || ^22.11.0 || >=24.0.0"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
"./package.json": "./package.json"
|
"./package.json": "./package.json"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"packageManager": "yarn@4.6.0+sha512.5383cc12567a95f1d668fbe762dfe0075c595b4bfff433be478dbbe24e05251a8e8c3eb992a986667c1d53b6c3a9c85b8398c35a960587fbd9fa3a0915406728",
|
"packageManager": "yarn@4.9.0+sha224.dce6c5df199861784bd9b0eecb2a228df97e3f18a02b1bb75ff98383",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/debug": "^4.1.5",
|
"@types/debug": "^4.1.5",
|
||||||
"@types/node": "^20.4.6",
|
"@types/node": "^20.4.6",
|
||||||
"@types/proxy-from-env": "^1",
|
"@types/proxy-from-env": "^1",
|
||||||
"@types/semver": "^7.1.0",
|
"@types/semver": "^7.1.0",
|
||||||
"@types/which": "^3.0.0",
|
"@types/which": "^3.0.0",
|
||||||
"@yarnpkg/eslint-config": "^2.0.0",
|
"@yarnpkg/eslint-config": "^3.0.0",
|
||||||
"@yarnpkg/fslib": "^3.0.0-rc.48",
|
"@yarnpkg/fslib": "^3.0.0-rc.48",
|
||||||
"@zkochan/cmd-shim": "^6.0.0",
|
"@zkochan/cmd-shim": "^6.0.0",
|
||||||
"better-sqlite3": "^11.7.2",
|
"better-sqlite3": "^11.7.2",
|
||||||
"clipanion": "patch:clipanion@npm%3A3.2.1#~/.yarn/patches/clipanion-npm-3.2.1-fc9187f56c.patch",
|
"clipanion": "patch:clipanion@npm%3A3.2.1#~/.yarn/patches/clipanion-npm-3.2.1-fc9187f56c.patch",
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^9.22.0",
|
||||||
"proxy-from-env": "^1.1.0",
|
"proxy-from-env": "^1.1.0",
|
||||||
"semver": "^7.6.3",
|
"semver": "^7.6.3",
|
||||||
"supports-color": "^10.0.0",
|
"supports-color": "^10.0.0",
|
||||||
|
|
|
@ -274,7 +274,7 @@ export class Engine {
|
||||||
if (typeof locator.reference === `function`)
|
if (typeof locator.reference === `function`)
|
||||||
fallbackDescriptor.range = await locator.reference();
|
fallbackDescriptor.range = await locator.reference();
|
||||||
|
|
||||||
if (process.env.COREPACK_ENABLE_AUTO_PIN !== `0`) {
|
if (process.env.COREPACK_ENABLE_AUTO_PIN === `1`) {
|
||||||
const resolved = await this.resolveDescriptor(fallbackDescriptor, {allowTags: true});
|
const resolved = await this.resolveDescriptor(fallbackDescriptor, {allowTags: true});
|
||||||
if (resolved === null)
|
if (resolved === null)
|
||||||
throw new UsageError(`Failed to successfully resolve '${fallbackDescriptor.range}' to a valid ${fallbackDescriptor.name} release`);
|
throw new UsageError(`Failed to successfully resolve '${fallbackDescriptor.range}' to a valid ${fallbackDescriptor.name} release`);
|
||||||
|
@ -288,7 +288,7 @@ export class Engine {
|
||||||
await specUtils.setLocalPackageManager(path.dirname(result.target), installSpec);
|
await specUtils.setLocalPackageManager(path.dirname(result.target), installSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
debugUtils.log(`Falling back to ${fallbackDescriptor.name}@${fallbackDescriptor.range} in the absence of "packageManage" field in ${result.target}`);
|
debugUtils.log(`Falling back to ${fallbackDescriptor.name}@${fallbackDescriptor.range} in the absence of "packageManager" field in ${result.target}`);
|
||||||
return fallbackDescriptor;
|
return fallbackDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import fs from 'f
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import which from 'which';
|
import which from 'which';
|
||||||
|
|
||||||
|
import * as corepackUtils from '../corepackUtils';
|
||||||
import {Context} from '../main';
|
import {Context} from '../main';
|
||||||
import type {NodeError} from '../nodeUtils';
|
import type {NodeError} from '../nodeUtils';
|
||||||
import {isSupportedPackageManager, SupportedPackageManagerSetWithoutNpm} from '../types';
|
import {isSupportedPackageManager, SupportedPackageManagerSetWithoutNpm} from '../types';
|
||||||
|
@ -70,6 +71,11 @@ export class DisableCommand extends Command<Context> {
|
||||||
async removePosixLink(installDirectory: string, binName: string) {
|
async removePosixLink(installDirectory: string, binName: string) {
|
||||||
const file = path.join(installDirectory, binName);
|
const file = path.join(installDirectory, binName);
|
||||||
try {
|
try {
|
||||||
|
if (binName.includes(`yarn`) && corepackUtils.isYarnSwitchPath(await fs.promises.realpath(file))) {
|
||||||
|
console.warn(`${binName} is already installed in ${file} and points to a Yarn Switch install - skipping`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await fs.promises.unlink(file);
|
await fs.promises.unlink(file);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if ((err as NodeError).code !== `ENOENT`) {
|
if ((err as NodeError).code !== `ENOENT`) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import fs from 'f
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import which from 'which';
|
import which from 'which';
|
||||||
|
|
||||||
|
import * as corepackUtils from '../corepackUtils';
|
||||||
import {Context} from '../main';
|
import {Context} from '../main';
|
||||||
import {isSupportedPackageManager, SupportedPackageManagerSetWithoutNpm} from '../types';
|
import {isSupportedPackageManager, SupportedPackageManagerSetWithoutNpm} from '../types';
|
||||||
|
|
||||||
|
@ -83,6 +84,12 @@ export class EnableCommand extends Command<Context> {
|
||||||
|
|
||||||
if (fs.existsSync(file)) {
|
if (fs.existsSync(file)) {
|
||||||
const currentSymlink = await fs.promises.readlink(file);
|
const currentSymlink = await fs.promises.readlink(file);
|
||||||
|
|
||||||
|
if (binName.includes(`yarn`) && corepackUtils.isYarnSwitchPath(await fs.promises.realpath(file))) {
|
||||||
|
console.warn(`${binName} is already installed in ${file} and points to a Yarn Switch install - skipping`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentSymlink !== symlink) {
|
if (currentSymlink !== symlink) {
|
||||||
await fs.promises.unlink(file);
|
await fs.promises.unlink(file);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -19,6 +19,12 @@ import * as npmRegistryUtils from './npmRegist
|
||||||
import {RegistrySpec, Descriptor, Locator, PackageManagerSpec} from './types';
|
import {RegistrySpec, Descriptor, Locator, PackageManagerSpec} from './types';
|
||||||
import {BinList, BinSpec, InstallSpec, DownloadSpec} from './types';
|
import {BinList, BinSpec, InstallSpec, DownloadSpec} from './types';
|
||||||
|
|
||||||
|
const YARN_SWITCH_REGEX = /[/\\]switch[/\\]bin[/\\]/;
|
||||||
|
|
||||||
|
export function isYarnSwitchPath(p: string) {
|
||||||
|
return YARN_SWITCH_REGEX.test(p);
|
||||||
|
}
|
||||||
|
|
||||||
export function getRegistryFromPackageManagerSpec(spec: PackageManagerSpec) {
|
export function getRegistryFromPackageManagerSpec(spec: PackageManagerSpec) {
|
||||||
return process.env.COREPACK_NPM_REGISTRY
|
return process.env.COREPACK_NPM_REGISTRY
|
||||||
? spec.npmRegistry ?? spec.registry
|
? spec.npmRegistry ?? spec.registry
|
||||||
|
|
|
@ -58,15 +58,15 @@ export function parseSpec(raw: unknown, source: string, {enforceExactVersion = t
|
||||||
|
|
||||||
type CorepackPackageJSON = {
|
type CorepackPackageJSON = {
|
||||||
packageManager?: string;
|
packageManager?: string;
|
||||||
devEngines?: { packageManager?: DevEngineDependency };
|
devEngines?: {packageManager?: DevEngineDependency};
|
||||||
};
|
};
|
||||||
|
|
||||||
interface DevEngineDependency {
|
interface DevEngineDependency {
|
||||||
name: string;
|
name: string;
|
||||||
version: string;
|
version: string;
|
||||||
onFail?: 'ignore' | 'warn' | 'error';
|
onFail?: `ignore` | `warn` | `error`;
|
||||||
}
|
}
|
||||||
function warnOrThrow(errorMessage: string, onFail?: DevEngineDependency['onFail']) {
|
function warnOrThrow(errorMessage: string, onFail?: DevEngineDependency[`onFail`]) {
|
||||||
switch (onFail) {
|
switch (onFail) {
|
||||||
case `ignore`:
|
case `ignore`:
|
||||||
break;
|
break;
|
||||||
|
@ -151,7 +151,7 @@ interface FoundSpecResult {
|
||||||
type: `Found`;
|
type: `Found`;
|
||||||
target: string;
|
target: string;
|
||||||
getSpec: () => Descriptor;
|
getSpec: () => Descriptor;
|
||||||
range?: Descriptor & {onFail?: DevEngineDependency['onFail']};
|
range?: Descriptor & {onFail?: DevEngineDependency[`onFail`]};
|
||||||
envFilePath?: string;
|
envFilePath?: string;
|
||||||
}
|
}
|
||||||
export type LoadSpecResult =
|
export type LoadSpecResult =
|
||||||
|
|
|
@ -71,7 +71,7 @@ export interface DownloadSpec {
|
||||||
*/
|
*/
|
||||||
export interface Config {
|
export interface Config {
|
||||||
definitions: {
|
definitions: {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
[name in SupportedPackageManagers]?: {
|
[name in SupportedPackageManagers]?: {
|
||||||
/**
|
/**
|
||||||
* Defines the version that needs to be used when running commands within
|
* Defines the version that needs to be used when running commands within
|
||||||
|
|
|
@ -97,4 +97,23 @@ describe(`DisableCommand`, () => {
|
||||||
await expect(sortedEntries).resolves.toEqual([...binNames].sort());
|
await expect(sortedEntries).resolves.toEqual([...binNames].sort());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it(`shouldn't remove Yarn binaries if they are in a /switch/ folder`, async () => {
|
||||||
|
await xfs.mktempPromise(async cwd => {
|
||||||
|
await xfs.mkdirPromise(ppath.join(cwd, `switch/bin`), {recursive: true});
|
||||||
|
await xfs.writeFilePromise(ppath.join(cwd, `switch/bin/yarn`), `hello`);
|
||||||
|
|
||||||
|
await xfs.linkPromise(
|
||||||
|
ppath.join(cwd, `switch/bin/yarn`),
|
||||||
|
ppath.join(cwd, `yarn`),
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(runCli(cwd, [`disable`])).resolves.toMatchObject({
|
||||||
|
exitCode: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const file = await xfs.readFilePromise(ppath.join(cwd, `yarn`), `utf8`);
|
||||||
|
expect(file).toBe(`hello`);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {Filename, ppath, xfs, npath} from '@yarnpkg/fslib';
|
import {Filename, ppath, xfs, npath} from '@yarnpkg/fslib';
|
||||||
import {delimiter} from 'node:path';
|
import {delimiter} from 'node:path';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import {describe, beforeEach, it, expect} from 'vitest';
|
import {describe, beforeEach, it, expect, test} from 'vitest';
|
||||||
|
|
||||||
import {Engine} from '../sources/Engine';
|
import {Engine} from '../sources/Engine';
|
||||||
import {SupportedPackageManagers, SupportedPackageManagerSetWithoutNpm} from '../sources/types';
|
import {SupportedPackageManagers, SupportedPackageManagerSetWithoutNpm} from '../sources/types';
|
||||||
|
@ -87,4 +87,42 @@ describe(`EnableCommand`, () => {
|
||||||
await expect(sortedEntries).resolves.toEqual(expectedEntries.sort());
|
await expect(sortedEntries).resolves.toEqual(expectedEntries.sort());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.skipIf(process.platform === `win32`)(`should overwrite existing files`, async () => {
|
||||||
|
await xfs.mktempPromise(async cwd => {
|
||||||
|
await xfs.writeFilePromise(ppath.join(cwd, `yarn`), `hello`);
|
||||||
|
|
||||||
|
process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${process.env.PATH}`;
|
||||||
|
await expect(runCli(cwd, [`enable`])).resolves.toMatchObject({
|
||||||
|
stdout: ``,
|
||||||
|
stderr: ``,
|
||||||
|
exitCode: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const file = await xfs.readFilePromise(ppath.join(cwd, `yarn`), `utf8`);
|
||||||
|
expect(file).toBe(`hello`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.skipIf(process.platform === `win32`)(`shouldn't overwrite Yarn files if they are in a /switch/ folder`, async () => {
|
||||||
|
await xfs.mktempPromise(async cwd => {
|
||||||
|
await xfs.mkdirPromise(ppath.join(cwd, `switch/bin`), {recursive: true});
|
||||||
|
await xfs.writeFilePromise(ppath.join(cwd, `switch/bin/yarn`), `hello`);
|
||||||
|
|
||||||
|
await xfs.linkPromise(
|
||||||
|
ppath.join(cwd, `switch/bin/yarn`),
|
||||||
|
ppath.join(cwd, `yarn`),
|
||||||
|
);
|
||||||
|
|
||||||
|
process.env.PATH = `${npath.fromPortablePath(cwd)}${delimiter}${process.env.PATH}`;
|
||||||
|
await expect(runCli(cwd, [`enable`])).resolves.toMatchObject({
|
||||||
|
stdout: ``,
|
||||||
|
stderr: ``,
|
||||||
|
exitCode: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const file = await xfs.readFilePromise(ppath.join(cwd, `yarn`), `utf8`);
|
||||||
|
expect(file).toBe(`hello`);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -79,7 +79,7 @@ const registry = {
|
||||||
__proto__: null,
|
__proto__: null,
|
||||||
yarn: [`1.9998.9999`],
|
yarn: [`1.9998.9999`],
|
||||||
pnpm: [`1.9998.9999`],
|
pnpm: [`1.9998.9999`],
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
'@yarnpkg/cli-dist': [`5.9999.9999`],
|
'@yarnpkg/cli-dist': [`5.9999.9999`],
|
||||||
customPkgManager: [`1.0.0`],
|
customPkgManager: [`1.0.0`],
|
||||||
};
|
};
|
||||||
|
@ -131,7 +131,6 @@ const server = createServer((req, res) => {
|
||||||
const packageName = req.url.slice(1, slashPosition === -1 ? undefined : slashPosition);
|
const packageName = req.url.slice(1, slashPosition === -1 ? undefined : slashPosition);
|
||||||
if (packageName in registry) {
|
if (packageName in registry) {
|
||||||
if (req.url === `/${packageName}`) {
|
if (req.url === `/${packageName}`) {
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
res.end(JSON.stringify({"dist-tags": {
|
res.end(JSON.stringify({"dist-tags": {
|
||||||
latest: registry[packageName].at(-1),
|
latest: registry[packageName].at(-1),
|
||||||
}, versions: Object.fromEntries(registry[packageName].map(version =>
|
}, versions: Object.fromEntries(registry[packageName].map(version =>
|
||||||
|
|
|
@ -648,25 +648,7 @@ for (const name of SupportedPackageManagerSet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe(`when called on a project without any defined packageManager`, () => {
|
describe(`when called on a project without any defined packageManager`, () => {
|
||||||
it(`should append the field to package.json by default`, async () => {
|
it(`should not modify package.json by default`, async () => {
|
||||||
await xfs.mktempPromise(async cwd => {
|
|
||||||
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
|
|
||||||
// empty package.json file
|
|
||||||
});
|
|
||||||
|
|
||||||
await runCli(cwd, [`yarn`]);
|
|
||||||
|
|
||||||
const data = await xfs.readJsonPromise(ppath.join(cwd, `package.json` as Filename));
|
|
||||||
|
|
||||||
expect(data).toMatchObject({
|
|
||||||
packageManager: `yarn@${config.definitions.yarn.default}`,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should not modify package.json if disabled by env`, async () => {
|
|
||||||
process.env.COREPACK_ENABLE_AUTO_PIN = `0`;
|
|
||||||
|
|
||||||
await xfs.mktempPromise(async cwd => {
|
await xfs.mktempPromise(async cwd => {
|
||||||
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
|
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
|
||||||
// empty package.json file
|
// empty package.json file
|
||||||
|
@ -680,7 +662,25 @@ describe(`when called on a project without any defined packageManager`, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should not modify package.json if disabled by .corepack.env`, async t => {
|
it(`should modify package.json if enabled by env`, async () => {
|
||||||
|
process.env.COREPACK_ENABLE_AUTO_PIN = `1`;
|
||||||
|
|
||||||
|
await xfs.mktempPromise(async cwd => {
|
||||||
|
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
|
||||||
|
// empty package.json file
|
||||||
|
});
|
||||||
|
|
||||||
|
await runCli(cwd, [`yarn`]);
|
||||||
|
|
||||||
|
const data = await xfs.readJsonPromise(ppath.join(cwd, `package.json` as Filename));
|
||||||
|
|
||||||
|
expect(data).toMatchObject({
|
||||||
|
packageManager: expect.stringMatching(/^yarn@/),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should modify package.json if enabled by .corepack.env`, async t => {
|
||||||
// Skip that test on Node.js 18.x as it lacks support for .env files.
|
// Skip that test on Node.js 18.x as it lacks support for .env files.
|
||||||
if (process.version.startsWith(`v18.`)) t.skip();
|
if (process.version.startsWith(`v18.`)) t.skip();
|
||||||
|
|
||||||
|
@ -688,33 +688,34 @@ describe(`when called on a project without any defined packageManager`, () => {
|
||||||
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
|
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
|
||||||
// empty package.json file
|
// empty package.json file
|
||||||
});
|
});
|
||||||
await xfs.writeFilePromise(ppath.join(cwd, `.corepack.env` as Filename), `COREPACK_ENABLE_AUTO_PIN=0\n`);
|
await xfs.writeFilePromise(ppath.join(cwd, `.corepack.env` as Filename), `COREPACK_ENABLE_AUTO_PIN=1\n`);
|
||||||
|
|
||||||
await runCli(cwd, [`yarn`]);
|
|
||||||
|
|
||||||
const data = await xfs.readJsonPromise(ppath.join(cwd, `package.json` as Filename));
|
|
||||||
|
|
||||||
expect(Object.hasOwn(data, `packageManager`)).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it(`should modify package.json if .corepack.env if disabled`, async () => {
|
|
||||||
process.env.COREPACK_ENV_FILE = `0`;
|
|
||||||
|
|
||||||
await xfs.mktempPromise(async cwd => {
|
|
||||||
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
|
|
||||||
// empty package.json file
|
|
||||||
});
|
|
||||||
await xfs.writeFilePromise(ppath.join(cwd, `.corepack.env` as Filename), `COREPACK_ENABLE_AUTO_PIN=0\n`);
|
|
||||||
|
|
||||||
await runCli(cwd, [`yarn`]);
|
await runCli(cwd, [`yarn`]);
|
||||||
|
|
||||||
const data = await xfs.readJsonPromise(ppath.join(cwd, `package.json` as Filename));
|
const data = await xfs.readJsonPromise(ppath.join(cwd, `package.json` as Filename));
|
||||||
|
|
||||||
expect(data).toMatchObject({
|
expect(data).toMatchObject({
|
||||||
packageManager: `yarn@${config.definitions.yarn.default}`,
|
packageManager: expect.stringMatching(/^yarn@/),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it(`should not modify package.json if .corepack.env is disabled`, async () => {
|
||||||
|
process.env.COREPACK_ENV_FILE = `0`;
|
||||||
|
|
||||||
|
await xfs.mktempPromise(async cwd => {
|
||||||
|
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
|
||||||
|
// empty package.json file
|
||||||
|
});
|
||||||
|
await xfs.writeFilePromise(ppath.join(cwd, `.corepack.env` as Filename), `COREPACK_ENABLE_AUTO_PIN=1\n`);
|
||||||
|
|
||||||
|
await runCli(cwd, [`yarn`]);
|
||||||
|
|
||||||
|
const data = await xfs.readJsonPromise(ppath.join(cwd, `package.json` as Filename));
|
||||||
|
|
||||||
|
expect(Object.hasOwn(data, `packageManager`)).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should allow updating the pinned version using the "corepack install -g" command`, async () => {
|
it(`should allow updating the pinned version using the "corepack install -g" command`, async () => {
|
||||||
|
@ -1302,7 +1303,7 @@ it(`should download latest pnpm from custom registry`, async () => {
|
||||||
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
||||||
exitCode: 0,
|
exitCode: 0,
|
||||||
stdout: `pnpm: Hello from custom registry\n`,
|
stdout: `pnpm: Hello from custom registry\n`,
|
||||||
stderr: expect.stringContaining(`! The local project doesn't define a 'packageManager' field. Corepack will now add one referencing pnpm@1.9998.9999+sha1.`),
|
stderr: ``,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Should keep working with cache
|
// Should keep working with cache
|
||||||
|
@ -1335,7 +1336,7 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
|
||||||
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
||||||
exitCode: 0,
|
exitCode: 0,
|
||||||
stdout: `pnpm: Hello from custom registry\n`,
|
stdout: `pnpm: Hello from custom registry\n`,
|
||||||
stderr: expect.stringContaining(`The local project doesn't define a 'packageManager' field`),
|
stderr: ``,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1358,7 +1359,7 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
|
||||||
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
||||||
exitCode: 0,
|
exitCode: 0,
|
||||||
stdout: `pnpm: Hello from custom registry\n`,
|
stdout: `pnpm: Hello from custom registry\n`,
|
||||||
stderr: expect.stringContaining(`The local project doesn't define a 'packageManager' field`),
|
stderr: ``,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1385,7 +1386,7 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
|
||||||
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
||||||
exitCode: 0,
|
exitCode: 0,
|
||||||
stdout: `pnpm: Hello from custom registry\n`,
|
stdout: `pnpm: Hello from custom registry\n`,
|
||||||
stderr: expect.stringContaining(`The local project doesn't define a 'packageManager' field`),
|
stderr: ``,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1408,7 +1409,7 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
|
||||||
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
||||||
exitCode: 0,
|
exitCode: 0,
|
||||||
stdout: `pnpm: Hello from custom registry\n`,
|
stdout: `pnpm: Hello from custom registry\n`,
|
||||||
stderr: expect.stringContaining(`The local project doesn't define a 'packageManager' field`),
|
stderr: ``,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1434,7 +1435,7 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
|
||||||
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
||||||
exitCode: 0,
|
exitCode: 0,
|
||||||
stdout: `pnpm: Hello from custom registry\n`,
|
stdout: `pnpm: Hello from custom registry\n`,
|
||||||
stderr: expect.stringContaining(`The local project doesn't define a 'packageManager' field`),
|
stderr: ``,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1458,7 +1459,7 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
|
||||||
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
await expect(runCli(cwd, [`pnpm`, `--version`], true)).resolves.toMatchObject({
|
||||||
exitCode: 0,
|
exitCode: 0,
|
||||||
stdout: `pnpm: Hello from custom registry\n`,
|
stdout: `pnpm: Hello from custom registry\n`,
|
||||||
stderr: expect.stringContaining(`The local project doesn't define a 'packageManager' field`),
|
stderr: ``,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
BIN
tests/nocks.db
BIN
tests/nocks.db
Binary file not shown.
Loading…
Reference in New Issue