@yarnpkg/plugin-essentials 3.2.0-rc.9 → 4.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commands/add.d.ts +1 -0
- package/lib/commands/add.js +21 -11
- package/lib/commands/config/get.js +1 -1
- package/lib/commands/config/set.js +3 -3
- package/lib/commands/config/unset.js +3 -3
- package/lib/commands/dedupe.js +2 -2
- package/lib/commands/explain/peerRequirements.js +1 -1
- package/lib/commands/explain.js +1 -1
- package/lib/commands/info.js +1 -1
- package/lib/commands/install.d.ts +3 -1
- package/lib/commands/install.js +17 -5
- package/lib/commands/plugin/import/sources.js +1 -1
- package/lib/commands/plugin/import.d.ts +1 -0
- package/lib/commands/plugin/import.js +2 -2
- package/lib/commands/plugin/list.d.ts +2 -2
- package/lib/commands/plugin/list.js +6 -3
- package/lib/commands/remove.js +3 -3
- package/lib/commands/set/version/sources.js +4 -4
- package/lib/commands/set/version.d.ts +7 -2
- package/lib/commands/set/version.js +86 -43
- package/lib/commands/unlink.js +1 -1
- package/lib/commands/up.d.ts +1 -0
- package/lib/commands/up.js +9 -5
- package/lib/dedupeUtils.d.ts +7 -5
- package/lib/dedupeUtils.js +65 -34
- package/lib/index.d.ts +1 -0
- package/lib/index.js +43 -38
- package/lib/suggestUtils.d.ts +2 -1
- package/lib/suggestUtils.js +11 -13
- package/package.json +12 -14
package/lib/commands/add.d.ts
CHANGED
package/lib/commands/add.js
CHANGED
|
@@ -7,8 +7,8 @@ const core_2 = require("@yarnpkg/core");
|
|
|
7
7
|
const core_3 = require("@yarnpkg/core");
|
|
8
8
|
const clipanion_1 = require("clipanion");
|
|
9
9
|
const enquirer_1 = require("enquirer");
|
|
10
|
-
const t =
|
|
11
|
-
const suggestUtils =
|
|
10
|
+
const t = tslib_1.__importStar(require("typanion"));
|
|
11
|
+
const suggestUtils = tslib_1.__importStar(require("../suggestUtils"));
|
|
12
12
|
// eslint-disable-next-line arca/no-default-export
|
|
13
13
|
class AddCommand extends cli_1.BaseCommand {
|
|
14
14
|
constructor() {
|
|
@@ -16,6 +16,9 @@ class AddCommand extends cli_1.BaseCommand {
|
|
|
16
16
|
this.json = clipanion_1.Option.Boolean(`--json`, false, {
|
|
17
17
|
description: `Format the output as an NDJSON stream`,
|
|
18
18
|
});
|
|
19
|
+
this.fixed = clipanion_1.Option.Boolean(`-F,--fixed`, false, {
|
|
20
|
+
description: `Store dependency tags as-is instead of resolving them`,
|
|
21
|
+
});
|
|
19
22
|
this.exact = clipanion_1.Option.Boolean(`-E,--exact`, false, {
|
|
20
23
|
description: `Don't use any semver modifier on the resolved range`,
|
|
21
24
|
});
|
|
@@ -60,32 +63,39 @@ class AddCommand extends cli_1.BaseCommand {
|
|
|
60
63
|
await project.restoreInstallState({
|
|
61
64
|
restoreResolutions: false,
|
|
62
65
|
});
|
|
66
|
+
const fixed = this.fixed;
|
|
63
67
|
const interactive = (_a = this.interactive) !== null && _a !== void 0 ? _a : configuration.get(`preferInteractive`);
|
|
68
|
+
const reuse = interactive || configuration.get(`preferReuse`);
|
|
64
69
|
const modifier = suggestUtils.getModifier(this, project);
|
|
65
70
|
const strategies = [
|
|
66
|
-
|
|
67
|
-
suggestUtils.Strategy.REUSE
|
|
68
|
-
|
|
71
|
+
reuse ?
|
|
72
|
+
suggestUtils.Strategy.REUSE
|
|
73
|
+
: undefined,
|
|
69
74
|
suggestUtils.Strategy.PROJECT,
|
|
70
|
-
|
|
71
|
-
suggestUtils.Strategy.CACHE
|
|
72
|
-
|
|
75
|
+
this.cached ?
|
|
76
|
+
suggestUtils.Strategy.CACHE
|
|
77
|
+
: undefined,
|
|
73
78
|
suggestUtils.Strategy.LATEST,
|
|
74
|
-
];
|
|
79
|
+
].filter((strategy) => typeof strategy !== `undefined`);
|
|
75
80
|
const maxResults = interactive
|
|
76
81
|
? Infinity
|
|
77
82
|
: 1;
|
|
78
83
|
const allSuggestions = await Promise.all(this.packages.map(async (pseudoDescriptor) => {
|
|
79
84
|
const request = pseudoDescriptor.match(/^\.{0,2}\//)
|
|
80
85
|
? await suggestUtils.extractDescriptorFromPath(pseudoDescriptor, { cwd: this.context.cwd, workspace })
|
|
81
|
-
: core_3.structUtils.
|
|
86
|
+
: core_3.structUtils.tryParseDescriptor(pseudoDescriptor);
|
|
87
|
+
const unsupportedPrefix = pseudoDescriptor.match(/^(https?:|git@github)/);
|
|
88
|
+
if (unsupportedPrefix)
|
|
89
|
+
throw new clipanion_1.UsageError(`It seems you are trying to add a package using a ${core_1.formatUtils.pretty(configuration, `${unsupportedPrefix[0]}...`, core_1.FormatType.RANGE)} url; we now require package names to be explicitly specified.\nTry running the command again with the package name prefixed: ${core_1.formatUtils.pretty(configuration, `yarn add`, core_1.FormatType.CODE)} ${core_1.formatUtils.pretty(configuration, core_3.structUtils.makeDescriptor(core_3.structUtils.makeIdent(null, `my-package`), `${unsupportedPrefix[0]}...`), core_1.FormatType.DESCRIPTOR)}`);
|
|
90
|
+
if (!request)
|
|
91
|
+
throw new clipanion_1.UsageError(`The ${core_1.formatUtils.pretty(configuration, pseudoDescriptor, core_1.FormatType.CODE)} string didn't match the required format (package-name@range). Did you perhaps forget to explicitly reference the package name?`);
|
|
82
92
|
const target = suggestTarget(workspace, request, {
|
|
83
93
|
dev: this.dev,
|
|
84
94
|
peer: this.peer,
|
|
85
95
|
preferDev: this.preferDev,
|
|
86
96
|
optional: this.optional,
|
|
87
97
|
});
|
|
88
|
-
const suggestions = await suggestUtils.getSuggestedDescriptors(request, { project, workspace, cache, target, modifier, strategies, maxResults });
|
|
98
|
+
const suggestions = await suggestUtils.getSuggestedDescriptors(request, { project, workspace, cache, fixed, target, modifier, strategies, maxResults });
|
|
89
99
|
return [request, suggestions, target];
|
|
90
100
|
}));
|
|
91
101
|
const checkReport = await core_1.LightReport.start({
|
|
@@ -4,7 +4,7 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const cli_1 = require("@yarnpkg/cli");
|
|
5
5
|
const core_1 = require("@yarnpkg/core");
|
|
6
6
|
const clipanion_1 = require("clipanion");
|
|
7
|
-
const get_1 =
|
|
7
|
+
const get_1 = tslib_1.__importDefault(require("lodash/get"));
|
|
8
8
|
const util_1 = require("util");
|
|
9
9
|
// eslint-disable-next-line arca/no-default-export
|
|
10
10
|
class ConfigGetCommand extends cli_1.BaseCommand {
|
|
@@ -4,9 +4,9 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const cli_1 = require("@yarnpkg/cli");
|
|
5
5
|
const core_1 = require("@yarnpkg/core");
|
|
6
6
|
const clipanion_1 = require("clipanion");
|
|
7
|
-
const cloneDeep_1 =
|
|
8
|
-
const get_1 =
|
|
9
|
-
const set_1 =
|
|
7
|
+
const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
|
|
8
|
+
const get_1 = tslib_1.__importDefault(require("lodash/get"));
|
|
9
|
+
const set_1 = tslib_1.__importDefault(require("lodash/set"));
|
|
10
10
|
const util_1 = require("util");
|
|
11
11
|
// eslint-disable-next-line arca/no-default-export
|
|
12
12
|
class ConfigSetCommand extends cli_1.BaseCommand {
|
|
@@ -4,9 +4,9 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const cli_1 = require("@yarnpkg/cli");
|
|
5
5
|
const core_1 = require("@yarnpkg/core");
|
|
6
6
|
const clipanion_1 = require("clipanion");
|
|
7
|
-
const cloneDeep_1 =
|
|
8
|
-
const has_1 =
|
|
9
|
-
const unset_1 =
|
|
7
|
+
const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
|
|
8
|
+
const has_1 = tslib_1.__importDefault(require("lodash/has"));
|
|
9
|
+
const unset_1 = tslib_1.__importDefault(require("lodash/unset"));
|
|
10
10
|
// eslint-disable-next-line arca/no-default-export
|
|
11
11
|
class ConfigUnsetCommand extends cli_1.BaseCommand {
|
|
12
12
|
constructor() {
|
package/lib/commands/dedupe.js
CHANGED
|
@@ -17,8 +17,8 @@ const tslib_1 = require("tslib");
|
|
|
17
17
|
const cli_1 = require("@yarnpkg/cli");
|
|
18
18
|
const core_1 = require("@yarnpkg/core");
|
|
19
19
|
const clipanion_1 = require("clipanion");
|
|
20
|
-
const t =
|
|
21
|
-
const dedupeUtils =
|
|
20
|
+
const t = tslib_1.__importStar(require("typanion"));
|
|
21
|
+
const dedupeUtils = tslib_1.__importStar(require("../dedupeUtils"));
|
|
22
22
|
// eslint-disable-next-line arca/no-default-export
|
|
23
23
|
class DedupeCommand extends cli_1.BaseCommand {
|
|
24
24
|
constructor() {
|
|
@@ -5,7 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const cli_1 = require("@yarnpkg/cli");
|
|
6
6
|
const core_1 = require("@yarnpkg/core");
|
|
7
7
|
const clipanion_1 = require("clipanion");
|
|
8
|
-
const t =
|
|
8
|
+
const t = tslib_1.__importStar(require("typanion"));
|
|
9
9
|
// eslint-disable-next-line arca/no-default-export
|
|
10
10
|
class ExplainPeerRequirementsCommand extends cli_1.BaseCommand {
|
|
11
11
|
constructor() {
|
package/lib/commands/explain.js
CHANGED
|
@@ -5,7 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const cli_1 = require("@yarnpkg/cli");
|
|
6
6
|
const core_1 = require("@yarnpkg/core");
|
|
7
7
|
const clipanion_1 = require("clipanion");
|
|
8
|
-
const t =
|
|
8
|
+
const t = tslib_1.__importStar(require("typanion"));
|
|
9
9
|
const version_1 = require("./set/version");
|
|
10
10
|
function getCodeName(code) {
|
|
11
11
|
return core_1.MessageName[(0, core_1.parseMessageName)(code)];
|
package/lib/commands/info.js
CHANGED
|
@@ -5,7 +5,7 @@ const cli_1 = require("@yarnpkg/cli");
|
|
|
5
5
|
const core_1 = require("@yarnpkg/core");
|
|
6
6
|
const fslib_1 = require("@yarnpkg/fslib");
|
|
7
7
|
const clipanion_1 = require("clipanion");
|
|
8
|
-
const micromatch_1 =
|
|
8
|
+
const micromatch_1 = tslib_1.__importDefault(require("micromatch"));
|
|
9
9
|
// eslint-disable-next-line arca/no-default-export
|
|
10
10
|
class InfoCommand extends cli_1.BaseCommand {
|
|
11
11
|
constructor() {
|
|
@@ -7,7 +7,9 @@ export default class YarnCommand extends BaseCommand {
|
|
|
7
7
|
json: boolean;
|
|
8
8
|
immutable: boolean | undefined;
|
|
9
9
|
immutableCache: boolean | undefined;
|
|
10
|
-
|
|
10
|
+
refreshLockfile: boolean | undefined;
|
|
11
|
+
checkCache: boolean | undefined;
|
|
12
|
+
checkResolutions: boolean | undefined;
|
|
11
13
|
inlineBuilds: boolean | undefined;
|
|
12
14
|
mode: InstallMode | undefined;
|
|
13
15
|
cacheFolder: string | undefined;
|
package/lib/commands/install.js
CHANGED
|
@@ -5,9 +5,9 @@ const cli_1 = require("@yarnpkg/cli");
|
|
|
5
5
|
const core_1 = require("@yarnpkg/core");
|
|
6
6
|
const fslib_1 = require("@yarnpkg/fslib");
|
|
7
7
|
const parsers_1 = require("@yarnpkg/parsers");
|
|
8
|
-
const ci_info_1 =
|
|
8
|
+
const ci_info_1 = tslib_1.__importDefault(require("ci-info"));
|
|
9
9
|
const clipanion_1 = require("clipanion");
|
|
10
|
-
const t =
|
|
10
|
+
const t = tslib_1.__importStar(require("typanion"));
|
|
11
11
|
// eslint-disable-next-line arca/no-default-export
|
|
12
12
|
class YarnCommand extends cli_1.BaseCommand {
|
|
13
13
|
constructor() {
|
|
@@ -21,9 +21,15 @@ class YarnCommand extends cli_1.BaseCommand {
|
|
|
21
21
|
this.immutableCache = clipanion_1.Option.Boolean(`--immutable-cache`, {
|
|
22
22
|
description: `Abort with an error exit code if the cache folder was to be modified`,
|
|
23
23
|
});
|
|
24
|
-
this.
|
|
24
|
+
this.refreshLockfile = clipanion_1.Option.Boolean(`--refresh-lockfile`, {
|
|
25
|
+
description: `Refresh the package metadata stored in the lockfile`,
|
|
26
|
+
});
|
|
27
|
+
this.checkCache = clipanion_1.Option.Boolean(`--check-cache`, {
|
|
25
28
|
description: `Always refetch the packages and ensure that their checksums are consistent`,
|
|
26
29
|
});
|
|
30
|
+
this.checkResolutions = clipanion_1.Option.Boolean(`--check-resolutions`, {
|
|
31
|
+
description: `Validates that the package resolutions are coherent`,
|
|
32
|
+
});
|
|
27
33
|
this.inlineBuilds = clipanion_1.Option.Boolean(`--inline-builds`, {
|
|
28
34
|
description: `Verbosely print the output of the build steps of dependencies`,
|
|
29
35
|
});
|
|
@@ -43,7 +49,7 @@ class YarnCommand extends cli_1.BaseCommand {
|
|
|
43
49
|
this.networkTimeout = clipanion_1.Option.String(`--network-timeout`, { hidden: true });
|
|
44
50
|
}
|
|
45
51
|
async execute() {
|
|
46
|
-
var _a;
|
|
52
|
+
var _a, _b, _c;
|
|
47
53
|
const configuration = await core_1.Configuration.find(this.context.cwd, this.context.plugins);
|
|
48
54
|
if (typeof this.inlineBuilds !== `undefined`)
|
|
49
55
|
configuration.useWithSource(`<cli>`, { enableInlineBuilds: this.inlineBuilds }, configuration.startingCwd, { overwrite: true });
|
|
@@ -228,6 +234,10 @@ class YarnCommand extends cli_1.BaseCommand {
|
|
|
228
234
|
await project.restoreInstallState({
|
|
229
235
|
restoreResolutions: false,
|
|
230
236
|
});
|
|
237
|
+
const enableHardenedMode = configuration.get(`enableHardenedMode`);
|
|
238
|
+
if ((_b = this.refreshLockfile) !== null && _b !== void 0 ? _b : enableHardenedMode)
|
|
239
|
+
project.lockfileNeedsRefresh = true;
|
|
240
|
+
const checkResolutions = (_c = this.checkResolutions) !== null && _c !== void 0 ? _c : enableHardenedMode;
|
|
231
241
|
// Important: Because other commands also need to run installs, if you
|
|
232
242
|
// get in a situation where you need to change this file in order to
|
|
233
243
|
// customize the install it's very likely you're doing something wrong.
|
|
@@ -241,7 +251,7 @@ class YarnCommand extends cli_1.BaseCommand {
|
|
|
241
251
|
stdout: this.context.stdout,
|
|
242
252
|
includeLogs: true,
|
|
243
253
|
}, async (report) => {
|
|
244
|
-
await project.install({ cache, report, immutable, mode: this.mode });
|
|
254
|
+
await project.install({ cache, report, immutable, checkResolutions, mode: this.mode });
|
|
245
255
|
});
|
|
246
256
|
return report.exitCode();
|
|
247
257
|
}
|
|
@@ -270,6 +280,8 @@ YarnCommand.usage = clipanion_1.Command.Usage({
|
|
|
270
280
|
|
|
271
281
|
If the \`--immutable-cache\` option is set, Yarn will abort with an error exit code if the cache folder was to be modified (either because files would be added, or because they'd be removed).
|
|
272
282
|
|
|
283
|
+
If the \`--refresh-lockfile\` option is set, Yarn will keep the same resolution for the packages currently in the lockfile but will refresh their metadata. If used together with \`--immutable\`, it can validate that the lockfile information are consistent. This flag is enabled by default when Yarn detects it runs within a pull request context.
|
|
284
|
+
|
|
273
285
|
If the \`--check-cache\` option is set, Yarn will always refetch the packages and will ensure that their checksum matches what's 1/ described in the lockfile 2/ inside the existing cache files (if present). This is recommended as part of your CI workflow if you're both following the Zero-Installs model and accepting PRs from third-parties, as they'd otherwise have the ability to alter the checked-in packages before submitting them.
|
|
274
286
|
|
|
275
287
|
If the \`--inline-builds\` option is set, Yarn will verbosely print the output of the build steps of your dependencies (instead of writing them into individual files). This is likely useful mostly for debug purposes only when using Docker-like environments.
|
|
@@ -46,7 +46,7 @@ class PluginDlSourcesCommand extends cli_1.BaseCommand {
|
|
|
46
46
|
const { project } = await core_2.Project.find(configuration, this.context.cwd);
|
|
47
47
|
const ident = core_1.structUtils.parseIdent(this.name.replace(/^((@yarnpkg\/)?plugin-)?/, `@yarnpkg/plugin-`));
|
|
48
48
|
const identStr = core_1.structUtils.stringifyIdent(ident);
|
|
49
|
-
const data = await (0, list_1.getAvailablePlugins)(configuration);
|
|
49
|
+
const data = await (0, list_1.getAvailablePlugins)(configuration, core_1.YarnVersion);
|
|
50
50
|
if (!Object.prototype.hasOwnProperty.call(data, identStr))
|
|
51
51
|
throw new core_2.ReportError(core_2.MessageName.PLUGIN_NAME_NOT_FOUND, `Couldn't find a plugin named "${identStr}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be built and imported from sources.`);
|
|
52
52
|
const pluginSpec = identStr;
|
|
@@ -7,7 +7,7 @@ const core_1 = require("@yarnpkg/core");
|
|
|
7
7
|
const core_2 = require("@yarnpkg/core");
|
|
8
8
|
const fslib_1 = require("@yarnpkg/fslib");
|
|
9
9
|
const clipanion_1 = require("clipanion");
|
|
10
|
-
const semver_1 =
|
|
10
|
+
const semver_1 = tslib_1.__importDefault(require("semver"));
|
|
11
11
|
const url_1 = require("url");
|
|
12
12
|
const vm_1 = require("vm");
|
|
13
13
|
const list_1 = require("./list");
|
|
@@ -49,7 +49,7 @@ class PluginDlCommand extends cli_1.BaseCommand {
|
|
|
49
49
|
if (locator.reference !== `unknown` && !semver_1.default.valid(locator.reference))
|
|
50
50
|
throw new core_1.ReportError(core_1.MessageName.UNNAMED, `Official plugins only accept strict version references. Use an explicit URL if you wish to download them from another location.`);
|
|
51
51
|
const identStr = core_2.structUtils.stringifyIdent(locator);
|
|
52
|
-
const data = await (0, list_1.getAvailablePlugins)(configuration);
|
|
52
|
+
const data = await (0, list_1.getAvailablePlugins)(configuration, core_2.YarnVersion);
|
|
53
53
|
if (!Object.prototype.hasOwnProperty.call(data, identStr))
|
|
54
54
|
throw new core_1.ReportError(core_1.MessageName.PLUGIN_NAME_NOT_FOUND, `Couldn't find a plugin named "${identStr}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be referenced by their name; any other plugin will have to be referenced through its public url (for example https://github.com/yarnpkg/berry/raw/master/packages/plugin-typescript/bin/%40yarnpkg/plugin-typescript.js).`);
|
|
55
55
|
pluginSpec = identStr;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BaseCommand } from '@yarnpkg/cli';
|
|
2
2
|
import { Configuration } from '@yarnpkg/core';
|
|
3
3
|
import { Usage } from 'clipanion';
|
|
4
|
-
export declare function getAvailablePlugins(configuration: Configuration): Promise<{
|
|
5
|
-
[
|
|
4
|
+
export declare function getAvailablePlugins(configuration: Configuration, version: string | null): Promise<{
|
|
5
|
+
[k: string]: any;
|
|
6
6
|
}>;
|
|
7
7
|
export default class PluginDlCommand extends BaseCommand {
|
|
8
8
|
static paths: string[][];
|
|
@@ -6,10 +6,13 @@ const core_1 = require("@yarnpkg/core");
|
|
|
6
6
|
const parsers_1 = require("@yarnpkg/parsers");
|
|
7
7
|
const clipanion_1 = require("clipanion");
|
|
8
8
|
const REMOTE_REGISTRY = `https://raw.githubusercontent.com/yarnpkg/berry/master/plugins.yml`;
|
|
9
|
-
async function getAvailablePlugins(configuration) {
|
|
9
|
+
async function getAvailablePlugins(configuration, version) {
|
|
10
10
|
const raw = await core_1.httpUtils.get(REMOTE_REGISTRY, { configuration });
|
|
11
11
|
const data = (0, parsers_1.parseSyml)(raw.toString());
|
|
12
|
-
return data
|
|
12
|
+
return Object.fromEntries(Object.entries(data).filter(([pluginName, pluginData]) => {
|
|
13
|
+
var _a;
|
|
14
|
+
return !version || core_1.semverUtils.satisfiesWithPrereleases(version, (_a = pluginData.range) !== null && _a !== void 0 ? _a : `<4.0.0`);
|
|
15
|
+
}));
|
|
13
16
|
}
|
|
14
17
|
exports.getAvailablePlugins = getAvailablePlugins;
|
|
15
18
|
// eslint-disable-next-line arca/no-default-export
|
|
@@ -27,7 +30,7 @@ class PluginDlCommand extends cli_1.BaseCommand {
|
|
|
27
30
|
json: this.json,
|
|
28
31
|
stdout: this.context.stdout,
|
|
29
32
|
}, async (report) => {
|
|
30
|
-
const data = await getAvailablePlugins(configuration);
|
|
33
|
+
const data = await getAvailablePlugins(configuration, core_1.YarnVersion);
|
|
31
34
|
for (const [name, { experimental, ...rest }] of Object.entries(data)) {
|
|
32
35
|
let label = name;
|
|
33
36
|
if (experimental)
|
package/lib/commands/remove.js
CHANGED
|
@@ -6,9 +6,9 @@ const core_1 = require("@yarnpkg/core");
|
|
|
6
6
|
const core_2 = require("@yarnpkg/core");
|
|
7
7
|
const core_3 = require("@yarnpkg/core");
|
|
8
8
|
const clipanion_1 = require("clipanion");
|
|
9
|
-
const micromatch_1 =
|
|
10
|
-
const t =
|
|
11
|
-
const suggestUtils =
|
|
9
|
+
const micromatch_1 = tslib_1.__importDefault(require("micromatch"));
|
|
10
|
+
const t = tslib_1.__importStar(require("typanion"));
|
|
11
|
+
const suggestUtils = tslib_1.__importStar(require("../suggestUtils"));
|
|
12
12
|
// eslint-disable-next-line arca/no-default-export
|
|
13
13
|
class RemoveCommand extends cli_1.BaseCommand {
|
|
14
14
|
constructor() {
|
|
@@ -76,11 +76,11 @@ class SetVersionSourcesCommand extends cli_1.BaseCommand {
|
|
|
76
76
|
report.reportSeparator();
|
|
77
77
|
const bundlePath = fslib_1.ppath.resolve(target, `packages/yarnpkg-cli/bundles/yarn.js`);
|
|
78
78
|
const bundleBuffer = await fslib_1.xfs.readFilePromise(bundlePath);
|
|
79
|
-
await (0, version_1.setVersion)(configuration,
|
|
79
|
+
const { bundleVersion } = await (0, version_1.setVersion)(configuration, null, async () => bundleBuffer, {
|
|
80
80
|
report,
|
|
81
81
|
});
|
|
82
82
|
if (!this.skipPlugins) {
|
|
83
|
-
await updatePlugins(this, { project, report, target });
|
|
83
|
+
await updatePlugins(this, bundleVersion, { project, report, target });
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
86
|
return report.exitCode();
|
|
@@ -155,8 +155,8 @@ async function prepareRepo(spec, { configuration, report, target }) {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
exports.prepareRepo = prepareRepo;
|
|
158
|
-
async function updatePlugins(context, { project, report, target }) {
|
|
159
|
-
const data = await (0, list_1.getAvailablePlugins)(project.configuration);
|
|
158
|
+
async function updatePlugins(context, version, { project, report, target }) {
|
|
159
|
+
const data = await (0, list_1.getAvailablePlugins)(project.configuration, version);
|
|
160
160
|
const contribPlugins = new Set(Object.keys(data));
|
|
161
161
|
for (const name of project.configuration.plugins.keys()) {
|
|
162
162
|
if (!contribPlugins.has(name))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
import { BaseCommand } from '@yarnpkg/cli';
|
|
3
4
|
import { Configuration, Report } from '@yarnpkg/core';
|
|
4
5
|
import { Usage } from 'clipanion';
|
|
@@ -9,12 +10,16 @@ export declare type Tags = {
|
|
|
9
10
|
export default class SetVersionCommand extends BaseCommand {
|
|
10
11
|
static paths: string[][];
|
|
11
12
|
static usage: Usage;
|
|
13
|
+
useYarnPath: boolean | undefined;
|
|
12
14
|
onlyIfNeeded: boolean;
|
|
13
15
|
version: string;
|
|
14
16
|
execute(): Promise<1 | 0>;
|
|
15
17
|
}
|
|
16
18
|
export declare function resolveRange(configuration: Configuration, request: string): Promise<string>;
|
|
17
19
|
export declare function resolveTag(configuration: Configuration, request: `stable` | `canary`): Promise<string>;
|
|
18
|
-
export declare function setVersion(configuration: Configuration, bundleVersion: string | null,
|
|
20
|
+
export declare function setVersion(configuration: Configuration, bundleVersion: string | null, fetchBuffer: () => Promise<Buffer>, { report, useYarnPath }: {
|
|
19
21
|
report: Report;
|
|
20
|
-
|
|
22
|
+
useYarnPath?: boolean;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
bundleVersion: string;
|
|
25
|
+
}>;
|
|
@@ -7,11 +7,14 @@ const core_1 = require("@yarnpkg/core");
|
|
|
7
7
|
const core_2 = require("@yarnpkg/core");
|
|
8
8
|
const fslib_1 = require("@yarnpkg/fslib");
|
|
9
9
|
const clipanion_1 = require("clipanion");
|
|
10
|
-
const semver_1 =
|
|
10
|
+
const semver_1 = tslib_1.__importDefault(require("semver"));
|
|
11
11
|
// eslint-disable-next-line arca/no-default-export
|
|
12
12
|
class SetVersionCommand extends cli_1.BaseCommand {
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
15
|
+
this.useYarnPath = clipanion_1.Option.Boolean(`--yarn-path`, {
|
|
16
|
+
description: `Set the yarnPath setting even if the version can be accessed by Corepack`,
|
|
17
|
+
});
|
|
15
18
|
this.onlyIfNeeded = clipanion_1.Option.Boolean(`--only-if-needed`, false, {
|
|
16
19
|
description: `Only lock the Yarn version if it isn't already locked`,
|
|
17
20
|
});
|
|
@@ -26,23 +29,28 @@ class SetVersionCommand extends cli_1.BaseCommand {
|
|
|
26
29
|
throw new clipanion_1.UsageError(`The --install flag can only be used without explicit version specifier from the Yarn CLI`);
|
|
27
30
|
return `file://${process.argv[1]}`;
|
|
28
31
|
};
|
|
29
|
-
let
|
|
32
|
+
let bundleRef;
|
|
33
|
+
const getRef = (url, version) => {
|
|
34
|
+
return { version, url: url.replace(/\{\}/g, version) };
|
|
35
|
+
};
|
|
30
36
|
if (this.version === `self`)
|
|
31
|
-
|
|
37
|
+
bundleRef = { url: getBundlePath(), version: core_1.YarnVersion !== null && core_1.YarnVersion !== void 0 ? core_1.YarnVersion : `self` };
|
|
32
38
|
else if (this.version === `latest` || this.version === `berry` || this.version === `stable`)
|
|
33
|
-
|
|
39
|
+
bundleRef = getRef(`https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js`, await resolveTag(configuration, `stable`));
|
|
34
40
|
else if (this.version === `canary`)
|
|
35
|
-
|
|
41
|
+
bundleRef = getRef(`https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js`, await resolveTag(configuration, `canary`));
|
|
36
42
|
else if (this.version === `classic`)
|
|
37
|
-
|
|
43
|
+
bundleRef = { url: `https://nightly.yarnpkg.com/latest.js`, version: `classic` };
|
|
44
|
+
else if (this.version.match(/^https?:/))
|
|
45
|
+
bundleRef = { url: this.version, version: `remote` };
|
|
38
46
|
else if (this.version.match(/^\.{0,2}[\\/]/) || fslib_1.npath.isAbsolute(this.version))
|
|
39
|
-
|
|
47
|
+
bundleRef = { url: `file://${fslib_1.ppath.resolve(fslib_1.npath.toPortablePath(this.version))}`, version: `file` };
|
|
40
48
|
else if (core_2.semverUtils.satisfiesWithPrereleases(this.version, `>=2.0.0`))
|
|
41
|
-
|
|
49
|
+
bundleRef = getRef(`https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js`, this.version);
|
|
42
50
|
else if (core_2.semverUtils.satisfiesWithPrereleases(this.version, `^0.x || ^1.x`))
|
|
43
|
-
|
|
51
|
+
bundleRef = getRef(`https://github.com/yarnpkg/yarn/releases/download/v{}/yarn-{}.js`, this.version);
|
|
44
52
|
else if (core_2.semverUtils.validRange(this.version))
|
|
45
|
-
|
|
53
|
+
bundleRef = getRef(`https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js`, await resolveRange(configuration, this.version));
|
|
46
54
|
else
|
|
47
55
|
throw new clipanion_1.UsageError(`Invalid version descriptor "${this.version}"`);
|
|
48
56
|
const report = await core_1.StreamReport.start({
|
|
@@ -50,17 +58,18 @@ class SetVersionCommand extends cli_1.BaseCommand {
|
|
|
50
58
|
stdout: this.context.stdout,
|
|
51
59
|
includeLogs: !this.context.quiet,
|
|
52
60
|
}, async (report) => {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
const fetchBuffer = async () => {
|
|
62
|
+
const filePrefix = `file://`;
|
|
63
|
+
if (bundleRef.url.startsWith(filePrefix)) {
|
|
64
|
+
report.reportInfo(core_1.MessageName.UNNAMED, `Retrieving ${core_2.formatUtils.pretty(configuration, bundleRef.url, core_1.FormatType.PATH)}`);
|
|
65
|
+
return await fslib_1.xfs.readFilePromise(bundleRef.url.slice(filePrefix.length));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
report.reportInfo(core_1.MessageName.UNNAMED, `Downloading ${core_2.formatUtils.pretty(configuration, bundleRef.url, core_1.FormatType.URL)}`);
|
|
69
|
+
return await core_2.httpUtils.get(bundleRef.url, { configuration });
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
await setVersion(configuration, bundleRef.version, fetchBuffer, { report, useYarnPath: this.useYarnPath });
|
|
64
73
|
});
|
|
65
74
|
return report.exitCode();
|
|
66
75
|
}
|
|
@@ -72,7 +81,9 @@ SetVersionCommand.paths = [
|
|
|
72
81
|
SetVersionCommand.usage = clipanion_1.Command.Usage({
|
|
73
82
|
description: `lock the Yarn version used by the project`,
|
|
74
83
|
details: `
|
|
75
|
-
This command will
|
|
84
|
+
This command will set a specific release of Yarn to be used by Corepack: https://nodejs.org/api/corepack.html.
|
|
85
|
+
|
|
86
|
+
By default it only will set the \`packageManager\` field at the root of your project, but if the referenced release cannot be represented this way, if you already have \`yarnPath\` configured, or if you set the \`--yarn-path\` command line flag, then the release will also be downloaded from the Yarn GitHub repository, stored inside your project, and referenced via the \`yarnPath\` settings from your project \`.yarnrc.yml\` file.
|
|
76
87
|
|
|
77
88
|
A very good use case for this command is to enforce the version of Yarn used by the any single member of your team inside a same project - by doing this you ensure that you have control on Yarn upgrades and downgrades (including on your deployment servers), and get rid of most of the headaches related to someone using a slightly different version and getting a different behavior than you.
|
|
78
89
|
|
|
@@ -112,6 +123,9 @@ SetVersionCommand.usage = clipanion_1.Command.Usage({
|
|
|
112
123
|
], [
|
|
113
124
|
`Use a release from the local filesystem`,
|
|
114
125
|
`$0 set version ./yarn.cjs`,
|
|
126
|
+
], [
|
|
127
|
+
`Use a release from a URL`,
|
|
128
|
+
`$0 set version https://repo.yarnpkg.com/3.1.0/packages/yarnpkg-cli/bin/yarn.js`,
|
|
115
129
|
], [
|
|
116
130
|
`Download the version used to invoke the command`,
|
|
117
131
|
`$0 set version self`,
|
|
@@ -133,9 +147,16 @@ async function resolveTag(configuration, request) {
|
|
|
133
147
|
return data.latest[request];
|
|
134
148
|
}
|
|
135
149
|
exports.resolveTag = resolveTag;
|
|
136
|
-
async function setVersion(configuration, bundleVersion,
|
|
150
|
+
async function setVersion(configuration, bundleVersion, fetchBuffer, { report, useYarnPath }) {
|
|
137
151
|
var _a;
|
|
152
|
+
let bundleBuffer;
|
|
153
|
+
const ensureBuffer = async () => {
|
|
154
|
+
if (typeof bundleBuffer === `undefined`)
|
|
155
|
+
bundleBuffer = await fetchBuffer();
|
|
156
|
+
return bundleBuffer;
|
|
157
|
+
};
|
|
138
158
|
if (bundleVersion === null) {
|
|
159
|
+
const bundleBuffer = await ensureBuffer();
|
|
139
160
|
await fslib_1.xfs.mktempPromise(async (tmpDir) => {
|
|
140
161
|
const temporaryPath = fslib_1.ppath.join(tmpDir, `yarn.cjs`);
|
|
141
162
|
await fslib_1.xfs.writeFilePromise(temporaryPath, bundleBuffer);
|
|
@@ -153,29 +174,51 @@ async function setVersion(configuration, bundleVersion, bundleBuffer, { report }
|
|
|
153
174
|
const releaseFolder = fslib_1.ppath.resolve(projectCwd, `.yarn/releases`);
|
|
154
175
|
const absolutePath = fslib_1.ppath.resolve(releaseFolder, `yarn-${bundleVersion}.cjs`);
|
|
155
176
|
const displayPath = fslib_1.ppath.relative(configuration.startingCwd, absolutePath);
|
|
156
|
-
const
|
|
177
|
+
const isTaggedYarnVersion = core_2.miscUtils.isTaggedYarnVersion(bundleVersion);
|
|
157
178
|
const yarnPath = configuration.get(`yarnPath`);
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
179
|
+
const absolutelyMustUseYarnPath = !isTaggedYarnVersion;
|
|
180
|
+
let probablyShouldUseYarnPath = absolutelyMustUseYarnPath || !!yarnPath || !!useYarnPath;
|
|
181
|
+
if (useYarnPath === false) {
|
|
182
|
+
if (absolutelyMustUseYarnPath)
|
|
183
|
+
throw new core_1.ReportError(core_1.MessageName.UNNAMED, `You explicitly opted out of yarnPath usage in your command line, but the version you specified cannot be represented by Corepack`);
|
|
184
|
+
probablyShouldUseYarnPath = false;
|
|
185
|
+
}
|
|
186
|
+
else if (!probablyShouldUseYarnPath && !process.env.COREPACK_ROOT) {
|
|
187
|
+
report.reportWarning(core_1.MessageName.UNNAMED, `You don't seem to have ${core_2.formatUtils.applyHyperlink(configuration, `Corepack`, `https://nodejs.org/api/corepack.html`)} enabled; we'll have to rely on ${core_2.formatUtils.applyHyperlink(configuration, `yarnPath`, `https://yarnpkg.com/configuration/yarnrc#yarnPath`)} instead`);
|
|
188
|
+
probablyShouldUseYarnPath = true;
|
|
189
|
+
}
|
|
190
|
+
if (probablyShouldUseYarnPath) {
|
|
191
|
+
const bundleBuffer = await ensureBuffer();
|
|
192
|
+
report.reportInfo(core_1.MessageName.UNNAMED, `Saving the new release in ${core_2.formatUtils.pretty(configuration, displayPath, `magenta`)}`);
|
|
193
|
+
await fslib_1.xfs.removePromise(fslib_1.ppath.dirname(absolutePath));
|
|
194
|
+
await fslib_1.xfs.mkdirPromise(fslib_1.ppath.dirname(absolutePath), { recursive: true });
|
|
195
|
+
await fslib_1.xfs.writeFilePromise(absolutePath, bundleBuffer, { mode: 0o755 });
|
|
196
|
+
if (!yarnPath || fslib_1.ppath.contains(releaseFolder, yarnPath)) {
|
|
197
|
+
await core_1.Configuration.updateConfiguration(projectCwd, {
|
|
198
|
+
yarnPath: fslib_1.ppath.relative(projectCwd, absolutePath),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
await fslib_1.xfs.removePromise(fslib_1.ppath.dirname(absolutePath));
|
|
164
204
|
await core_1.Configuration.updateConfiguration(projectCwd, {
|
|
165
|
-
yarnPath:
|
|
166
|
-
});
|
|
167
|
-
const manifest = (await core_1.Manifest.tryFind(projectCwd)) || new core_1.Manifest();
|
|
168
|
-
manifest.packageManager = `yarn@${bundleVersion && core_2.miscUtils.isTaggedYarnVersion(bundleVersion)
|
|
169
|
-
? bundleVersion
|
|
170
|
-
// If the version isn't tagged, we use the latest stable version as the wrapper
|
|
171
|
-
: await resolveTag(configuration, `stable`)}`;
|
|
172
|
-
const data = {};
|
|
173
|
-
manifest.exportTo(data);
|
|
174
|
-
const path = fslib_1.ppath.join(projectCwd, core_1.Manifest.fileName);
|
|
175
|
-
const content = `${JSON.stringify(data, null, manifest.indent)}\n`;
|
|
176
|
-
await fslib_1.xfs.changeFilePromise(path, content, {
|
|
177
|
-
automaticNewlines: true,
|
|
205
|
+
yarnPath: core_1.Configuration.deleteProperty,
|
|
178
206
|
});
|
|
179
207
|
}
|
|
208
|
+
const manifest = (await core_1.Manifest.tryFind(projectCwd)) || new core_1.Manifest();
|
|
209
|
+
manifest.packageManager = `yarn@${isTaggedYarnVersion
|
|
210
|
+
? bundleVersion
|
|
211
|
+
// If the version isn't tagged, we use the latest stable version as the wrapper
|
|
212
|
+
: await resolveTag(configuration, `stable`)}`;
|
|
213
|
+
const data = {};
|
|
214
|
+
manifest.exportTo(data);
|
|
215
|
+
const path = fslib_1.ppath.join(projectCwd, core_1.Manifest.fileName);
|
|
216
|
+
const content = `${JSON.stringify(data, null, manifest.indent)}\n`;
|
|
217
|
+
await fslib_1.xfs.changeFilePromise(path, content, {
|
|
218
|
+
automaticNewlines: true,
|
|
219
|
+
});
|
|
220
|
+
return {
|
|
221
|
+
bundleVersion: bundleVersion,
|
|
222
|
+
};
|
|
180
223
|
}
|
|
181
224
|
exports.setVersion = setVersion;
|
package/lib/commands/unlink.js
CHANGED
|
@@ -5,7 +5,7 @@ const cli_1 = require("@yarnpkg/cli");
|
|
|
5
5
|
const core_1 = require("@yarnpkg/core");
|
|
6
6
|
const fslib_1 = require("@yarnpkg/fslib");
|
|
7
7
|
const clipanion_1 = require("clipanion");
|
|
8
|
-
const micromatch_1 =
|
|
8
|
+
const micromatch_1 = tslib_1.__importDefault(require("micromatch"));
|
|
9
9
|
// eslint-disable-next-line arca/no-default-export
|
|
10
10
|
class UnlinkCommand extends cli_1.BaseCommand {
|
|
11
11
|
constructor() {
|
package/lib/commands/up.d.ts
CHANGED
package/lib/commands/up.js
CHANGED
|
@@ -7,9 +7,9 @@ const core_2 = require("@yarnpkg/core");
|
|
|
7
7
|
const core_3 = require("@yarnpkg/core");
|
|
8
8
|
const clipanion_1 = require("clipanion");
|
|
9
9
|
const enquirer_1 = require("enquirer");
|
|
10
|
-
const micromatch_1 =
|
|
11
|
-
const t =
|
|
12
|
-
const suggestUtils =
|
|
10
|
+
const micromatch_1 = tslib_1.__importDefault(require("micromatch"));
|
|
11
|
+
const t = tslib_1.__importStar(require("typanion"));
|
|
12
|
+
const suggestUtils = tslib_1.__importStar(require("../suggestUtils"));
|
|
13
13
|
// eslint-disable-next-line arca/no-default-export
|
|
14
14
|
class UpCommand extends cli_1.BaseCommand {
|
|
15
15
|
constructor() {
|
|
@@ -17,6 +17,9 @@ class UpCommand extends cli_1.BaseCommand {
|
|
|
17
17
|
this.interactive = clipanion_1.Option.Boolean(`-i,--interactive`, {
|
|
18
18
|
description: `Offer various choices, depending on the detected upgrade paths`,
|
|
19
19
|
});
|
|
20
|
+
this.fixed = clipanion_1.Option.Boolean(`-F,--fixed`, false, {
|
|
21
|
+
description: `Store dependency tags as-is instead of resolving them`,
|
|
22
|
+
});
|
|
20
23
|
this.exact = clipanion_1.Option.Boolean(`-E,--exact`, false, {
|
|
21
24
|
description: `Don't use any semver modifier on the resolved range`,
|
|
22
25
|
});
|
|
@@ -90,6 +93,7 @@ class UpCommand extends cli_1.BaseCommand {
|
|
|
90
93
|
await project.restoreInstallState({
|
|
91
94
|
restoreResolutions: false,
|
|
92
95
|
});
|
|
96
|
+
const fixed = this.fixed;
|
|
93
97
|
const interactive = (_a = this.interactive) !== null && _a !== void 0 ? _a : configuration.get(`preferInteractive`);
|
|
94
98
|
const modifier = suggestUtils.getModifier(this, project);
|
|
95
99
|
const strategies = interactive ? [
|
|
@@ -124,7 +128,7 @@ class UpCommand extends cli_1.BaseCommand {
|
|
|
124
128
|
workspace,
|
|
125
129
|
target,
|
|
126
130
|
existingDescriptor,
|
|
127
|
-
await suggestUtils.getSuggestedDescriptors(request, { project, workspace, cache, target, modifier, strategies }),
|
|
131
|
+
await suggestUtils.getSuggestedDescriptors(request, { project, workspace, cache, target, fixed, modifier, strategies }),
|
|
128
132
|
];
|
|
129
133
|
}));
|
|
130
134
|
isReferenced = true;
|
|
@@ -185,7 +189,7 @@ class UpCommand extends cli_1.BaseCommand {
|
|
|
185
189
|
({ answer: selected } = await (0, enquirer_1.prompt)({
|
|
186
190
|
type: `select`,
|
|
187
191
|
name: `answer`,
|
|
188
|
-
message: `Which range
|
|
192
|
+
message: `Which range do you want to use in ${core_1.structUtils.prettyWorkspace(configuration, workspace)} ❯ ${target}?`,
|
|
189
193
|
choices: suggestions.map(({ descriptor, name, reason }) => descriptor ? {
|
|
190
194
|
name,
|
|
191
195
|
hint: reason,
|
package/lib/dedupeUtils.d.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { Project, ResolveOptions, Resolver, Descriptor, Package, Report, Cache } from '@yarnpkg/core';
|
|
2
2
|
import { Fetcher, FetchOptions } from '@yarnpkg/core';
|
|
3
|
+
export declare type PackageUpdate = {
|
|
4
|
+
descriptor: Descriptor;
|
|
5
|
+
currentPackage: Package;
|
|
6
|
+
updatedPackage: Package;
|
|
7
|
+
resolvedPackage: Package;
|
|
8
|
+
};
|
|
3
9
|
export declare type Algorithm = (project: Project, patterns: Array<string>, opts: {
|
|
4
10
|
resolver: Resolver;
|
|
5
11
|
resolveOptions: ResolveOptions;
|
|
6
12
|
fetcher: Fetcher;
|
|
7
13
|
fetchOptions: FetchOptions;
|
|
8
|
-
}) => Promise<Array<Promise<
|
|
9
|
-
descriptor: Descriptor;
|
|
10
|
-
currentPackage: Package;
|
|
11
|
-
updatedPackage: Package;
|
|
12
|
-
} | null>>>;
|
|
14
|
+
}) => Promise<Array<Promise<PackageUpdate>>>;
|
|
13
15
|
export declare enum Strategy {
|
|
14
16
|
/**
|
|
15
17
|
* This strategy dedupes a locator to the best candidate already installed in the project.
|
package/lib/dedupeUtils.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.dedupe = exports.acceptedStrategies = exports.Strategy = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const core_1 = require("@yarnpkg/core");
|
|
6
6
|
const core_2 = require("@yarnpkg/core");
|
|
7
|
-
const micromatch_1 =
|
|
7
|
+
const micromatch_1 = tslib_1.__importDefault(require("micromatch"));
|
|
8
8
|
var Strategy;
|
|
9
9
|
(function (Strategy) {
|
|
10
10
|
/**
|
|
@@ -26,44 +26,75 @@ const DEDUPE_ALGORITHMS = {
|
|
|
26
26
|
throw new Error(`Assertion failed: The descriptor (${descriptorHash}) should have been registered`);
|
|
27
27
|
core_1.miscUtils.getSetWithDefault(locatorsByIdent, descriptor.identHash).add(locatorHash);
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
const deferredMap = new Map(core_1.miscUtils.mapAndFilter(project.storedDescriptors.values(), descriptor => {
|
|
30
|
+
// We only care about resolutions that are stored in the lockfile
|
|
31
|
+
// (we shouldn't accidentally try deduping virtual packages)
|
|
32
|
+
if (core_2.structUtils.isVirtualDescriptor(descriptor))
|
|
33
|
+
return core_1.miscUtils.mapAndFilter.skip;
|
|
34
|
+
return [descriptor.descriptorHash, core_1.miscUtils.makeDeferred()];
|
|
35
|
+
}));
|
|
36
|
+
for (const descriptor of project.storedDescriptors.values()) {
|
|
37
|
+
const deferred = deferredMap.get(descriptor.descriptorHash);
|
|
38
|
+
if (typeof deferred === `undefined`)
|
|
39
|
+
throw new Error(`Assertion failed: The descriptor (${descriptor.descriptorHash}) should have been registered`);
|
|
32
40
|
const currentResolution = project.storedResolutions.get(descriptor.descriptorHash);
|
|
33
41
|
if (typeof currentResolution === `undefined`)
|
|
34
42
|
throw new Error(`Assertion failed: The resolution (${descriptor.descriptorHash}) should have been registered`);
|
|
35
|
-
// We only care about resolutions that are stored in the lockfile
|
|
36
|
-
// (we shouldn't accidentally try deduping virtual packages)
|
|
37
43
|
const currentPackage = project.originalPackages.get(currentResolution);
|
|
38
44
|
if (typeof currentPackage === `undefined`)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
45
|
+
throw new Error(`Assertion failed: The package (${currentResolution}) should have been registered`);
|
|
46
|
+
Promise.resolve().then(async () => {
|
|
47
|
+
var _a;
|
|
48
|
+
const dependencies = resolver.getResolutionDependencies(descriptor, resolveOptions);
|
|
49
|
+
const resolvedDependencies = Object.fromEntries(await core_1.miscUtils.allSettledSafe(Object.entries(dependencies).map(async ([dependencyName, dependency]) => {
|
|
50
|
+
const dependencyDeferred = deferredMap.get(dependency.descriptorHash);
|
|
51
|
+
if (typeof dependencyDeferred === `undefined`)
|
|
52
|
+
throw new Error(`Assertion failed: The descriptor (${dependency.descriptorHash}) should have been registered`);
|
|
53
|
+
const dedupeResult = await dependencyDeferred.promise;
|
|
54
|
+
if (!dedupeResult)
|
|
55
|
+
throw new Error(`Assertion failed: Expected the dependency to have been through the dedupe process itself`);
|
|
56
|
+
return [dependencyName, dedupeResult.updatedPackage];
|
|
57
|
+
})));
|
|
58
|
+
if (patterns.length && !micromatch_1.default.isMatch(core_2.structUtils.stringifyIdent(descriptor), patterns))
|
|
59
|
+
return currentPackage;
|
|
60
|
+
// No need to try deduping packages that are not persisted,
|
|
61
|
+
// they will be resolved again anyways
|
|
62
|
+
if (!resolver.shouldPersistResolution(currentPackage, resolveOptions))
|
|
63
|
+
return currentPackage;
|
|
64
|
+
const candidateHashes = locatorsByIdent.get(descriptor.identHash);
|
|
65
|
+
if (typeof candidateHashes === `undefined`)
|
|
66
|
+
throw new Error(`Assertion failed: The resolutions (${descriptor.identHash}) should have been registered`);
|
|
67
|
+
// No need to choose when there's only one possibility
|
|
68
|
+
if (candidateHashes.size === 1)
|
|
69
|
+
return currentPackage;
|
|
70
|
+
const candidates = [...candidateHashes].map(locatorHash => {
|
|
71
|
+
const pkg = project.originalPackages.get(locatorHash);
|
|
72
|
+
if (typeof pkg === `undefined`)
|
|
73
|
+
throw new Error(`Assertion failed: The package (${locatorHash}) should have been registered`);
|
|
74
|
+
return pkg;
|
|
75
|
+
});
|
|
76
|
+
const satisfying = await resolver.getSatisfying(descriptor, resolvedDependencies, candidates, resolveOptions);
|
|
77
|
+
const bestLocator = (_a = satisfying.locators) === null || _a === void 0 ? void 0 : _a[0];
|
|
78
|
+
if (typeof bestLocator === `undefined` || !satisfying.sorted)
|
|
79
|
+
return currentPackage;
|
|
80
|
+
const updatedPackage = project.originalPackages.get(bestLocator.locatorHash);
|
|
81
|
+
if (typeof updatedPackage === `undefined`)
|
|
82
|
+
throw new Error(`Assertion failed: The package (${bestLocator.locatorHash}) should have been registered`);
|
|
83
|
+
return updatedPackage;
|
|
84
|
+
}).then(async (updatedPackage) => {
|
|
85
|
+
const resolvedPackage = await project.preparePackage(updatedPackage, { resolver, resolveOptions });
|
|
86
|
+
deferred.resolve({
|
|
87
|
+
descriptor,
|
|
88
|
+
currentPackage,
|
|
89
|
+
updatedPackage,
|
|
90
|
+
resolvedPackage,
|
|
91
|
+
});
|
|
92
|
+
}).catch(error => {
|
|
93
|
+
deferred.reject(error);
|
|
55
94
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return null;
|
|
60
|
-
const updatedResolution = bestCandidate.locatorHash;
|
|
61
|
-
const updatedPackage = project.originalPackages.get(updatedResolution);
|
|
62
|
-
if (typeof updatedPackage === `undefined`)
|
|
63
|
-
throw new Error(`Assertion failed: The package (${updatedResolution}) should have been registered`);
|
|
64
|
-
if (updatedResolution === currentResolution)
|
|
65
|
-
return null;
|
|
66
|
-
return { descriptor, currentPackage, updatedPackage };
|
|
95
|
+
}
|
|
96
|
+
return [...deferredMap.values()].map(deferred => {
|
|
97
|
+
return deferred.promise;
|
|
67
98
|
});
|
|
68
99
|
},
|
|
69
100
|
};
|
|
@@ -97,7 +128,7 @@ async function dedupe(project, { strategy, patterns, cache, report }) {
|
|
|
97
128
|
let dedupedPackageCount = 0;
|
|
98
129
|
await Promise.all(dedupePromises.map(dedupePromise => dedupePromise
|
|
99
130
|
.then(dedupe => {
|
|
100
|
-
if (dedupe === null)
|
|
131
|
+
if (dedupe === null || dedupe.currentPackage.locatorHash === dedupe.updatedPackage.locatorHash)
|
|
101
132
|
return;
|
|
102
133
|
dedupedPackageCount++;
|
|
103
134
|
const { descriptor, currentPackage, updatedPackage } = dedupe;
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -4,45 +4,45 @@ exports.suggestUtils = exports.dedupeUtils = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const core_1 = require("@yarnpkg/core");
|
|
6
6
|
const ci_info_1 = require("ci-info");
|
|
7
|
-
const add_1 =
|
|
8
|
-
const bin_1 =
|
|
9
|
-
const clean_1 =
|
|
10
|
-
const get_1 =
|
|
11
|
-
const set_1 =
|
|
12
|
-
const unset_1 =
|
|
13
|
-
const config_1 =
|
|
14
|
-
const dedupe_1 =
|
|
15
|
-
const clipanion_1 =
|
|
16
|
-
const help_1 =
|
|
17
|
-
const run_1 =
|
|
18
|
-
const version_1 =
|
|
19
|
-
const exec_1 =
|
|
20
|
-
const peerRequirements_1 =
|
|
21
|
-
const explain_1 =
|
|
22
|
-
const info_1 =
|
|
23
|
-
const install_1 =
|
|
24
|
-
const link_1 =
|
|
25
|
-
const node_1 =
|
|
26
|
-
const sources_1 =
|
|
27
|
-
const import_1 =
|
|
28
|
-
const list_1 =
|
|
29
|
-
const remove_1 =
|
|
30
|
-
const runtime_1 =
|
|
31
|
-
const rebuild_1 =
|
|
32
|
-
const remove_2 =
|
|
33
|
-
const runIndex_1 =
|
|
34
|
-
const run_2 =
|
|
35
|
-
const resolution_1 =
|
|
36
|
-
const sources_2 =
|
|
37
|
-
const version_2 =
|
|
38
|
-
const unlink_1 =
|
|
39
|
-
const up_1 =
|
|
40
|
-
const why_1 =
|
|
41
|
-
const list_2 =
|
|
42
|
-
const workspace_1 =
|
|
43
|
-
const dedupeUtils =
|
|
7
|
+
const add_1 = tslib_1.__importDefault(require("./commands/add"));
|
|
8
|
+
const bin_1 = tslib_1.__importDefault(require("./commands/bin"));
|
|
9
|
+
const clean_1 = tslib_1.__importDefault(require("./commands/cache/clean"));
|
|
10
|
+
const get_1 = tslib_1.__importDefault(require("./commands/config/get"));
|
|
11
|
+
const set_1 = tslib_1.__importDefault(require("./commands/config/set"));
|
|
12
|
+
const unset_1 = tslib_1.__importDefault(require("./commands/config/unset"));
|
|
13
|
+
const config_1 = tslib_1.__importDefault(require("./commands/config"));
|
|
14
|
+
const dedupe_1 = tslib_1.__importDefault(require("./commands/dedupe"));
|
|
15
|
+
const clipanion_1 = tslib_1.__importDefault(require("./commands/entries/clipanion"));
|
|
16
|
+
const help_1 = tslib_1.__importDefault(require("./commands/entries/help"));
|
|
17
|
+
const run_1 = tslib_1.__importDefault(require("./commands/entries/run"));
|
|
18
|
+
const version_1 = tslib_1.__importDefault(require("./commands/entries/version"));
|
|
19
|
+
const exec_1 = tslib_1.__importDefault(require("./commands/exec"));
|
|
20
|
+
const peerRequirements_1 = tslib_1.__importDefault(require("./commands/explain/peerRequirements"));
|
|
21
|
+
const explain_1 = tslib_1.__importDefault(require("./commands/explain"));
|
|
22
|
+
const info_1 = tslib_1.__importDefault(require("./commands/info"));
|
|
23
|
+
const install_1 = tslib_1.__importDefault(require("./commands/install"));
|
|
24
|
+
const link_1 = tslib_1.__importDefault(require("./commands/link"));
|
|
25
|
+
const node_1 = tslib_1.__importDefault(require("./commands/node"));
|
|
26
|
+
const sources_1 = tslib_1.__importDefault(require("./commands/plugin/import/sources"));
|
|
27
|
+
const import_1 = tslib_1.__importDefault(require("./commands/plugin/import"));
|
|
28
|
+
const list_1 = tslib_1.__importDefault(require("./commands/plugin/list"));
|
|
29
|
+
const remove_1 = tslib_1.__importDefault(require("./commands/plugin/remove"));
|
|
30
|
+
const runtime_1 = tslib_1.__importDefault(require("./commands/plugin/runtime"));
|
|
31
|
+
const rebuild_1 = tslib_1.__importDefault(require("./commands/rebuild"));
|
|
32
|
+
const remove_2 = tslib_1.__importDefault(require("./commands/remove"));
|
|
33
|
+
const runIndex_1 = tslib_1.__importDefault(require("./commands/runIndex"));
|
|
34
|
+
const run_2 = tslib_1.__importDefault(require("./commands/run"));
|
|
35
|
+
const resolution_1 = tslib_1.__importDefault(require("./commands/set/resolution"));
|
|
36
|
+
const sources_2 = tslib_1.__importDefault(require("./commands/set/version/sources"));
|
|
37
|
+
const version_2 = tslib_1.__importDefault(require("./commands/set/version"));
|
|
38
|
+
const unlink_1 = tslib_1.__importDefault(require("./commands/unlink"));
|
|
39
|
+
const up_1 = tslib_1.__importDefault(require("./commands/up"));
|
|
40
|
+
const why_1 = tslib_1.__importDefault(require("./commands/why"));
|
|
41
|
+
const list_2 = tslib_1.__importDefault(require("./commands/workspaces/list"));
|
|
42
|
+
const workspace_1 = tslib_1.__importDefault(require("./commands/workspace"));
|
|
43
|
+
const dedupeUtils = tslib_1.__importStar(require("./dedupeUtils"));
|
|
44
44
|
exports.dedupeUtils = dedupeUtils;
|
|
45
|
-
const suggestUtils =
|
|
45
|
+
const suggestUtils = tslib_1.__importStar(require("./suggestUtils"));
|
|
46
46
|
exports.suggestUtils = suggestUtils;
|
|
47
47
|
const plugin = {
|
|
48
48
|
configuration: {
|
|
@@ -57,6 +57,11 @@ const plugin = {
|
|
|
57
57
|
values: [`^`, `~`, ``],
|
|
58
58
|
default: suggestUtils.Modifier.CARET,
|
|
59
59
|
},
|
|
60
|
+
preferReuse: {
|
|
61
|
+
description: `If true, \`yarn add\` will attempt to reuse the most common dependency range in other workspaces.`,
|
|
62
|
+
type: core_1.SettingsType.BOOLEAN,
|
|
63
|
+
default: false,
|
|
64
|
+
},
|
|
60
65
|
},
|
|
61
66
|
commands: [
|
|
62
67
|
clean_1.default,
|
package/lib/suggestUtils.d.ts
CHANGED
|
@@ -78,11 +78,12 @@ export declare function extractDescriptorFromPath(path: PortablePath, { cwd, wor
|
|
|
78
78
|
cwd: PortablePath;
|
|
79
79
|
workspace: Workspace;
|
|
80
80
|
}): Promise<Descriptor>;
|
|
81
|
-
export declare function getSuggestedDescriptors(request: Descriptor, { project, workspace, cache, target, modifier, strategies, maxResults }: {
|
|
81
|
+
export declare function getSuggestedDescriptors(request: Descriptor, { project, workspace, cache, target, fixed, modifier, strategies, maxResults }: {
|
|
82
82
|
project: Project;
|
|
83
83
|
workspace: Workspace;
|
|
84
84
|
cache: Cache;
|
|
85
85
|
target: Target;
|
|
86
|
+
fixed: boolean;
|
|
86
87
|
modifier: Modifier;
|
|
87
88
|
strategies: Array<Strategy>;
|
|
88
89
|
maxResults?: number;
|
package/lib/suggestUtils.js
CHANGED
|
@@ -5,7 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const core_1 = require("@yarnpkg/core");
|
|
6
6
|
const core_2 = require("@yarnpkg/core");
|
|
7
7
|
const fslib_1 = require("@yarnpkg/fslib");
|
|
8
|
-
const semver_1 =
|
|
8
|
+
const semver_1 = tslib_1.__importDefault(require("semver"));
|
|
9
9
|
const WORKSPACE_PROTOCOL = `workspace:`;
|
|
10
10
|
var Target;
|
|
11
11
|
(function (Target) {
|
|
@@ -165,10 +165,15 @@ async function extractDescriptorFromPath(path, { cwd, workspace }) {
|
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
167
|
exports.extractDescriptorFromPath = extractDescriptorFromPath;
|
|
168
|
-
async function getSuggestedDescriptors(request, { project, workspace, cache, target, modifier, strategies, maxResults = Infinity }) {
|
|
168
|
+
async function getSuggestedDescriptors(request, { project, workspace, cache, target, fixed, modifier, strategies, maxResults = Infinity }) {
|
|
169
169
|
if (!(maxResults >= 0))
|
|
170
170
|
throw new Error(`Invalid maxResults (${maxResults})`);
|
|
171
|
-
|
|
171
|
+
const [requestRange, requestTag] = request.range !== `unknown`
|
|
172
|
+
? fixed || semver_1.default.validRange(request.range) || !request.range.match(/^[a-z0-9._-]+$/i)
|
|
173
|
+
? [request.range, `latest`]
|
|
174
|
+
: [`unknown`, request.range]
|
|
175
|
+
: [`unknown`, `latest`];
|
|
176
|
+
if (requestRange !== `unknown`) {
|
|
172
177
|
return {
|
|
173
178
|
suggestions: [{
|
|
174
179
|
descriptor: request,
|
|
@@ -265,14 +270,7 @@ async function getSuggestedDescriptors(request, { project, workspace, cache, tar
|
|
|
265
270
|
case Strategy.LATEST:
|
|
266
271
|
{
|
|
267
272
|
await trySuggest(async () => {
|
|
268
|
-
if (
|
|
269
|
-
suggested.push({
|
|
270
|
-
descriptor: request,
|
|
271
|
-
name: `Use ${core_2.structUtils.prettyRange(project.configuration, request.range)}`,
|
|
272
|
-
reason: `(explicit range requested)`,
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
else if (target === Target.PEER) {
|
|
273
|
+
if (target === Target.PEER) {
|
|
276
274
|
suggested.push({
|
|
277
275
|
descriptor: core_2.structUtils.makeDescriptor(request, `*`),
|
|
278
276
|
name: `Use *`,
|
|
@@ -287,7 +285,7 @@ async function getSuggestedDescriptors(request, { project, workspace, cache, tar
|
|
|
287
285
|
});
|
|
288
286
|
}
|
|
289
287
|
else {
|
|
290
|
-
let latest = await fetchDescriptorFrom(request, `
|
|
288
|
+
let latest = await fetchDescriptorFrom(request, `${project.configuration.get(`defaultProtocol`)}${requestTag}`, { project, cache, workspace, preserveModifier: false });
|
|
291
289
|
if (latest) {
|
|
292
290
|
latest = applyModifier(latest, modifier);
|
|
293
291
|
suggested.push({
|
|
@@ -318,7 +316,7 @@ async function fetchDescriptorFrom(ident, range, { project, cache, workspace, pr
|
|
|
318
316
|
// The descriptor has to be bound for the resolvers that need a parent locator. (e.g. FileResolver)
|
|
319
317
|
// If we didn't bind it, `yarn add ./folder` wouldn't work.
|
|
320
318
|
const boundDescriptor = resolver.bindDescriptor(latestDescriptor, workspace.anchoredLocator, resolveOptions);
|
|
321
|
-
const candidateLocators = await resolver.getCandidates(boundDescriptor,
|
|
319
|
+
const candidateLocators = await resolver.getCandidates(boundDescriptor, {}, resolveOptions);
|
|
322
320
|
if (candidateLocators.length === 0)
|
|
323
321
|
return null;
|
|
324
322
|
// Per the requirements exposed in Resolver.ts, the best is the first one
|
package/package.json
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yarnpkg/plugin-essentials",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-rc.2",
|
|
4
4
|
"license": "BSD-2-Clause",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@yarnpkg/fslib": "^
|
|
8
|
-
"@yarnpkg/
|
|
9
|
-
"@yarnpkg/parsers": "^2.5.0-rc.9",
|
|
7
|
+
"@yarnpkg/fslib": "^3.0.0-rc.2",
|
|
8
|
+
"@yarnpkg/parsers": "^3.0.0-rc.2",
|
|
10
9
|
"ci-info": "^3.2.0",
|
|
11
|
-
"clipanion": "^3.2.0-rc.
|
|
10
|
+
"clipanion": "^3.2.0-rc.10",
|
|
12
11
|
"enquirer": "^2.3.6",
|
|
13
12
|
"lodash": "^4.17.15",
|
|
14
13
|
"micromatch": "^4.0.2",
|
|
@@ -17,18 +16,17 @@
|
|
|
17
16
|
"typanion": "^3.3.0"
|
|
18
17
|
},
|
|
19
18
|
"peerDependencies": {
|
|
20
|
-
"@yarnpkg/cli": "^
|
|
21
|
-
"@yarnpkg/core": "^
|
|
22
|
-
"@yarnpkg/plugin-git": "^
|
|
19
|
+
"@yarnpkg/cli": "^4.0.0-rc.2",
|
|
20
|
+
"@yarnpkg/core": "^4.0.0-rc.2",
|
|
21
|
+
"@yarnpkg/plugin-git": "^3.0.0-rc.2"
|
|
23
22
|
},
|
|
24
23
|
"devDependencies": {
|
|
25
24
|
"@types/lodash": "^4.14.136",
|
|
26
25
|
"@types/micromatch": "^4.0.1",
|
|
27
26
|
"@types/semver": "^7.1.0",
|
|
28
|
-
"@
|
|
29
|
-
"@yarnpkg/
|
|
30
|
-
"@yarnpkg/
|
|
31
|
-
"@yarnpkg/plugin-git": "^2.6.0-rc.11"
|
|
27
|
+
"@yarnpkg/cli": "^4.0.0-rc.2",
|
|
28
|
+
"@yarnpkg/core": "^4.0.0-rc.2",
|
|
29
|
+
"@yarnpkg/plugin-git": "^3.0.0-rc.2"
|
|
32
30
|
},
|
|
33
31
|
"repository": {
|
|
34
32
|
"type": "git",
|
|
@@ -47,8 +45,8 @@
|
|
|
47
45
|
"/lib/**/*"
|
|
48
46
|
],
|
|
49
47
|
"engines": {
|
|
50
|
-
"node": ">=
|
|
48
|
+
"node": ">=14.15.0"
|
|
51
49
|
},
|
|
52
|
-
"stableVersion": "3.
|
|
50
|
+
"stableVersion": "3.2.0",
|
|
53
51
|
"typings": "./lib/index.d.ts"
|
|
54
52
|
}
|