A Gradle Plugin that generates dependency graphs showing the relationship between modules in your project.
The plugin generates a graph visualising the dependencies across the whole project. It also generates sub-graphs for each module within the project. For projects with a large number of modules, I find the sub-graphs tend to be a lot more useful.
The graphs are generated in the mermaid.js
format so they are automatically displayed by Github.
This plugin is a derivation of Jake Wharton's project dependency graph script available here.
The plugin is available in the Gradle plugins repository.
Apply the plugin to your project's root build.gradle.kts
Kotlin:
plugins {
id("io.github.adityabhaskar.dependencygraph") version "<version>"
}
Groovy:
plugins {
id "io.github.adityabhaskar.dependencygraph" version "<version>"
}
See here for applying without the plugins DSL block.
The plugin adds a new Gradle task - dependencyGraph
. Running the task will generate the dependency graphs for all modules in the project.
./gradlew dependencyGraph
Optionally configure the plugin in the same build.gradle.kts
if you want to change the defaults
dependencyGraphConfig {
graphDirection.set(Direction.LeftToRight)
showLegend.set(ShowLegend.OnlyInRootGraph)
ignoreModules.set(listOf(":example:system-test", ":example:test-fixtures"))
repoRootUrl.set("https://github.com/adityabhaskar/Gradle-dependency-graphs")
mainBranchName.set("main")
graphFileName.set("dependencyGraph.md")
}
All configuration options are optional with sensible defaults.
Config option | Type | Default value | Description |
---|---|---|---|
graphDirection |
Direction |
Direction.LeftToRight |
The direction in which the graph should be laid out. Options:
|
showLegend |
ShowLegend |
ShowLegend.OnlyInRootGraph |
Whether to show a legend. When enabled, the graph with contain a legend identifying different types of modules β current/root, java/kotlin, Android and multiplatform β and different type of dependencies - direct, indirect & transitive. Options:
|
graphFileName |
String |
dependencyGraph.md |
Name of the file in which the graph is saved. Note: If the provided filename does not end in .md , then the extension will be appended. |
ignoreModules |
List<String> |
emptyList() |
A list of modules to be ignored when generating the graph. This may be used, for instance to remove system test modules to see only the production graph. Provide the full path of the modules you want to ignore, e.g. :live-feature:ui instead of :test-ui . |
shouldLinkModuleText |
Boolean |
true |
Whether to add sub-graph links to module names in graphs. The links are useful for quickly navigating between graphs and sub-graphs. Note: For links to work repoRootUrl and mainBranchName need to be provided |
repoRootUrl |
String |
"" |
Github URL for your repository. E.g. https://github.com/adityabhaskar/Gradle-dependency-graphs The URL is used for adding links to modules to allow navigation to a module's subgraph just by clicking on it. If no URL is provided, then links are not added to the graph. |
mainBranchName |
String |
main |
Name of your main branch, e.g. master .This is combined with the repoRootUrl to create clickable URLs. The URLs are used for adding links to graph to allow navigation to a module's subgraph by clicking on a module. If no repoRootUrl is provided, then links are not added to the graph. |
The plugin will generate one graph at the root of the project for all modules in the project (except any ignored).
Sample root project graph with a legend:
%%{ init: { 'theme': 'base' } }%%
graph LR;
%% Styling for module nodes by type
classDef rootNode stroke-width:4px;
classDef mppNode fill:#ffd2b3,color:#333333;
classDef andNode fill:#baffc9,color:#333333;
classDef javaNode fill:#ffb3ba,color:#333333;
%% Modules
subgraph
direction LR;
:example:feature{{<a href='https://github.com/adityabhaskar/Gradle-dependency-graphs/blob/main/example/feature/dependencyGraph.md' style='text-decoration:auto'>:example:feature</a>}}:::javaNode;
:example:models{{<a href='https://github.com/adityabhaskar/Gradle-dependency-graphs/blob/main/example/models/dependencyGraph.md' style='text-decoration:auto'>:example:models</a>}}:::javaNode;
:example:ui[<a href='https://github.com/adityabhaskar/Gradle-dependency-graphs/blob/main/example/ui/dependencyGraph.md' style='text-decoration:auto'>:example:ui</a>]:::javaNode;
end
%% Dependencies
:example:ui===>:example:models
%% Dependents
:example:feature-.->:example:ui
Further, the plugin will generate a graph for every module's dependencies within that module's root folder. This graph will include:
- Direct dependents of the module, and
- Direct and indirect dependencies of the module
Dependents are identified with a dashed line.
Sample sub graph for the module :example:domain
without a legend:
%%{ init: { 'theme': 'base' } }%%
graph LR;
%% Styling for module nodes by type
classDef rootNode stroke-width:4px;
classDef mppNode fill:#ffd2b3,color:#333333;
classDef andNode fill:#baffc9,color:#333333;
classDef javaNode fill:#ffb3ba,color:#333333;
%% Modules
subgraph
direction LR;
:example:data{{<a href='https://github.com/adityabhaskar/Gradle-dependency-graphs/blob/main/example/data/dependencyGraph.md' style='text-decoration:auto'>:example:data</a>}}:::javaNode;
:example:domain[<a href='https://github.com/adityabhaskar/Gradle-dependency-graphs/blob/main/example/domain/dependencyGraph.md' style='text-decoration:auto'>:example:domain</a>]:::javaNode;
:example:feature{{<a href='https://github.com/adityabhaskar/Gradle-dependency-graphs/blob/main/example/feature/dependencyGraph.md' style='text-decoration:auto'>:example:feature</a>}}:::javaNode;
:example:models{{<a href='https://github.com/adityabhaskar/Gradle-dependency-graphs/blob/main/example/models/dependencyGraph.md' style='text-decoration:auto'>:example:models</a>}}:::javaNode;
end
%% Dependencies
:example:data--->:example:models
:example:domain==API===>:example:models
:example:domain===>:example:data
%% Dependents
:example:feature-.->:example:domain
This section is a work in progress
The update-graphs-pr.yaml
action creates a new PR with changed dependency graphs when module dependencies change on main
.
- The action runs the plugin task
./gradlew :example:dependencyGraph
to generate fresh dependency graphs. - A simple script -
.github/ci-scripts/changed_files.sh
- collects all the changed graph files so they can be listed in the PR body. - We use the
peter-evans/create-pull-request
action to create a PR only if there are any changed graphs.
Sample PR with changed graphs: #16
TBD: Github action that will automatically commit any new dependency graphs to main
.
Feel free to open a issue or submit a pull request for any bugs/improvements.
This template is licensed under the MIT License - see the License file for details.