Skip to content

Commit 3481154

Browse files
committed
[FIX] npm translator: Remove deduped optional dependencies from tree
In some cases optional (pending) dependencies that have been deduped have not been removed from the dependency tree, no matter whether the "includeDeduped" flag was set or not.
1 parent 4d8527a commit 3481154

File tree

2 files changed

+99
-5
lines changed

2 files changed

+99
-5
lines changed

lib/translators/npm.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,12 @@ class NpmTranslator {
461461
`(child of ${parent.id})`);
462462

463463
const idx = parent.dependencies.indexOf(project);
464-
const dedupedProject = this.createDedupedProject(project);
465-
parent.dependencies.splice(idx, 1, dedupedProject);
464+
if (this.includeDeduped) {
465+
const dedupedProject = this.createDedupedProject(project);
466+
parent.dependencies.splice(idx, 1, dedupedProject);
467+
} else {
468+
parent.dependencies.splice(idx, 1);
469+
}
466470
}
467471

468472
if (project.dependencies) {

test/lib/translators/npm.js

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ test("AppG: project with npm 'optionalDependencies' should not fail if optional
5959
test("AppCycleA: cyclic dev deps", (t) => {
6060
const applicationCycleAPath = path.join(cycleDepsBasePath, "application.cycle.a");
6161

62-
return npmTranslator.generateDependencyTree(applicationCycleAPath, {includeDeduped: false}).then((parsedTree) => {
62+
return npmTranslator.generateDependencyTree(applicationCycleAPath).then((parsedTree) => {
6363
t.deepEqual(parsedTree, applicationCycleATree, "Parsed correctly");
6464
});
6565
});
@@ -72,9 +72,16 @@ test("AppCycleA: cyclic dev deps - include deduped", (t) => {
7272
});
7373
});
7474

75+
test("AppCycleB: cyclic npm deps - Cycle via devDependency on second level - include deduped", (t) => {
76+
const applicationCycleBPath = path.join(cycleDepsBasePath, "application.cycle.b");
77+
return npmTranslator.generateDependencyTree(applicationCycleBPath, {includeDeduped: true}).then((parsedTree) => {
78+
t.deepEqual(parsedTree, applicationCycleBTreeIncDeduped, "Parsed correctly");
79+
});
80+
});
81+
7582
test("AppCycleB: cyclic npm deps - Cycle via devDependency on second level", (t) => {
7683
const applicationCycleBPath = path.join(cycleDepsBasePath, "application.cycle.b");
77-
return npmTranslator.generateDependencyTree(applicationCycleBPath).then((parsedTree) => {
84+
return npmTranslator.generateDependencyTree(applicationCycleBPath, {includeDeduped: false}).then((parsedTree) => {
7885
t.deepEqual(parsedTree, applicationCycleBTree, "Parsed correctly");
7986
});
8087
});
@@ -100,9 +107,16 @@ test("AppCycleD: cyclic npm deps - Cycles everywhere", (t) => {
100107
});
101108
});
102109

103-
test("AppCycleE: cyclic npm deps - Cycle via devDependency", (t) => {
110+
test("AppCycleE: cyclic npm deps - Cycle via devDependency - include deduped", (t) => {
104111
const applicationCycleEPath = path.join(cycleDepsBasePath, "application.cycle.e");
105112
return npmTranslator.generateDependencyTree(applicationCycleEPath, {includeDeduped: true}).then((parsedTree) => {
113+
t.deepEqual(parsedTree, applicationCycleETreeIncDeduped, "Parsed correctly");
114+
});
115+
});
116+
117+
test("AppCycleE: cyclic npm deps - Cycle via devDependency", (t) => {
118+
const applicationCycleEPath = path.join(cycleDepsBasePath, "application.cycle.e");
119+
return npmTranslator.generateDependencyTree(applicationCycleEPath, {includeDeduped: false}).then((parsedTree) => {
106120
t.deepEqual(parsedTree, applicationCycleETree, "Parsed correctly");
107121
});
108122
});
@@ -394,6 +408,48 @@ const applicationCycleBTree = {
394408
}
395409
]
396410
},
411+
{
412+
"id": "module.e",
413+
"version": "1.0.0",
414+
"path": path.join(cycleDepsBasePath, "module.e"),
415+
"dependencies": [
416+
{
417+
"id": "module.d",
418+
"version": "1.0.0",
419+
"path": path.join(cycleDepsBasePath, "module.d"),
420+
"dependencies": []
421+
}
422+
]
423+
}
424+
]
425+
};
426+
427+
const applicationCycleBTreeIncDeduped = {
428+
"id": "application.cycle.b",
429+
"version": "1.0.0",
430+
"path": path.join(cycleDepsBasePath, "application.cycle.b"),
431+
"dependencies": [
432+
{
433+
"id": "module.d",
434+
"version": "1.0.0",
435+
"path": path.join(cycleDepsBasePath, "module.d"),
436+
"dependencies": [
437+
{
438+
"id": "module.e",
439+
"version": "1.0.0",
440+
"path": path.join(cycleDepsBasePath, "module.e"),
441+
"dependencies": [
442+
{
443+
"id": "module.d",
444+
"version": "1.0.0",
445+
"path": path.join(cycleDepsBasePath, "module.d"),
446+
"dependencies": [],
447+
"deduped": true
448+
}
449+
]
450+
}
451+
]
452+
},
397453
{
398454
"id": "module.e",
399455
"version": "1.0.0",
@@ -860,6 +916,40 @@ const applicationCycleDTree = {
860916
};
861917

862918
const applicationCycleETree = {
919+
"id": "application.cycle.e",
920+
"version": "1.0.0",
921+
"path": path.join(cycleDepsBasePath, "application.cycle.e"),
922+
"dependencies": [
923+
{
924+
"id": "module.l",
925+
"version": "1.0.0",
926+
"path": path.join(cycleDepsBasePath, "module.l"),
927+
"dependencies": [
928+
{
929+
"id": "module.m",
930+
"version": "1.0.0",
931+
"path": path.join(cycleDepsBasePath, "module.m"),
932+
"dependencies": []
933+
}
934+
]
935+
},
936+
{
937+
"id": "module.m",
938+
"version": "1.0.0",
939+
"path": path.join(cycleDepsBasePath, "module.m"),
940+
"dependencies": [
941+
{
942+
"id": "module.l",
943+
"version": "1.0.0",
944+
"path": path.join(cycleDepsBasePath, "module.l"),
945+
"dependencies": []
946+
}
947+
]
948+
}
949+
]
950+
};
951+
952+
const applicationCycleETreeIncDeduped = {
863953
"id": "application.cycle.e",
864954
"version": "1.0.0",
865955
"path": path.join(cycleDepsBasePath, "application.cycle.e"),

0 commit comments

Comments
 (0)