From 8404b0d42db93687378d62fc27cbf23730822e0e Mon Sep 17 00:00:00 2001 From: Robert Stupp Date: Mon, 27 Oct 2025 09:56:03 +0100 Subject: [PATCH] Simplify digest generation Similarly to the change to simplify artifact signing, this change simplifies digest generation by introducing a function to digest the output files of any task. That function takes care of setting up the correct task dependencies and task execution. Also removes an unnecessary double buffering during digest generation. --- .../src/main/kotlin/publishing/digest-task.kt | 52 +++++++++++++------ .../src/main/kotlin/publishing/rootProject.kt | 12 +---- runtime/distribution/build.gradle.kts | 20 ++----- 3 files changed, 41 insertions(+), 43 deletions(-) diff --git a/build-logic/src/main/kotlin/publishing/digest-task.kt b/build-logic/src/main/kotlin/publishing/digest-task.kt index a1f173daff..1c249b4e4c 100644 --- a/build-logic/src/main/kotlin/publishing/digest-task.kt +++ b/build-logic/src/main/kotlin/publishing/digest-task.kt @@ -19,40 +19,52 @@ package publishing +import java.io.File import java.security.MessageDigest import javax.inject.Inject import org.gradle.api.DefaultTask +import org.gradle.api.Project import org.gradle.api.model.ObjectFactory import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputFiles import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.TaskProvider +import org.gradle.internal.extensions.stdlib.capitalized import org.gradle.work.DisableCachingByDefault @DisableCachingByDefault abstract class GenerateDigest @Inject constructor(objectFactory: ObjectFactory) : DefaultTask() { - @get:InputFile val file = objectFactory.fileProperty() + @get:InputFiles val files = objectFactory.fileCollection() + @get:Input val algorithm = objectFactory.property(String::class.java).convention("SHA-512") - @get:OutputFile - val outputFile = - objectFactory.fileProperty().convention { - val input = file.get().asFile - val algo = algorithm.get() - input.parentFile.resolve("${input.name}.${algo.replace("-", "").lowercase()}") - } + + @Suppress("unused", "UnstableApiUsage") + @get:OutputFiles + val outputFiles = + objectFactory.fileCollection().convention(files.map { file -> digestFileForInput(file) }) @TaskAction fun generate() { - val input = file.get().asFile - val digestFile = outputFile.get().asFile - val md = MessageDigest.getInstance(algorithm.get()) + files.files.forEach { input -> digest(input) } + } + + private fun digestFileForInput(input: File): File { + val algo = algorithm.get() + return input.parentFile.resolve("${input.name}.${algo.replace("-", "").lowercase()}") + } + + private fun digest(input: File) { + val algo = algorithm.get() + logger.info("Generating {} digest for '{}'", algo, input) + val digestFile = digestFileForInput(input) + val md = MessageDigest.getInstance(algo) input.inputStream().use { - val buffered = it.buffered(8192) val buf = ByteArray(8192) var rd: Int while (true) { - rd = buffered.read(buf) + rd = it.read(buf) if (rd == -1) break md.update(buf, 0, rd) } @@ -64,3 +76,13 @@ abstract class GenerateDigest @Inject constructor(objectFactory: ObjectFactory) } } } + +fun Project.digestTaskOutputs(task: TaskProvider<*>): TaskProvider { + val digestTask = tasks.register("digest${task.name.capitalized()}", GenerateDigest::class.java) + digestTask.configure { + dependsOn(task) + this.files.from(task.map { t -> t.outputs.files }.get()) + } + task.configure { finalizedBy(digestTask) } + return digestTask +} diff --git a/build-logic/src/main/kotlin/publishing/rootProject.kt b/build-logic/src/main/kotlin/publishing/rootProject.kt index 5c8a5da90a..95267fb0a6 100644 --- a/build-logic/src/main/kotlin/publishing/rootProject.kt +++ b/build-logic/src/main/kotlin/publishing/rootProject.kt @@ -64,17 +64,7 @@ internal fun configureOnRootProject(project: Project) = outputs.file(e.sourceTarball) } - val digestSourceTarball = - tasks.register("digestSourceTarball") { - description = "Generate the source tarball digest" - mustRunAfter(sourceTarball) - file.set { - val e = project.extensions.getByType(PublishingHelperExtension::class.java) - e.sourceTarball.get().asFile - } - } - - sourceTarball.configure { finalizedBy(digestSourceTarball) } + digestTaskOutputs(sourceTarball) signTaskOutputs(sourceTarball) diff --git a/runtime/distribution/build.gradle.kts b/runtime/distribution/build.gradle.kts index ee905ca97e..75ddcf7b4c 100644 --- a/runtime/distribution/build.gradle.kts +++ b/runtime/distribution/build.gradle.kts @@ -17,8 +17,8 @@ * under the License. */ -import publishing.GenerateDigest import publishing.PublishingHelperPlugin +import publishing.digestTaskOutputs import publishing.signTaskOutputs plugins { @@ -81,23 +81,9 @@ val distTar = tasks.named("distTar") { compression = Compression.GZIP } val distZip = tasks.named("distZip") {} -val digestDistTar = - tasks.register("digestDistTar") { - description = "Generate the distribution tar digest" - dependsOn(distTar) - file.set { distTar.get().archiveFile.get().asFile } - } - -val digestDistZip = - tasks.register("digestDistZip") { - description = "Generate the distribution zip digest" - dependsOn(distZip) - file.set { distZip.get().archiveFile.get().asFile } - } - -distTar.configure { finalizedBy(digestDistTar) } +digestTaskOutputs(distTar) -distZip.configure { finalizedBy(digestDistZip) } +digestTaskOutputs(distZip) signTaskOutputs(distTar)