Skip to content

Commit f92f5a6

Browse files
authored
Display which dependencies were fixed when running with --fix (#320)
1 parent f704ab5 commit f92f5a6

File tree

5 files changed

+223
-56
lines changed

5 files changed

+223
-56
lines changed

bin/check-dependency-version-consistency.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ import {
88
calculateMismatchingVersions,
99
filterOutIgnoredDependencies,
1010
fixMismatchingVersions,
11+
MismatchingDependencyVersions,
1112
} from '../lib/dependency-versions.js';
1213
import { getPackages } from '../lib/workspace.js';
13-
import { mismatchingVersionsToOutput } from '../lib/output.js';
14+
import {
15+
mismatchingVersionsToOutput,
16+
mismatchingVersionsFixedToOutput,
17+
} from '../lib/output.js';
1418
import { join, dirname } from 'node:path';
1519
import type { PackageJson } from 'type-fest';
1620
import { fileURLToPath } from 'node:url';
@@ -100,21 +104,31 @@ function run() {
100104
options.ignorePath,
101105
options.ignorePathPattern.map((s) => new RegExp(s))
102106
);
107+
103108
const dependencyVersions = calculateVersionsForEachDependency(packages);
109+
104110
let mismatchingVersions = filterOutIgnoredDependencies(
105111
calculateMismatchingVersions(dependencyVersions),
106112
options.ignoreDep,
107113
options.ignoreDepPattern.map((s) => new RegExp(s))
108114
);
115+
let mismatchingVersionsFixed: MismatchingDependencyVersions = [];
109116

110117
if (options.fix) {
111-
mismatchingVersions = fixMismatchingVersions(
118+
const resultsAfterFix = fixMismatchingVersions(
112119
packages,
113120
mismatchingVersions
114121
);
122+
mismatchingVersions = resultsAfterFix.notFixed;
123+
mismatchingVersionsFixed = resultsAfterFix.fixed;
124+
}
125+
126+
// Show output for dependencies we fixed.
127+
if (mismatchingVersionsFixed.length > 0) {
128+
console.log(mismatchingVersionsFixedToOutput(mismatchingVersionsFixed));
115129
}
116130

117-
// Show output.
131+
// Show output for dependencies that still have mismatches.
118132
if (mismatchingVersions.length > 0) {
119133
console.log(mismatchingVersionsToOutput(mismatchingVersions));
120134
process.exitCode = 1;

lib/dependency-versions.ts

Lines changed: 61 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -202,59 +202,71 @@ function writeDependencyVersion(
202202
export function fixMismatchingVersions(
203203
packages: Package[],
204204
mismatchingVersions: MismatchingDependencyVersions
205-
): MismatchingDependencyVersions {
206-
// Return any mismatching versions that are still present after attempting fixes.
207-
return mismatchingVersions
208-
.map((mismatchingVersion) => {
209-
const versions = mismatchingVersion.versions.map(
210-
(object) => object.version
211-
);
212-
let sortedVersions;
213-
try {
214-
sortedVersions = versions.sort(compareRanges);
215-
} catch {
216-
// Unable to sort so skip this dependency (return it to indicate it was not fixed).
217-
return mismatchingVersion;
218-
}
219-
const fixedVersion = sortedVersions[sortedVersions.length - 1]; // Highest version will be sorted to end of list.
205+
): {
206+
fixed: MismatchingDependencyVersions;
207+
notFixed: MismatchingDependencyVersions;
208+
} {
209+
const fixed = [];
210+
const notFixed = [];
211+
for (const mismatchingVersion of mismatchingVersions) {
212+
const versions = mismatchingVersion.versions.map(
213+
(object) => object.version
214+
);
215+
let sortedVersions;
216+
try {
217+
sortedVersions = versions.sort(compareRanges);
218+
} catch {
219+
// Unable to sort so skip this dependency.
220+
notFixed.push(mismatchingVersion);
221+
continue;
222+
}
220223

221-
for (const package_ of packages) {
222-
if (
223-
package_.packageJson.devDependencies &&
224-
package_.packageJson.devDependencies[mismatchingVersion.dependency] &&
225-
package_.packageJson.devDependencies[
226-
mismatchingVersion.dependency
227-
] !== fixedVersion
228-
) {
229-
writeDependencyVersion(
230-
package_.pathPackageJson,
231-
package_.packageJsonEndsInNewline,
232-
false,
233-
mismatchingVersion.dependency,
234-
fixedVersion
235-
);
236-
}
224+
const fixedVersion = sortedVersions[sortedVersions.length - 1]; // Highest version will be sorted to end of list.
237225

238-
if (
239-
package_.packageJson.dependencies &&
240-
package_.packageJson.dependencies[mismatchingVersion.dependency] &&
241-
package_.packageJson.dependencies[mismatchingVersion.dependency] !==
242-
fixedVersion
243-
) {
244-
writeDependencyVersion(
245-
package_.pathPackageJson,
246-
package_.packageJsonEndsInNewline,
247-
true,
248-
mismatchingVersion.dependency,
249-
fixedVersion
250-
);
251-
}
226+
let isFixed = false;
227+
for (const package_ of packages) {
228+
if (
229+
package_.packageJson.devDependencies &&
230+
package_.packageJson.devDependencies[mismatchingVersion.dependency] &&
231+
package_.packageJson.devDependencies[mismatchingVersion.dependency] !==
232+
fixedVersion
233+
) {
234+
writeDependencyVersion(
235+
package_.pathPackageJson,
236+
package_.packageJsonEndsInNewline,
237+
false,
238+
mismatchingVersion.dependency,
239+
fixedVersion
240+
);
241+
isFixed = true;
252242
}
253243

254-
// Fixed successfully.
255-
return undefined;
256-
})
257-
.filter((item) => item !== undefined) as MismatchingDependencyVersions;
244+
if (
245+
package_.packageJson.dependencies &&
246+
package_.packageJson.dependencies[mismatchingVersion.dependency] &&
247+
package_.packageJson.dependencies[mismatchingVersion.dependency] !==
248+
fixedVersion
249+
) {
250+
writeDependencyVersion(
251+
package_.pathPackageJson,
252+
package_.packageJsonEndsInNewline,
253+
true,
254+
mismatchingVersion.dependency,
255+
fixedVersion
256+
);
257+
isFixed = true;
258+
}
259+
}
260+
261+
if (isFixed) {
262+
fixed.push(mismatchingVersion);
263+
}
264+
}
265+
266+
return {
267+
fixed,
268+
notFixed,
269+
};
258270
}
259271

260272
export function compareRanges(a: string, b: string): 0 | -1 | 1 {

lib/output.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,18 @@ export function mismatchingVersionsToOutput(
6161
tables,
6262
].join('\n');
6363
}
64+
65+
export function mismatchingVersionsFixedToOutput(
66+
mismatchingDependencyVersions: MismatchingDependencyVersions
67+
): string {
68+
if (mismatchingDependencyVersions.length === 0) {
69+
throw new Error('No fixes to output.');
70+
}
71+
72+
const dependencies = mismatchingDependencyVersions
73+
.map((mismatchingVersion) => mismatchingVersion.dependency)
74+
.sort();
75+
return `Fixed versions for ${dependencies.length} ${
76+
dependencies.length === 1 ? 'dependency' : 'dependencies'
77+
}: ${dependencies.join(', ')}`;
78+
}

test/lib/dependency-versions-test.ts

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ describe('Utils | dependency-versions', function () {
310310
const mismatchingVersions = calculateMismatchingVersions(
311311
calculateVersionsForEachDependency(packages)
312312
);
313-
const fixedMismatchingVersions = fixMismatchingVersions(
313+
const { fixed, notFixed } = fixMismatchingVersions(
314314
packages,
315315
mismatchingVersions
316316
);
@@ -388,8 +388,8 @@ describe('Utils | dependency-versions', function () {
388388
).toStrictEqual('1.0.1');
389389

390390
// Check return value.
391-
// Should return only the dependency that could not be fixed due to the abnormal version present.
392-
expect(fixedMismatchingVersions).toStrictEqual([
391+
// Only one dependency should not be fixed due to the abnormal version present.
392+
expect(notFixed).toStrictEqual([
393393
{
394394
dependency: 'bar',
395395
versions: [
@@ -412,6 +412,95 @@ describe('Utils | dependency-versions', function () {
412412
],
413413
},
414414
]);
415+
expect(fixed).toStrictEqual([
416+
{
417+
dependency: '@types/one',
418+
versions: [
419+
{
420+
version: '1.0.0',
421+
packages: [
422+
expect.objectContaining({
423+
path: join('@scope1', 'package2'),
424+
}),
425+
],
426+
},
427+
{
428+
version: '1.0.1',
429+
packages: [
430+
expect.objectContaining({
431+
path: join('@scope1', 'package1'),
432+
}),
433+
],
434+
},
435+
],
436+
},
437+
{
438+
dependency: 'a.b.c',
439+
versions: [
440+
{
441+
version: '5.0.0',
442+
packages: [
443+
expect.objectContaining({
444+
path: join('@scope1', 'package1'),
445+
}),
446+
],
447+
},
448+
{
449+
version: '~5.5.0',
450+
packages: [
451+
expect.objectContaining({
452+
path: join('@scope1', 'package2'),
453+
}),
454+
],
455+
},
456+
],
457+
},
458+
{
459+
dependency: 'foo',
460+
versions: [
461+
{
462+
version: '^1.0.0',
463+
packages: [
464+
expect.objectContaining({
465+
path: '.',
466+
}),
467+
expect.objectContaining({
468+
path: join('@scope1', 'package1'),
469+
}),
470+
],
471+
},
472+
{
473+
version: '^2.0.0',
474+
packages: [
475+
expect.objectContaining({
476+
path: join('@scope1', 'package2'),
477+
}),
478+
],
479+
},
480+
],
481+
},
482+
{
483+
dependency: 'one.two.three',
484+
versions: [
485+
{
486+
version: '^4.0.0',
487+
packages: [
488+
expect.objectContaining({
489+
path: join('@scope1', 'package2'),
490+
}),
491+
],
492+
},
493+
{
494+
version: '^4.1.0',
495+
packages: [
496+
expect.objectContaining({
497+
path: join('@scope1', 'package1'),
498+
}),
499+
],
500+
},
501+
],
502+
},
503+
]);
415504

416505
// Existing newline at end of file should be maintained.
417506
expect(packageJson1Contents).not.toMatch(/\n$/); // package1 should not end in newline

test/lib/output-test.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import {
22
calculateVersionsForEachDependency,
33
calculateMismatchingVersions,
44
} from '../../lib/dependency-versions.js';
5-
import { mismatchingVersionsToOutput } from '../../lib/output.js';
5+
import {
6+
mismatchingVersionsToOutput,
7+
mismatchingVersionsFixedToOutput,
8+
} from '../../lib/output.js';
69
import { getPackages } from '../../lib/workspace.js';
710
import {
811
FIXTURE_PATH_TESTING_OUTPUT,
@@ -92,4 +95,38 @@ describe('Utils | output', function () {
9295
);
9396
});
9497
});
98+
99+
describe('#mismatchingVersionsFixedToOutputLines', function () {
100+
it('behaves correctly', function () {
101+
expect(
102+
mismatchingVersionsFixedToOutput(
103+
calculateMismatchingVersions(
104+
calculateVersionsForEachDependency(
105+
getPackages(FIXTURE_PATH_TESTING_OUTPUT, [], [], [], [])
106+
)
107+
)
108+
)
109+
).toMatchInlineSnapshot(
110+
'"Fixed versions for 4 dependencies: bar, baz, biz, foo"'
111+
);
112+
});
113+
114+
it('behaves correctly with a single fix', function () {
115+
expect(
116+
mismatchingVersionsFixedToOutput(
117+
calculateMismatchingVersions(
118+
calculateVersionsForEachDependency(
119+
getPackages(FIXTURE_PATH_TESTING_OUTPUT, [], [], [], [])
120+
)
121+
).slice(0, 1)
122+
)
123+
).toMatchInlineSnapshot('"Fixed versions for 1 dependency: bar"');
124+
});
125+
126+
it('behaves correctly with empty input', function () {
127+
expect(() =>
128+
mismatchingVersionsFixedToOutput([])
129+
).toThrowErrorMatchingInlineSnapshot('"No fixes to output."');
130+
});
131+
});
95132
});

0 commit comments

Comments
 (0)