Skip to content

Instantly share code, notes, and snippets.

@gabrielfeo
Forked from ghale/captureFingerprints.gradle
Last active March 13, 2025 18:52
Show Gist options
  • Save gabrielfeo/c31fe742c75a19507a5098850d772571 to your computer and use it in GitHub Desktop.
Save gabrielfeo/c31fe742c75a19507a5098850d772571 to your computer and use it in GitHub Desktop.
Capture task classpath fingerprints in a configuration cache–compatible way
def fingerprinter = services.get(org.gradle.internal.fingerprint.classpath.ClasspathFingerprinter)
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { task ->
def objectFactory = task.project.objects
def buildScan = rootProject.buildScan
doFirst {
ClassLoader classLoader = task.getClass().classLoader
while (classLoader instanceof URLClassLoader) {
def fingerprints = [] as Set
def allFiles = [] as Set
classLoader.getURLs().each {
def fingerprint = fingerprinter.fingerprint(objectFactory.fileCollection().from(it.file)).hash
fingerprints.add(["${task.path}:${new File(it.file).name}", "${fingerprint}"])
allFiles.add(it.file)
}
fingerprints.each { buildScan.value it[0], it[1] }
buildScan.value "${task.path}:classpath", allFiles.join("\n")
classLoader = classLoader.parent
}
}
}
@gabrielfeo
Copy link
Author

gabrielfeo commented Mar 13, 2025

For each Task of the given type, this script registers a <task>:classpath=<classpath> custom value, as well as a <task>:<fileName>=<fileHash> custom value for each of that task's classpath's files.

One possible use is investigating cache misses caused by "Task implementation changed". This script can then be used to register the contents of that Task's classpath in the Build Scan® itself, and quickly compare it across builds in Develocity.

Change KotlinCompile to whatever task type you need, e.g. com.google.devtools.ksp.gradle.KspTaskJvm.

Usage

This can be applied to a single project or to multiple projects. Applying to all projects is also possible, but you're more likely to hit the custom value limits.

To apply it to projects, the preferable way is to

  1. save this file somewhere
  2. apply it from your projects' build.gradle or build.gradle.kts:
// my-project/build.gradle.kts
appy(from = "$rootDir/captureFingerprints.gradle")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment