@yarnpkg/plugin-essentials 4.0.0 → 4.0.1

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.
@@ -5,7 +5,7 @@ import { Writable } from 'stream';
5
5
  export default class ExplainPeerRequirementsCommand extends BaseCommand {
6
6
  static paths: string[][];
7
7
  static usage: import("clipanion").Usage;
8
- hash: string | undefined;
8
+ hash: string;
9
9
  execute(): Promise<0 | 1>;
10
10
  }
11
11
  export declare function explainPeerRequirements(peerRequirementsHash: string, project: Project, opts: {
@@ -11,8 +11,7 @@ class ExplainPeerRequirementsCommand extends cli_1.BaseCommand {
11
11
  constructor() {
12
12
  super(...arguments);
13
13
  this.hash = clipanion_1.Option.String({
14
- required: false,
15
- validator: t.applyCascade(t.isString(), [
14
+ validator: t.cascade(t.isString(), [
16
15
  t.matchesRegExp(/^p[0-9a-f]{5}$/),
17
16
  ]),
18
17
  });
@@ -23,42 +22,10 @@ class ExplainPeerRequirementsCommand extends cli_1.BaseCommand {
23
22
  await project.restoreInstallState({
24
23
  restoreResolutions: false,
25
24
  });
26
- // peerRequirements aren't stored inside the install state
27
25
  await project.applyLightResolution();
28
- if (typeof this.hash !== `undefined`) {
29
- return await explainPeerRequirements(this.hash, project, {
30
- stdout: this.context.stdout,
31
- });
32
- }
33
- const report = await core_1.StreamReport.start({
34
- configuration,
26
+ return await explainPeerRequirements(this.hash, project, {
35
27
  stdout: this.context.stdout,
36
- includeFooter: false,
37
- }, async (report) => {
38
- const sortCriterias = [
39
- ([, requirement]) => core_1.structUtils.stringifyLocator(project.storedPackages.get(requirement.subject)),
40
- ([, requirement]) => core_1.structUtils.stringifyIdent(requirement.requested),
41
- ];
42
- for (const [hash, requirement] of core_1.miscUtils.sortMap(project.peerRequirements, sortCriterias)) {
43
- const subject = project.storedPackages.get(requirement.subject);
44
- if (typeof subject === `undefined`)
45
- throw new Error(`Assertion failed: Expected the subject package to have been registered`);
46
- const rootRequester = project.storedPackages.get(requirement.rootRequester);
47
- if (typeof rootRequester === `undefined`)
48
- throw new Error(`Assertion failed: Expected the root package to have been registered`);
49
- const providedDescriptor = subject.dependencies.get(requirement.requested.identHash) ?? null;
50
- const prettyHash = core_1.formatUtils.pretty(configuration, hash, core_1.formatUtils.Type.CODE);
51
- const prettySubject = core_1.structUtils.prettyLocator(configuration, subject);
52
- const prettyIdent = core_1.structUtils.prettyIdent(configuration, requirement.requested);
53
- const prettyRoot = core_1.structUtils.prettyIdent(configuration, rootRequester);
54
- const descendantCount = requirement.allRequesters.length - 1;
55
- const pluralized = `descendant${descendantCount === 1 ? `` : `s`}`;
56
- const maybeDescendants = descendantCount > 0 ? ` and ${descendantCount} ${pluralized}` : ``;
57
- const provides = providedDescriptor !== null ? `provides` : `doesn't provide`;
58
- report.reportInfo(null, `${prettyHash} → ${prettySubject} ${provides} ${prettyIdent} to ${prettyRoot}${maybeDescendants}`);
59
- }
60
28
  });
61
- return report.exitCode();
62
29
  }
63
30
  }
64
31
  ExplainPeerRequirementsCommand.paths = [
@@ -85,79 +52,83 @@ ExplainPeerRequirementsCommand.usage = clipanion_1.Command.Usage({
85
52
  });
86
53
  exports.default = ExplainPeerRequirementsCommand;
87
54
  async function explainPeerRequirements(peerRequirementsHash, project, opts) {
88
- const { configuration } = project;
89
- const requirement = project.peerRequirements.get(peerRequirementsHash);
90
- if (typeof requirement === `undefined`)
55
+ const warning = project.peerWarnings.find(warning => {
56
+ return warning.hash === peerRequirementsHash;
57
+ });
58
+ if (typeof warning === `undefined`)
91
59
  throw new Error(`No peerDependency requirements found for hash: "${peerRequirementsHash}"`);
92
60
  const report = await core_1.StreamReport.start({
93
- configuration,
61
+ configuration: project.configuration,
94
62
  stdout: opts.stdout,
95
63
  includeFooter: false,
64
+ includePrefix: false,
96
65
  }, async (report) => {
97
- const subject = project.storedPackages.get(requirement.subject);
98
- if (typeof subject === `undefined`)
99
- throw new Error(`Assertion failed: Expected the subject package to have been registered`);
100
- const rootRequester = project.storedPackages.get(requirement.rootRequester);
101
- if (typeof rootRequester === `undefined`)
102
- throw new Error(`Assertion failed: Expected the root package to have been registered`);
103
- const providedDescriptor = subject.dependencies.get(requirement.requested.identHash) ?? null;
104
- const providedResolution = providedDescriptor !== null
105
- ? project.storedResolutions.get(providedDescriptor.descriptorHash)
106
- : null;
107
- if (typeof providedResolution === `undefined`)
108
- throw new Error(`Assertion failed: Expected the resolution to have been registered`);
109
- const provided = providedResolution !== null
110
- ? project.storedPackages.get(providedResolution)
111
- : null;
112
- if (typeof provided === `undefined`)
113
- throw new Error(`Assertion failed: Expected the provided package to have been registered`);
114
- const allRequesters = [...requirement.allRequesters.values()].map(requesterHash => {
115
- const pkg = project.storedPackages.get(requesterHash);
116
- if (typeof pkg === `undefined`)
117
- throw new Error(`Assertion failed: Expected the package to be registered`);
118
- const devirtualizedLocator = core_1.structUtils.devirtualizeLocator(pkg);
119
- const devirtualizedPkg = project.storedPackages.get(devirtualizedLocator.locatorHash);
120
- if (typeof devirtualizedPkg === `undefined`)
121
- throw new Error(`Assertion failed: Expected the package to be registered`);
122
- const peerDependency = devirtualizedPkg.peerDependencies.get(requirement.requested.identHash);
123
- if (typeof peerDependency === `undefined`)
124
- throw new Error(`Assertion failed: Expected the peer dependency to be registered`);
125
- return { pkg, peerDependency };
126
- });
127
- if (provided !== null) {
128
- const satisfiesAllRanges = allRequesters.every(({ peerDependency }) => {
129
- return core_1.semverUtils.satisfiesWithPrereleases(provided.version, peerDependency.range);
130
- });
131
- report.reportInfo(core_1.MessageName.UNNAMED, `${core_1.structUtils.prettyLocator(configuration, subject)} provides ${core_1.structUtils.prettyLocator(configuration, provided)} with version ${core_1.structUtils.prettyReference(configuration, provided.version ?? `<missing>`)}, which ${satisfiesAllRanges ? `satisfies` : `doesn't satisfy`} the following requirements:`);
132
- }
133
- else {
134
- report.reportInfo(core_1.MessageName.UNNAMED, `${core_1.structUtils.prettyLocator(configuration, subject)} doesn't provide ${core_1.structUtils.prettyIdent(configuration, requirement.requested)}, breaking the following requirements:`);
135
- }
136
- report.reportSeparator();
137
- const Mark = core_1.formatUtils.mark(configuration);
138
- const requirements = [];
139
- for (const { pkg, peerDependency } of core_1.miscUtils.sortMap(allRequesters, requester => core_1.structUtils.stringifyLocator(requester.pkg))) {
140
- const isSatisfied = provided !== null
141
- ? core_1.semverUtils.satisfiesWithPrereleases(provided.version, peerDependency.range)
142
- : false;
143
- const mark = isSatisfied ? Mark.Check : Mark.Cross;
144
- requirements.push({
145
- stringifiedLocator: core_1.structUtils.stringifyLocator(pkg),
146
- prettyLocator: core_1.structUtils.prettyLocator(configuration, pkg),
147
- prettyRange: core_1.structUtils.prettyRange(configuration, peerDependency.range),
148
- mark,
149
- });
150
- }
151
- const maxStringifiedLocatorLength = Math.max(...requirements.map(({ stringifiedLocator }) => stringifiedLocator.length));
152
- const maxPrettyRangeLength = Math.max(...requirements.map(({ prettyRange }) => prettyRange.length));
153
- for (const { stringifiedLocator, prettyLocator, prettyRange, mark } of core_1.miscUtils.sortMap(requirements, ({ stringifiedLocator }) => stringifiedLocator)) {
154
- report.reportInfo(null, `${
155
- // We have to do this because prettyLocators can contain multiple colors
156
- prettyLocator.padEnd(maxStringifiedLocatorLength + (prettyLocator.length - stringifiedLocator.length), ` `)} → ${prettyRange.padEnd(maxPrettyRangeLength, ` `)} ${mark}`);
157
- }
158
- if (requirements.length > 1) {
159
- report.reportSeparator();
160
- report.reportInfo(core_1.MessageName.UNNAMED, `Note: these requirements start with ${core_1.structUtils.prettyLocator(project.configuration, rootRequester)}`);
66
+ const Marks = core_1.formatUtils.mark(project.configuration);
67
+ switch (warning.type) {
68
+ case core_1.PeerWarningType.NotCompatibleAggregate:
69
+ {
70
+ report.reportInfo(core_1.MessageName.UNNAMED, `We have a problem with ${core_1.formatUtils.pretty(project.configuration, warning.requested, core_1.formatUtils.Type.IDENT)}, which is provided with version ${core_1.structUtils.prettyReference(project.configuration, warning.version)}.`);
71
+ report.reportInfo(core_1.MessageName.UNNAMED, `It is needed by the following direct dependencies of workspaces in your project:`);
72
+ report.reportSeparator();
73
+ for (const dependent of warning.requesters.values()) {
74
+ const dependentPkg = project.storedPackages.get(dependent.locatorHash);
75
+ if (!dependentPkg)
76
+ throw new Error(`Assertion failed: Expected the package to be registered`);
77
+ const descriptor = dependentPkg?.peerDependencies.get(warning.requested.identHash);
78
+ if (!descriptor)
79
+ throw new Error(`Assertion failed: Expected the package to list the peer dependency`);
80
+ const mark = core_1.semverUtils.satisfiesWithPrereleases(warning.version, descriptor.range)
81
+ ? Marks.Check
82
+ : Marks.Cross;
83
+ report.reportInfo(null, ` ${mark} ${core_1.structUtils.prettyLocator(project.configuration, dependent)} (via ${core_1.structUtils.prettyRange(project.configuration, descriptor.range)})`);
84
+ }
85
+ const transitiveLinks = [...warning.links.values()].filter(link => {
86
+ return !warning.requesters.has(link.locatorHash);
87
+ });
88
+ if (transitiveLinks.length > 0) {
89
+ report.reportSeparator();
90
+ report.reportInfo(core_1.MessageName.UNNAMED, `However, those packages themselves have more dependencies listing ${core_1.structUtils.prettyIdent(project.configuration, warning.requested)} as peer dependency:`);
91
+ report.reportSeparator();
92
+ for (const link of transitiveLinks) {
93
+ const linkPkg = project.storedPackages.get(link.locatorHash);
94
+ if (!linkPkg)
95
+ throw new Error(`Assertion failed: Expected the package to be registered`);
96
+ const descriptor = linkPkg?.peerDependencies.get(warning.requested.identHash);
97
+ if (!descriptor)
98
+ throw new Error(`Assertion failed: Expected the package to list the peer dependency`);
99
+ const mark = core_1.semverUtils.satisfiesWithPrereleases(warning.version, descriptor.range)
100
+ ? Marks.Check
101
+ : Marks.Cross;
102
+ report.reportInfo(null, ` ${mark} ${core_1.structUtils.prettyLocator(project.configuration, link)} (via ${core_1.structUtils.prettyRange(project.configuration, descriptor.range)})`);
103
+ }
104
+ }
105
+ const allRanges = Array.from(warning.links.values(), locator => {
106
+ const pkg = project.storedPackages.get(locator.locatorHash);
107
+ if (typeof pkg === `undefined`)
108
+ throw new Error(`Assertion failed: Expected the package to be registered`);
109
+ const peerDependency = pkg.peerDependencies.get(warning.requested.identHash);
110
+ if (typeof peerDependency === `undefined`)
111
+ throw new Error(`Assertion failed: Expected the ident to be registered`);
112
+ return peerDependency.range;
113
+ });
114
+ if (allRanges.length > 1) {
115
+ const resolvedRange = core_1.semverUtils.simplifyRanges(allRanges);
116
+ report.reportSeparator();
117
+ if (resolvedRange === null) {
118
+ report.reportInfo(core_1.MessageName.UNNAMED, `Unfortunately, put together, we found no single range that can satisfy all those peer requirements.`);
119
+ report.reportInfo(core_1.MessageName.UNNAMED, `Your best option may be to try to upgrade some dependencies with ${core_1.formatUtils.pretty(project.configuration, `yarn up`, core_1.formatUtils.Type.CODE)}, or silence the warning via ${core_1.formatUtils.pretty(project.configuration, `logFilters`, core_1.formatUtils.Type.CODE)}.`);
120
+ }
121
+ else {
122
+ report.reportInfo(core_1.MessageName.UNNAMED, `Put together, the final range we computed is ${core_1.formatUtils.pretty(project.configuration, resolvedRange, core_1.formatUtils.Type.RANGE)}`);
123
+ }
124
+ }
125
+ }
126
+ break;
127
+ default:
128
+ {
129
+ report.reportInfo(core_1.MessageName.UNNAMED, `The ${core_1.formatUtils.pretty(project.configuration, `yarn explain peer-requirements`, core_1.formatUtils.Type.CODE)} command doesn't support this warning type yet.`);
130
+ }
131
+ break;
161
132
  }
162
133
  });
163
134
  return report.exitCode();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yarnpkg/plugin-essentials",
3
- "version": "4.0.0",
3
+ "version": "4.0.1",
4
4
  "license": "BSD-2-Clause",
5
5
  "main": "./lib/index.js",
6
6
  "exports": {
@@ -8,7 +8,7 @@
8
8
  "./package.json": "./package.json"
9
9
  },
10
10
  "dependencies": {
11
- "@yarnpkg/fslib": "^3.0.0",
11
+ "@yarnpkg/fslib": "^3.0.1",
12
12
  "@yarnpkg/parsers": "^3.0.0",
13
13
  "ci-info": "^3.2.0",
14
14
  "clipanion": "^4.0.0-rc.2",
@@ -20,16 +20,16 @@
20
20
  "typanion": "^3.14.0"
21
21
  },
22
22
  "peerDependencies": {
23
- "@yarnpkg/cli": "^4.0.0",
24
- "@yarnpkg/core": "^4.0.0",
23
+ "@yarnpkg/cli": "^4.0.1",
24
+ "@yarnpkg/core": "^4.0.1",
25
25
  "@yarnpkg/plugin-git": "^3.0.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/lodash": "^4.14.136",
29
29
  "@types/micromatch": "^4.0.1",
30
30
  "@types/semver": "^7.1.0",
31
- "@yarnpkg/cli": "^4.0.0",
32
- "@yarnpkg/core": "^4.0.0",
31
+ "@yarnpkg/cli": "^4.0.1",
32
+ "@yarnpkg/core": "^4.0.1",
33
33
  "@yarnpkg/plugin-git": "^3.0.0"
34
34
  },
35
35
  "repository": {