Feature request: Show only dependency cycles
Context
I need to focus on the cyclic dependencies in a quite complex application. Currently the output of depcruise -T err src show them in textual form, but I think that having them in graphical format is better to find patterns.
Before I was using madge that has options to show graphically only cyclic dependencies (and also orphan modules). Is it possible to have something similar also in depcruise?
Currently I use the following command to have a beautiful chart of dependencies for my application:
depcruise -v -T dot src | dot -T svg | depcruise-wrap-stream-in-html > dependency-graph.html
The application is written in TypeScript + Vue on Windows.
Expected Behavior
Here is an example of cycle chart generated using madge:
I want something similar.
Current Behavior
Maybe the functionality is already there but I was not able to find it.
Possible Solution
Considered alternatives
Currently the only alternative is using depcruise -T err but it is text only or madge --extensions ts,vue --ts-config tsconfig.json -i out.png -c --warning file.vue
Hi @crystalfp thank you for your question and sorry you had to wait so long for an answer - there were some private circumstances that prevented me from answering.
For visualing cycles, apart from what you've already found:
- The
err-htmlreporter shows the cycles slightly more clear (see below). Just like the defaulterrreporter it de-duplicates the cycles - There's some possibilities to format dot reports
- Also - pointing dependency-cruiser at just one module in a cycle (
depcruise -T err-html src/somefolder/thing-in-a-cycle.ts > violations-report.html) will typically show the cycles it's part of (and having a potentially smaller graph).
-> is this what you were looking for?
err-html
# tslint is a project with known circular dependencies
git clone https://github.com/palantir/tslint
cd tslint
depcruise -T err-html src > violations-report.html
configuring the dot reporter
By default dependencies that are part of a cycle get an o next to the arrow - if there's a rule attached the dependencies get the color configured with the severity of the rule (by default red for error, orange for warn, blue for info)
# using the same repo
depcruise -T dot src | dot -T svg | depcruise-wrap-stream-in-html > dependency-graph.html
# or, for short with an experimental reporter that combines both ...
# depcruise -T x-dot-webpage src > dependency-graph.html
This can be customized to one's heart's content - the default theme is probably a good starting point. The attributes and the values for them are passed directly to the graphviz render engine and are documented on their site.
@sverweij I tried the following command, but it also output other nodes and connection, is it possible to only show nodes and connection which are circular? Since I have 300+ files and the output graph is very large and unable to use it properly.
Hi - functionality to only show cycles (or rules, types of dependencies, etc) is not (yet) built into dependency-cruiser. However, via the internal data model it's straightforward to implement with e.g. a jq script (rough sketch below).
# make dependency-cruiser emit the cruise result in json format
npx dependency-cruiser src --output-type json --output-to result.json
# with jq, filter on circular modules (filter_circular_modules.jq below)
jq -f filter_circular_modules.jq result.json > cycles-only-result.json
# use dependency-cruiser's standalone reporter to show only the cycles e.g.
# svg ...
npx depcruise-fmt cycles-only-result.json --output-type dot | dot -T svg > cycles-only-result.svg
# ... or svg embedded on a webpage
npx depcruise-fmt cycles-only-result.json --output-type x-dot-webpage --output-to cycles-only-result.html
☝ no doubt the above can be written as one line by piping the output of steps into the next. Didn't do that as that doesn't explain that nicely.
A first (working) setup of the filter_circular_modules.jq script:
# Extract all module names that participate in circular dependencies
def circular_modules:
[
# Get modules that have circular dependencies
.modules[] | select(.dependencies[]?.circular == true) | .source
] | unique;
# Filter the original JSON to only include circular modules
. as $root |
circular_modules as $circular |
{
modules: [
.modules[] | select(.source as $src | $circular | index($src)) |
# Also filter dependencies within each module to only include circular ones
{
source: .source,
dependencies: [
.dependencies[] | select(
.circular == true or
(.resolved // empty | . as $res | $circular | index($res))
)
],
valid: .valid
}
],
summary: .summary,
revisionData: .revisionData
}
Applied to the tslint repo: