The Dependency Analysis Gradle Plugin (DAGP, née Dependency Analysis Android Gradle Plugin) detects the following:
-
Unused dependencies.
-
Used transitive dependencies (which you may want to declare directly).
-
Dependencies declared on the wrong configuration (
api
vsimplementation
vscompileOnly
, etc.).
As a side effect, the plugin can also tell you your project’s ABI, and produces graphviz files representing various views of your dependency graph, among other things. These side effects are currently mostly undocumented internal behaviors, but they may be interesting for some advanced users.
In addition to the dependency-related advice (see above), DAGP provides other advice to help maintain your "build health." This includes the detection of:
-
Unnecessary plugins (currently only
kapt
). -
Subprojects ("modules") that unnecessarily use the Android plugin, and could instead be "normal" JVM libraries.
Please see the wiki for information on the versions of Gradle, the Android Gradle Plugin, etc., that this plugin is compatible with.
For detailed instructions, see the wiki.
The simplest approach is to add the following:
plugins {
id("com.autonomousapps.build-health") version "<<latest_version>>"
}
Important
|
If your project uses Kotlin or Android (or both), then those plugins must also be loaded in the settings script classloader (or a parent). See the wiki for more information |
For a quick start, just run the following:
./gradlew buildHealth
You will probably see output like the following:
> Task :buildHealth FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':buildHealth'. > There were dependency violations. See report at file:///path/to/project/build/reports/dependency-analysis/build-health-report.txt
If you wish to have this (potentially very long) report printed to console, add this to your gradle.properties
file:
dependency.analysis.print.build.health=true
From 2.19.0 for releases, and 2.18.1-SNAPSHOT for snapshots, this plugin uses https://central.sonatype.com. To add this plugin to your project, use the following repositories.
pluginManagement {
repositories {
// releases
mavenCentral()
// snapshots
maven(url = "https://central.sonatype.com/repository/maven-snapshots/")
// Once you start using pluginManagement, you should explicitly add this,
// unless you NEVER want to use this repository
gradlePluginPortal()
}
}
You do not have to apply this plugin to all projects via the settings script. It can also be applied to only specific subprojects. In this case, it must also be applied to the root build script.
plugins {
id("com.autonomousapps.dependency-analysis") version "<<latest_version>>"
}
plugins {
id("com.autonomousapps.dependency-analysis")
}
Important
|
If your project uses Kotlin or Android (or both), then those plugins must also be loaded in the root build script classloader (or a parent). See the wiki for more information |
The analysis can be run against individual modules with the projectHealth
task. For example:
./gradlew app:projectHealth
It is common for the plugin to report many issues with your project’s dependency declarations. Since fixing manually can be tedious, the plugin also provides a task to auto-remediate all issues.
./gradlew fixDependencies
The fixDependencies
task is registered on each project where the plugin is applied. Running it as above will run the
task in each subproject. See also
One click dependencies fix.
In some circumstances, it may be considered infeasible to resolve all issues in one pass. Maybe you have a very large
project, or you publish libraries and you know that changing your dependency declarations will also change your
libraries' metadata, which might break consumers. To support this use-case, the the fixDependencies
task takes an
optional flag to tell it to, essentially, make only "safe" changes.
./gradlew fixDependencies --upgrade
With this flag in place, the fixDependencies
task will not remove or "downgrade" any dependency declarations. It will
only add or "upgrade" declarations (e.g., from implementation
to api
).
In an incremental rollout scenario, one could imagine using the --upgrade
flag, then updating all consumers, then
finally removing the flag and removing all unused dependencies.
If the analysis has any bugs, then fixing the dependency declarations make break your build (but this is also the case with manual fixes). If you encounter this, please file an issue.
Additionally, the rewriting functionality is based on a simplified Gradle Groovy DSL grammar, which will fail in the presence of complex Groovy build scripts. The Kotlin DSL grammar has full support for the entire Kotlin language, which makes the rewriting functionality work much better for Gradle Kotlin DSL scripts. There are no plans to do the same for Gradle Groovy DSL.
You may be curious why the plugin is emitting (or not emitting) advice regarding some dependency. You can ask it why:
./gradlew lib:reason --id com.squareup.okio:okio:2.2.2 (1) > Task :lib:reason ---------------------------------------- You asked about the dependency 'com.squareup.okio:okio:2.2.2'. There is no advice regarding this dependency. ---------------------------------------- Shortest path from :lib to com.squareup.okio:okio:2.2.2: :lib \--- com.squareup.okio:okio:2.2.2 Source: main ------------ * Exposes class okio.BufferedSource (implies api).
-
The version string is optional.
For detailed information on how to configure the plugin, see the wiki.
To configure the plugin, use the dependencyAnalysis
extension.
dependencyAnalysis {
// Declare that the plugin should use typesafe project accessors. False by default.
useTypesafeProjectAccessors(true)
// Configure ABI exclusion rules.
abi { ... }
// Configure the severity of issues, and exclusion rules, for potentially the entire project.
issues { ... }
// Configure issue reports.
reporting {
// false by default. Setting to true results in
// the advice report being emitted to console.
printBuildHealth(true)
}
// Configure dependency structure rules (bundles, mapping, etc).
structure { ... }
// Configure usage rules.
usage { ... }
}
From version 3.0.0 (unreleased), the plugin includes an api definition in api/api.txt
. Any backwards-incompatible
change from then on will result in a major version release. Note that some code is public only due to tooling
limitations; most of this code is in an internal
package, but com.autonomousapps.tasks
is also considered
"internal." Usage of any API in these internal packages is at your own risk.
For typical users who only apply the plugin and run the primary tasks (buildHealth
, projectHealth
, reason
, etc.),
major releases should be treated as non-events. For these users, the "API" is just those primary tasks.
The following is a list of articles / blog posts that have been published discussing this plugin:
This plugin has also been featured in these newsletters:
Podcast episodes about this plugin could be found here:
Youtube videos about this plugin: