dependency-cruiser icon indicating copy to clipboard operation
dependency-cruiser copied to clipboard

Feature request: Show only dependency cycles

Open crystalfp opened this issue 10 months ago • 3 comments

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:

Image

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

crystalfp avatar Feb 24 '25 15:02 crystalfp

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-html reporter shows the cycles slightly more clear (see below). Just like the default err reporter 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

Image

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
Image

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 avatar Mar 29 '25 12:03 sverweij

@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.

denishsharma avatar Jun 04 '25 07:06 denishsharma

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:

Image

sverweij avatar Jun 10 '25 20:06 sverweij