How to get the information of transitive dependencies in a gradle task?
Andrew Henderson
I want to get information of all dependencies (including transitive ones) in a gradle task.
I tried the code:
class MyGradlePlugin implements Plugin<Project> { void apply(Project project) { project.afterEvaluate { println " Project:" + project.name project.configurations.each { conf -> println " Configuration: ${conf.name}" conf.allDependencies.each { dep -> println " ${dep.group}:${dep.name}:${dep.version}" } } } }
}But it only prints the declared ones, no transitive ones.
That means, if my dependencies is:
dependencies { compile "com.google.guava:guava:18.0" compile 'org.codehaus.groovy:groovy-all:2.3.11' testCompile 'junit:junit:4.11'
}It only prints these 3 dependencies, but the org.hamcrest:hamcrest-core:1.3 which is the transitive dependency of junit:junit:4.11 is not displayed.
How to modify the code to let it show org.hamcrest:hamcrest-core:1.3 as well?
PS: I know gradle dependencies task will show everything I want, but I need to get the dependencies information manually and print it in my own format.
3 Answers
Finally, I figure it out with follow task
class Dep { String group String name String version String extention String classifier Dep(String group, String name, String version, String extension, String classifier) { this.group = group this.name = name this.version = version this.extention = extension this.classifier = classifier }
}
task collectAllDeps { def deps = [] configurations.each { conf -> if (conf.isCanBeResolved()) { conf.getResolvedConfiguration().getResolvedArtifacts().each { at -> def dep = at.getModuleVersion().getId() println at.getFile().getAbsolutePath() // dep = dep1.getComponentIdentifier() println "$dep.group:$dep.name:$dep.version" deps.add(new Dep(dep.group, dep.name, dep.version, at.extension, at.classifier)) } } } def json = groovy.json.JsonOutput.toJson(deps) json = groovy.json.JsonOutput.prettyPrint(json) new File("deps.json") << json
} 2 android studio 3.5
classpath 'com.android.tools.build:gradle:3.5.0'create a demo android app.
add code at build.gradle.
terminal : ./gradlew showAllDependenciesDebug
//task name : showAllDependencies[Flavor][BuildType]
The result show all sdk(s) info,
include that imported by : 'implementation fileTree(dir: 'libs', include: ['.jar', '.aar'])'
import com.android.build.gradle.internal.ide.dependencies.ArtifactUtils
import com.android.build.gradle.internal.ide.dependencies.BuildMappingUtils
import com.android.build.gradle.internal.pipeline.TransformManager
import com.android.build.gradle.internal.publishing.AndroidArtifacts
import com.android.build.gradle.internal.scope.VariantScopeImpl
project.afterEvaluate { project.android.applicationVariants.each {variant -> project.tasks.create(name : "showAllDependencies${variant.name.capitalize()}", group : "help", description: "Print all sdk(s) infomation. author:sodino") { doLast { showAllDeps(project, variant) } } }
}
def showAllDeps(def project, def variant) { def android = project.android def globalScope = android.globalScope def gradle = project.gradle def set = ArtifactUtils.getAllArtifacts( new VariantScopeImpl(globalScope, new TransformManager(project, null, null), variant.variantData), AndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH, null, BuildMappingUtils.computeBuildMapping(gradle) ) println "${variant.name.capitalize()} all dependencies.size=${set.size()}" set.eachWithIndex {artifact, idx-> def componentIdentifier = artifact.componentIdentifier if (componentIdentifier.displayName.contains(':')) { def modulerIdentifier = componentIdentifier.moduleIdentifier def group = modulerIdentifier.group def name = modulerIdentifier.name def version = componentIdentifier.version println "${idx} : ${componentIdentifier.displayName}" } else { println "${idx} -> ${artifact.artifactFile}" } }
}The result:
sodino Macbook-pro: MyApplication sodino$: ./gradlew showAllDependenciesDebug
> Configure project :app
> Task :app:showAllDependenciesDebug
Debug all dependencies.size=65
0 -> /Users/sodino/AndroidStudioProjects/MyApplication3/app/libs/sodino.xiamen.FJ.aar
1 : org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.3.41
2 : org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.41
3 : androidx.navigation:navigation-ui-ktx:2.1.0
4 : androidx.navigation:navigation-ui:2.1.0
5 : com.google.android.material:material:1.0.0
6 : androidx.appcompat:appcompat:1.1.0
7 : androidx.core:core-ktx:1.1.0
8 : androidx.legacy:legacy-support-v4:1.0.0
9 : androidx.constraintlayout:constraintlayout:1.1.3
10 : androidx.navigation:navigation-fragment-ktx:2.1.0
11 : androidx.navigation:navigation-fragment:2.1.0
12 : androidx.lifecycle:lifecycle-extensions:2.1.0
13 : androidx.navigation:navigation-runtime-ktx:2.1.0
14 : androidx.fragment:fragment-ktx:1.1.0
15 : androidx.activity:activity-ktx:1.0.0
16 : androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0
17 : androidx.navigation:navigation-common-ktx:2.1.0
18 : org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1
19 : org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1
20 : org.jetbrains.kotlin:kotlin-stdlib:1.3.41
21 : androidx.fragment:fragment:1.1.0
22 : androidx.appcompat:appcompat-resources:1.1.0
23 : androidx.recyclerview:recyclerview:1.0.0
24 : androidx.legacy:legacy-support-core-ui:1.0.0
25 : androidx.drawerlayout:drawerlayout:1.0.0
26 : androidx.media:media:1.0.0
27 : androidx.legacy:legacy-support-core-utils:1.0.0
28 : androidx.transition:transition:1.0.1
29 : androidx.viewpager:viewpager:1.0.0
30 : androidx.loader:loader:1.0.0
31 : androidx.navigation:navigation-runtime:2.1.0
32 : androidx.activity:activity:1.0.0
33 : androidx.vectordrawable:vectordrawable-animated:1.1.0
34 : androidx.vectordrawable:vectordrawable:1.1.0
35 : androidx.coordinatorlayout:coordinatorlayout:1.0.0
36 : androidx.slidingpanelayout:slidingpanelayout:1.0.0
37 : androidx.customview:customview:1.0.0
38 : androidx.swiperefreshlayout:swiperefreshlayout:1.0.0
39 : androidx.asynclayoutinflater:asynclayoutinflater:1.0.0
40 : androidx.navigation:navigation-common:2.1.0
41 : androidx.core:core:1.1.0
42 : androidx.cursoradapter:cursoradapter:1.0.0
43 : androidx.cardview:cardview:1.0.0
44 : androidx.lifecycle:lifecycle-process:2.1.0
45 : androidx.lifecycle:lifecycle-service:2.1.0
46 : androidx.lifecycle:lifecycle-runtime:2.1.0
47 : androidx.lifecycle:lifecycle-livedata:2.1.0
48 : androidx.lifecycle:lifecycle-livedata-core:2.1.0
49 : androidx.arch.core:core-runtime:2.1.0
50 : androidx.savedstate:savedstate:1.0.0
51 : androidx.arch.core:core-common:2.1.0
52 : androidx.lifecycle:lifecycle-common:2.1.0
53 : androidx.lifecycle:lifecycle-viewmodel:2.1.0
54 : androidx.versionedparcelable:versionedparcelable:1.1.0
55 : androidx.collection:collection:1.1.0
56 : androidx.documentfile:documentfile:1.0.0
57 : androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
58 : androidx.print:print:1.0.0
59 : androidx.interpolator:interpolator:1.0.0
60 : androidx.annotation:annotation:1.1.0
61 : androidx.constraintlayout:constraintlayout-solver:1.1.3
62 : org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.1.1
63 : org.jetbrains.kotlin:kotlin-stdlib-common:1.3.41
64 : org.jetbrains:annotations:13.0
BUILD SUCCESSFUL in 0s It's an old post but I think it's worth to show how to do it in both single/multi gradle project:
You can use Gradle scan or use the built-in dependencyReport Task if you don't want to share sensible information with Gradle servers.
In a single project, you can directly use:
./gradlew dependencyReportIn a multiple project, you can use the same invoked to each subproject:
allprojects { ... tasks.register("allDeps",DependencyReportTask) {} ...
}