diff --git a/src/report/dot.template.hbs b/src/report/dot.template.hbs index a093d7f6c..5f14aafbe 100644 --- a/src/report/dot.template.hbs +++ b/src/report/dot.template.hbs @@ -11,7 +11,7 @@ digraph "dependency-cruiser output"{ edge [color=black arrowhead=normal fontname="Helvetica" fontsize="9"] {{#each things}} - {{#if folder}}{{#each path}}subgraph "cluster_{{{.}}}" {label="{{{.}}}" style="rounded" {{/each}}"{{{source}}}" [label="{{{label}}}"]{{#each path}} }{{/each}} + {{#if folder}}{{#each path}}subgraph "cluster_{{{aggregateDir}}}" {label="{{{dir}}}" style="rounded" {{/each}}"{{{source}}}" [label="{{{label}}}"]{{#each path}} }{{/each}} {{else~}} "{{{source}}}" {{/if}} diff --git a/src/report/dot.template.js b/src/report/dot.template.js index 6de181ce3..f2165a58e 100644 --- a/src/report/dot.template.js +++ b/src/report/dot.template.js @@ -16,12 +16,12 @@ templates['dot.template.hbs'] = template({"1":function(container,depth0,helpers, + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.path : depth0),{"name":"each","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "\n"; },"3":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.lambda; + var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function"; return "subgraph \"cluster_" - + ((stack1 = alias1(depth0, depth0)) != null ? stack1 : "") + + ((stack1 = ((helper = (helper = helpers.aggregateDir || (depth0 != null ? depth0.aggregateDir : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"aggregateDir","hash":{},"data":data}) : helper))) != null ? stack1 : "") + "\" {label=\"" - + ((stack1 = alias1(depth0, depth0)) != null ? stack1 : "") + + ((stack1 = ((helper = (helper = helpers.dir || (depth0 != null ? depth0.dir : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"dir","hash":{},"data":data}) : helper))) != null ? stack1 : "") + "\" style=\"rounded\" "; },"5":function(container,depth0,helpers,partials,data) { return " }"; diff --git a/src/report/dotReporter.js b/src/report/dotReporter.js index 91f312057..f9938c6d3 100644 --- a/src/report/dotReporter.js +++ b/src/report/dotReporter.js @@ -5,22 +5,26 @@ const Handlebars = require("handlebars/dist/cjs/handlebars.runtime"); require("./dot.template"); -Handlebars.registerPartial( - 'dot.template.hbs', - Handlebars.templates['dot.template.hbs'] -); - function compareOnSource(pOne, pTwo) { return pOne.source > pTwo.source ? 1 : -1; } +let toFullPath = (pAll, pCurrent) => `${pAll}${path.sep}${pCurrent}`; + +function agg (pFolder, i, ary){ + return { + dir: pFolder, + aggregateDir: `${ary.slice(0, i).reduce(toFullPath, '')}${path.sep}${pFolder}` + }; +} + function folderify(pDependencyItem) { let lAdditions = {}; let lDirName = path.dirname(pDependencyItem.source); if (lDirName !== ".") { lAdditions.folder = lDirName; - lAdditions.path = lDirName.split(path.sep); + lAdditions.path = lDirName.split(path.sep).map(agg); } lAdditions.label = path.basename(pDependencyItem.source); diff --git a/test/cli.index.spec.js b/test/cli.index.spec.js index 96ffd84be..7ee5fd2c5 100644 --- a/test/cli.index.spec.js +++ b/test/cli.index.spec.js @@ -73,6 +73,17 @@ const testPairs = [ expect: "{{moduleType}}.dir.filtered.dot", cleanup: true }, + { + description: "dot - duplicate subs", + dirOrFile: "test/fixtures/duplicate-subs", + options: { + outputTo: path.join(OUT_DIR, "duplicate-subs.dot"), + outputType: "dot", + exclude: "node_modules" + }, + expect: "duplicate-subs.dot", + cleanup: true + }, { description: "csv", dirOrFile: "test/fixtures/{{moduleType}}", diff --git a/test/fixtures/cjs.dir.filtered.dot b/test/fixtures/cjs.dir.filtered.dot index 08af52e23..43d90a4f1 100644 --- a/test/fixtures/cjs.dir.filtered.dot +++ b/test/fixtures/cjs.dir.filtered.dot @@ -10,14 +10,14 @@ digraph "dependency-cruiser output"{ node [shape=box style="rounded, filled" fillcolor="#ffffcc" height=0.2 fontname=Helvetica fontsize=9] edge [color=black arrowhead=normal fontname="Helvetica" fontsize="9"] - subgraph "cluster_test" {label="test" style="rounded" subgraph "cluster_fixtures" {label="fixtures" style="rounded" subgraph "cluster_cjs" {label="cjs" style="rounded" "test/fixtures/cjs/one_only_one.js" [label="one_only_one.js"] } } } - subgraph "cluster_test" {label="test" style="rounded" subgraph "cluster_fixtures" {label="fixtures" style="rounded" subgraph "cluster_cjs" {label="cjs" style="rounded" "test/fixtures/cjs/one_only_two.js" [label="one_only_two.js"] } } } - subgraph "cluster_test" {label="test" style="rounded" subgraph "cluster_fixtures" {label="fixtures" style="rounded" subgraph "cluster_cjs" {label="cjs" style="rounded" "test/fixtures/cjs/root_one.js" [label="root_one.js"] } } } - subgraph "cluster_test" {label="test" style="rounded" subgraph "cluster_fixtures" {label="fixtures" style="rounded" subgraph "cluster_cjs" {label="cjs" style="rounded" "test/fixtures/cjs/root_two.js" [label="root_two.js"] } } } - subgraph "cluster_test" {label="test" style="rounded" subgraph "cluster_fixtures" {label="fixtures" style="rounded" subgraph "cluster_cjs" {label="cjs" style="rounded" "test/fixtures/cjs/shared.js" [label="shared.js"] } } } - subgraph "cluster_test" {label="test" style="rounded" subgraph "cluster_fixtures" {label="fixtures" style="rounded" subgraph "cluster_cjs" {label="cjs" style="rounded" subgraph "cluster_sub" {label="sub" style="rounded" "test/fixtures/cjs/sub/depindir.js" [label="depindir.js"] } } } } - subgraph "cluster_test" {label="test" style="rounded" subgraph "cluster_fixtures" {label="fixtures" style="rounded" subgraph "cluster_cjs" {label="cjs" style="rounded" subgraph "cluster_sub" {label="sub" style="rounded" "test/fixtures/cjs/sub/dir.js" [label="dir.js"] } } } } - subgraph "cluster_test" {label="test" style="rounded" subgraph "cluster_fixtures" {label="fixtures" style="rounded" subgraph "cluster_cjs" {label="cjs" style="rounded" "test/fixtures/cjs/two_only_one.js" [label="two_only_one.js"] } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/cjs" {label="cjs" style="rounded" "test/fixtures/cjs/one_only_one.js" [label="one_only_one.js"] } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/cjs" {label="cjs" style="rounded" "test/fixtures/cjs/one_only_two.js" [label="one_only_two.js"] } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/cjs" {label="cjs" style="rounded" "test/fixtures/cjs/root_one.js" [label="root_one.js"] } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/cjs" {label="cjs" style="rounded" "test/fixtures/cjs/root_two.js" [label="root_two.js"] } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/cjs" {label="cjs" style="rounded" "test/fixtures/cjs/shared.js" [label="shared.js"] } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/cjs" {label="cjs" style="rounded" subgraph "cluster_/test/fixtures/cjs/sub" {label="sub" style="rounded" "test/fixtures/cjs/sub/depindir.js" [label="depindir.js"] } } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/cjs" {label="cjs" style="rounded" subgraph "cluster_/test/fixtures/cjs/sub" {label="sub" style="rounded" "test/fixtures/cjs/sub/dir.js" [label="dir.js"] } } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/cjs" {label="cjs" style="rounded" "test/fixtures/cjs/two_only_one.js" [label="two_only_one.js"] } } } "test/fixtures/cjs/one_only_one.js" -> "path" [color="grey"] "test/fixtures/cjs/one_only_two.js" -> "path" [color="grey"] diff --git a/test/fixtures/duplicate-subs.dot b/test/fixtures/duplicate-subs.dot new file mode 100644 index 000000000..148c3450f --- /dev/null +++ b/test/fixtures/duplicate-subs.dot @@ -0,0 +1,24 @@ +digraph "dependency-cruiser output"{ + ordering=out + rankdir=LR + splines=true + overlap=false + nodesep=0.16 + fontname="Helvetica" + fontsize="9" + compound=true + node [shape=box style="rounded, filled" fillcolor="#ffffcc" height=0.2 fontname=Helvetica fontsize=9] + edge [color=black arrowhead=normal fontname="Helvetica" fontsize="9"] + + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs" {label="duplicate-subs" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs/nested-sub" {label="nested-sub" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs/nested-sub/sub" {label="sub" style="rounded" "test/fixtures/duplicate-subs/nested-sub/sub/index.js" [label="index.js"] } } } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs" {label="duplicate-subs" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs/nested-sub" {label="nested-sub" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs/nested-sub/sub" {label="sub" style="rounded" "test/fixtures/duplicate-subs/nested-sub/sub/sub.js" [label="sub.js"] } } } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs" {label="duplicate-subs" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs/nested-sub" {label="nested-sub" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs/nested-sub/sub" {label="sub" style="rounded" "test/fixtures/duplicate-subs/nested-sub/sub/wakka.js" [label="wakka.js"] } } } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs" {label="duplicate-subs" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs/sub" {label="sub" style="rounded" "test/fixtures/duplicate-subs/sub/index.js" [label="index.js"] } } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs" {label="duplicate-subs" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs/sub" {label="sub" style="rounded" "test/fixtures/duplicate-subs/sub/more-in-sub.js" [label="more-in-sub.js"] } } } } + subgraph "cluster_/test" {label="test" style="rounded" subgraph "cluster_/test/fixtures" {label="fixtures" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs" {label="duplicate-subs" style="rounded" subgraph "cluster_/test/fixtures/duplicate-subs/sub" {label="sub" style="rounded" "test/fixtures/duplicate-subs/sub/most-in-sub.js" [label="most-in-sub.js"] } } } } + + "test/fixtures/duplicate-subs/nested-sub/sub/index.js" -> "test/fixtures/duplicate-subs/nested-sub/sub/sub.js" + "test/fixtures/duplicate-subs/nested-sub/sub/index.js" -> "test/fixtures/duplicate-subs/nested-sub/sub/wakka.js" + "test/fixtures/duplicate-subs/nested-sub/sub/sub.js" -> "test/fixtures/duplicate-subs/nested-sub/sub/wakka.js" + "test/fixtures/duplicate-subs/sub/index.js" -> "test/fixtures/duplicate-subs/nested-sub/sub/index.js" +} diff --git a/test/fixtures/duplicate-subs/nested-sub/sub/index.js b/test/fixtures/duplicate-subs/nested-sub/sub/index.js new file mode 100644 index 000000000..9cecafd30 --- /dev/null +++ b/test/fixtures/duplicate-subs/nested-sub/sub/index.js @@ -0,0 +1,4 @@ +const wakka = require('./wakka'); +const sub = require('./sub'); + +console.log('yo from nested-sub/sub'); diff --git a/test/fixtures/duplicate-subs/nested-sub/sub/sub.js b/test/fixtures/duplicate-subs/nested-sub/sub/sub.js new file mode 100644 index 000000000..d7dbc31ee --- /dev/null +++ b/test/fixtures/duplicate-subs/nested-sub/sub/sub.js @@ -0,0 +1 @@ +let sub = require('./wakka'); diff --git a/test/fixtures/duplicate-subs/nested-sub/sub/wakka.js b/test/fixtures/duplicate-subs/nested-sub/sub/wakka.js new file mode 100644 index 000000000..6c54cf471 --- /dev/null +++ b/test/fixtures/duplicate-subs/nested-sub/sub/wakka.js @@ -0,0 +1 @@ +exports.yo = () => 'nothing, really'; diff --git a/test/fixtures/duplicate-subs/sub/index.js b/test/fixtures/duplicate-subs/sub/index.js new file mode 100644 index 000000000..dcfbbd830 --- /dev/null +++ b/test/fixtures/duplicate-subs/sub/index.js @@ -0,0 +1,2 @@ +const sub = require('../nested-sub/sub'); +console.log('yo from sub'); diff --git a/test/fixtures/duplicate-subs/sub/more-in-sub.js b/test/fixtures/duplicate-subs/sub/more-in-sub.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/duplicate-subs/sub/most-in-sub.js b/test/fixtures/duplicate-subs/sub/most-in-sub.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/report.dotReporter.spec.js b/test/report.dotReporter.spec.js index d1fe69806..008a44013 100644 --- a/test/report.dotReporter.spec.js +++ b/test/report.dotReporter.spec.js @@ -15,16 +15,16 @@ const elFixture = `digraph "dependency-cruiser output"{ node [shape=box style="rounded, filled" fillcolor="#ffffcc" height=0.2 fontname=Helvetica fontsize=9] edge [color=black arrowhead=normal fontname="Helvetica" fontsize="9"] - subgraph "cluster_node_modules" {label="node_modules" style="rounded" subgraph "cluster_somemodule" {label="somemodule" style="rounded" subgraph "cluster_node_modules" {label="node_modules" style="rounded" subgraph "cluster_someothermodule" {label="someothermodule" style="rounded" "node_modules/somemodule/node_modules/someothermodule/main.js" [label="main.js"] } } } } - subgraph "cluster_node_modules" {label="node_modules" style="rounded" subgraph "cluster_somemodule" {label="somemodule" style="rounded" subgraph "cluster_src" {label="src" style="rounded" "node_modules/somemodule/src/moar-javascript.js" [label="moar-javascript.js"] } } } - subgraph "cluster_node_modules" {label="node_modules" style="rounded" subgraph "cluster_somemodule" {label="somemodule" style="rounded" subgraph "cluster_src" {label="src" style="rounded" "node_modules/somemodule/src/somemodule.js" [label="somemodule.js"] } } } + subgraph "cluster_/node_modules" {label="node_modules" style="rounded" subgraph "cluster_/node_modules/somemodule" {label="somemodule" style="rounded" subgraph "cluster_/node_modules/somemodule/node_modules" {label="node_modules" style="rounded" subgraph "cluster_/node_modules/somemodule/node_modules/someothermodule" {label="someothermodule" style="rounded" "node_modules/somemodule/node_modules/someothermodule/main.js" [label="main.js"] } } } } + subgraph "cluster_/node_modules" {label="node_modules" style="rounded" subgraph "cluster_/node_modules/somemodule" {label="somemodule" style="rounded" subgraph "cluster_/node_modules/somemodule/src" {label="src" style="rounded" "node_modules/somemodule/src/moar-javascript.js" [label="moar-javascript.js"] } } } + subgraph "cluster_/node_modules" {label="node_modules" style="rounded" subgraph "cluster_/node_modules/somemodule" {label="somemodule" style="rounded" subgraph "cluster_/node_modules/somemodule/src" {label="src" style="rounded" "node_modules/somemodule/src/somemodule.js" [label="somemodule.js"] } } } "one_only_one.js" "one_only_two.js" "root_one.js" "root_two.js" "shared.js" - subgraph "cluster_sub" {label="sub" style="rounded" "sub/depindir.js" [label="depindir.js"] } - subgraph "cluster_sub" {label="sub" style="rounded" "sub/dir.js" [label="dir.js"] } + subgraph "cluster_/sub" {label="sub" style="rounded" "sub/depindir.js" [label="depindir.js"] } + subgraph "cluster_/sub" {label="sub" style="rounded" "sub/dir.js" [label="dir.js"] } "two_only_one.js" "node_modules/somemodule/src/somemodule.js" -> "node_modules/somemodule/src/moar-javascript.js" [color="red" penwidth=2.0]