Skip to content

Commit e4f1b7f

Browse files
authored
Add optionalDependencies option to --dep-type (#606)
1 parent be03487 commit e4f1b7f

File tree

7 files changed

+204
-3
lines changed

7 files changed

+204
-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`, `peerDependencies` (optional), `resolutions`) (default: `dependencies`, `devDependencies`, `resolutions`) (option can be repeated). |
119+
| `--dep-type` | Type of dependency to check (`dependencies`, `devDependencies`, `optionalDependencies` (optional), `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: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export function calculateVersionsForEachDependency(
5959
return dependenciesToVersionsSeen;
6060
}
6161

62+
// eslint-disable-next-line complexity
6263
function recordDependencyVersionsForPackageJson(
6364
dependenciesToVersionsSeen: DependenciesToVersionsSeen,
6465
package_: Package,
@@ -110,6 +111,24 @@ function recordDependencyVersionsForPackageJson(
110111
}
111112
}
112113

114+
if (
115+
depType.includes(DEPENDENCY_TYPE.optionalDependencies) &&
116+
package_.packageJson.optionalDependencies
117+
) {
118+
for (const [dependency, dependencyVersion] of Object.entries(
119+
package_.packageJson.optionalDependencies
120+
)) {
121+
if (dependencyVersion) {
122+
recordDependencyVersion(
123+
dependenciesToVersionsSeen,
124+
dependency,
125+
dependencyVersion,
126+
package_
127+
);
128+
}
129+
}
130+
}
131+
113132
if (
114133
depType.includes(DEPENDENCY_TYPE.peerDependencies) &&
115134
package_.packageJson.peerDependencies
@@ -406,6 +425,27 @@ export function fixVersionsMismatching(
406425
isFixed = true;
407426
}
408427

428+
if (
429+
package_.packageJson.optionalDependencies &&
430+
package_.packageJson.optionalDependencies[
431+
mismatchingVersion.dependency
432+
] &&
433+
package_.packageJson.optionalDependencies[
434+
mismatchingVersion.dependency
435+
] !== fixedVersion
436+
) {
437+
if (!dryrun) {
438+
writeDependencyVersion(
439+
package_.pathPackageJson,
440+
package_.packageJsonEndsInNewline,
441+
DEPENDENCY_TYPE.optionalDependencies,
442+
mismatchingVersion.dependency,
443+
fixedVersion
444+
);
445+
}
446+
isFixed = true;
447+
}
448+
409449
if (
410450
package_.packageJson.peerDependencies &&
411451
package_.packageJson.peerDependencies[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+
'optionalDependencies' = 'optionalDependencies',
1920
'peerDependencies' = 'peerDependencies',
2021
'resolutions' = 'resolutions',
21-
// TODO: `optionalDependencies`
2222
}
2323

2424
export type Options = {

test/fixtures/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ export const FIXTURE_PATH_PEER_DEPENDENCIES = join(
8282
FIXTURE_PATH,
8383
'peer-dependencies'
8484
);
85+
export const FIXTURE_PATH_OPTIONAL_DEPENDENCIES = join(
86+
FIXTURE_PATH,
87+
'optional-dependencies'
88+
);
8589

8690
export const FIXTURE_PATH_ALL_VERSION_TYPES = join(
8791
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+
"optionalDependencies": {
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: 139 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_OPTIONAL_DEPENDENCIES,
34
FIXTURE_PATH_PEER_DEPENDENCIES,
45
FIXTURE_PATH_RESOLUTIONS,
56
FIXTURE_PATH_VALID,
@@ -253,6 +254,143 @@ describe('CDVC', function () {
253254
});
254255
});
255256

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

0 commit comments

Comments
 (0)