Skip to content

Commit be03487

Browse files
authored
Add peerDependencies option to --dep-type (#601)
1 parent 5cf0673 commit be03487

File tree

7 files changed

+201
-3
lines changed

7 files changed

+201
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ These options are available on the CLI and as parameters to the [Node API](#node
116116

117117
| Name | Description |
118118
| :-- | :-- |
119-
| `--dep-type` | Type of dependency to check (`dependencies`, `devDependencies`, `resolutions`) (default: `dependencies`, `devDependencies`, `resolutions`) (option can be repeated). |
119+
| `--dep-type` | Type of dependency to check (`dependencies`, `devDependencies`, `peerDependencies` (optional), `resolutions`) (default: `dependencies`, `devDependencies`, `resolutions`) (option can be repeated). |
120120
| `--fix` | Whether to autofix inconsistencies (using latest version present). |
121121
| `--ignore-dep` | Dependency to ignore mismatches for (option can be repeated). |
122122
| `--ignore-dep-pattern` | RegExp of dependency names to ignore mismatches for (option can be repeated). |

lib/dependency-versions.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,24 @@ function recordDependencyVersionsForPackageJson(
110110
}
111111
}
112112

113+
if (
114+
depType.includes(DEPENDENCY_TYPE.peerDependencies) &&
115+
package_.packageJson.peerDependencies
116+
) {
117+
for (const [dependency, dependencyVersion] of Object.entries(
118+
package_.packageJson.peerDependencies
119+
)) {
120+
if (dependencyVersion) {
121+
recordDependencyVersion(
122+
dependenciesToVersionsSeen,
123+
dependency,
124+
dependencyVersion,
125+
package_
126+
);
127+
}
128+
}
129+
}
130+
113131
if (
114132
depType.includes(DEPENDENCY_TYPE.resolutions) &&
115133
package_.packageJson.resolutions
@@ -388,6 +406,24 @@ export function fixVersionsMismatching(
388406
isFixed = true;
389407
}
390408

409+
if (
410+
package_.packageJson.peerDependencies &&
411+
package_.packageJson.peerDependencies[mismatchingVersion.dependency] &&
412+
package_.packageJson.peerDependencies[mismatchingVersion.dependency] !==
413+
fixedVersion
414+
) {
415+
if (!dryrun) {
416+
writeDependencyVersion(
417+
package_.pathPackageJson,
418+
package_.packageJsonEndsInNewline,
419+
DEPENDENCY_TYPE.peerDependencies,
420+
mismatchingVersion.dependency,
421+
fixedVersion
422+
);
423+
}
424+
isFixed = true;
425+
}
426+
391427
if (
392428
package_.packageJson.resolutions &&
393429
package_.packageJson.resolutions[mismatchingVersion.dependency] &&

lib/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ export type Dependencies = Record<
1616
export enum DEPENDENCY_TYPE {
1717
'dependencies' = 'dependencies',
1818
'devDependencies' = 'devDependencies',
19+
'peerDependencies' = 'peerDependencies',
1920
'resolutions' = 'resolutions',
2021
// TODO: `optionalDependencies`
21-
// TODO: `peerDependencies`
2222
}
2323

2424
export type Options = {

test/fixtures/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ export const FIXTURE_PATH_NESTED_WORKSPACES = join(
7878
'nested-workspaces'
7979
);
8080
export const FIXTURE_PATH_RESOLUTIONS = join(FIXTURE_PATH, 'resolutions');
81+
export const FIXTURE_PATH_PEER_DEPENDENCIES = join(
82+
FIXTURE_PATH,
83+
'peer-dependencies'
84+
);
8185

8286
export const FIXTURE_PATH_ALL_VERSION_TYPES = join(
8387
FIXTURE_PATH,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"workspaces": [
3+
"*"
4+
],
5+
"devDependencies": {
6+
"foo": "^1.2.0"
7+
},
8+
"peerDependencies": {
9+
"foo": "^2.0.0",
10+
"bar": "^1.0.0"
11+
}
12+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "package1",
3+
"dependencies": {
4+
"foo": "1.3.0",
5+
"bar": "^1.0.0"
6+
}
7+
}

test/lib/cdvc-test.ts

Lines changed: 140 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
FIXTURE_PATH_INCONSISTENT_VERSIONS,
3+
FIXTURE_PATH_PEER_DEPENDENCIES,
34
FIXTURE_PATH_RESOLUTIONS,
45
FIXTURE_PATH_VALID,
56
} from '../fixtures/index.js';
@@ -8,6 +9,7 @@ import mockFs from 'mock-fs';
89
import { readFileSync } from 'node:fs';
910
import type { PackageJson } from 'type-fest';
1011
import path from 'node:path';
12+
import { DEPENDENCY_TYPE } from '../../lib/types.js';
1113

1214
describe('CDVC', function () {
1315
describe('valid fixture', function () {
@@ -251,6 +253,143 @@ describe('CDVC', function () {
251253
});
252254
});
253255

256+
describe('peer dependencies', function () {
257+
it('behaves correctly', function () {
258+
const cdvc = new CDVC(FIXTURE_PATH_PEER_DEPENDENCIES, {
259+
depType: ['peerDependencies'],
260+
});
261+
const dependencies = cdvc.getDependencies();
262+
263+
expect(cdvc.hasMismatchingDependencies).toBe(false);
264+
expect(cdvc.hasMismatchingDependenciesFixable).toBe(false);
265+
expect(cdvc.hasMismatchingDependenciesNotFixable).toBe(false);
266+
expect(dependencies).toStrictEqual([
267+
{
268+
isFixable: false,
269+
isMismatching: false,
270+
name: 'bar',
271+
versions: [
272+
{
273+
packages: [''],
274+
version: '^1.0.0',
275+
},
276+
],
277+
},
278+
{
279+
isFixable: false,
280+
isMismatching: false,
281+
name: 'foo',
282+
versions: [
283+
{
284+
packages: [''],
285+
version: '^2.0.0',
286+
},
287+
],
288+
},
289+
]);
290+
});
291+
292+
describe('mock fs', function () {
293+
beforeEach(function () {
294+
// Create a mock workspace filesystem for temporary usage in this test because changes will be written to some files.
295+
mockFs({
296+
'package.json': JSON.stringify({
297+
workspaces: ['*'],
298+
devDependencies: {
299+
foo: '^1.2.0',
300+
},
301+
peerDependencies: {
302+
foo: '^1.0.0',
303+
bar: '^1.0.0',
304+
},
305+
}),
306+
package1: {
307+
'package.json': JSON.stringify({
308+
name: 'package1',
309+
dependencies: {
310+
foo: '^2.0.0',
311+
bar: '^1.0.0',
312+
},
313+
}),
314+
},
315+
});
316+
});
317+
318+
afterEach(function () {
319+
mockFs.restore();
320+
});
321+
322+
it('fixes the fixable inconsistencies', function () {
323+
const cdvc = new CDVC('.', {
324+
fix: true,
325+
depType: [
326+
DEPENDENCY_TYPE.peerDependencies,
327+
DEPENDENCY_TYPE.devDependencies,
328+
DEPENDENCY_TYPE.dependencies,
329+
],
330+
});
331+
332+
// Read in package.json files.
333+
const packageJsonRootContents = readFileSync('package.json', 'utf8');
334+
const packageJson1Contents = readFileSync(
335+
'package1/package.json',
336+
'utf8'
337+
);
338+
const packageJsonRoot = JSON.parse(
339+
packageJsonRootContents
340+
) as PackageJson;
341+
const packageJson1 = JSON.parse(packageJson1Contents) as PackageJson;
342+
343+
expect(
344+
packageJsonRoot.devDependencies &&
345+
packageJsonRoot.devDependencies['foo']
346+
).toStrictEqual('^2.0.0');
347+
348+
expect(
349+
packageJsonRoot.peerDependencies &&
350+
packageJsonRoot.peerDependencies['foo']
351+
).toStrictEqual('^2.0.0');
352+
353+
expect(
354+
packageJson1.dependencies && packageJson1.dependencies['foo']
355+
).toStrictEqual('^2.0.0');
356+
357+
expect(cdvc.getDependencies()).toStrictEqual([
358+
{
359+
name: 'bar',
360+
isFixable: false,
361+
isMismatching: false,
362+
versions: [
363+
{
364+
version: '^1.0.0',
365+
packages: ['', 'package1'],
366+
},
367+
],
368+
},
369+
{
370+
name: 'foo',
371+
isFixable: true,
372+
isMismatching: true,
373+
versions: [
374+
{
375+
version: '^1.0.0',
376+
packages: [''],
377+
},
378+
{
379+
version: '^1.2.0',
380+
packages: [''],
381+
},
382+
{
383+
version: '^2.0.0',
384+
packages: ['package1'],
385+
},
386+
],
387+
},
388+
]);
389+
});
390+
});
391+
});
392+
254393
describe('resolutions', () => {
255394
it('behaves correctly', function () {
256395
const cdvc = new CDVC(FIXTURE_PATH_RESOLUTIONS, {
@@ -297,7 +436,7 @@ describe('CDVC', function () {
297436
depType: ['fake'],
298437
})
299438
).toThrowErrorMatchingInlineSnapshot(
300-
'"Invalid depType provided. Choices are: dependencies, devDependencies, resolutions."'
439+
'"Invalid depType provided. Choices are: dependencies, devDependencies, peerDependencies, resolutions."'
301440
);
302441
});
303442
});

0 commit comments

Comments
 (0)