Skip to content

Commit

Permalink
Move download logic to task and remove build service
Browse files Browse the repository at this point in the history
  • Loading branch information
tamaracha committed Sep 26, 2024
1 parent 40eeb0f commit 2719388
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import org.gradle.jvm.toolchain.JavaLanguageVersion

abstract class GradleJextractPlugin : Plugin<Project> {
override fun apply(project: Project) {
val serviceProvider = project.gradle.sharedServices.registerIfAbsent("${project.name}_${DownloadClient.SERVICE_NAME}", DownloadClient::class.java)
val extension = project.extensions.create(JextractExtension.EXTENSION_NAME, JextractExtension::class.java)
extension.generator.javaLanguageVersion.convention(JavaLanguageVersion.of(Jvm.current().javaVersionMajor ?: 22))
project.extensions.findByType(JavaPluginExtension::class.java)?.let { extension.generator.javaLanguageVersion.convention(it.toolchain.languageVersion) }
Expand All @@ -26,8 +25,6 @@ abstract class GradleJextractPlugin : Plugin<Project> {
val userOutput = project.layout.projectDirectory.dir(project.gradle.gradleUserHomeDir.absolutePath)
val downloadTask = project.tasks.register("downloadJextract", DownloadTask::class.java) { task ->
task.description = "Downloads Jextract"
task.downloadClient.convention(serviceProvider)
task.usesService(serviceProvider)
task.resource.convention(resourceProvider)
task.target.convention(userOutput.dir("downloads").file(task.resource.map { it.fileName }))
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,71 @@ package de.infolektuell.gradle.jextract.tasks

import de.infolektuell.gradle.jextract.extensions.JextractResolver
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
import java.io.InputStream
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardCopyOption
import java.security.DigestInputStream
import java.security.MessageDigest
import java.time.Duration

abstract class DownloadTask : DefaultTask() {
@get:Internal
abstract val downloadClient: Property<DownloadClient>
@get:Input
abstract val resource: Property<JextractResolver.Resource>
@get:OutputFile
abstract val target: RegularFileProperty
private val client: HttpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).version(HttpClient.Version.HTTP_1_1).build()

@TaskAction
fun download() {
Files.createDirectories(target.asFile.get().parentFile.toPath())
val url = resource.get().url
val checksum = resource.get().checksum
val algorithm = resource.get().algorithm
downloadClient.get().download(url, checksum, algorithm, target.get())
val targetPath = target.get().asFile.toPath()
Files.createDirectories(targetPath.parent)
download(url, checksum, algorithm, targetPath)
}

private fun download(source: URI, checksum: String, algorithm: String, target: Path) {
val downloaded = verify(target, checksum, algorithm)
if (downloaded) return
val request: HttpRequest = HttpRequest.newBuilder()
.uri(source)
.GET()
.build()
val response = client.send(request, HttpResponse.BodyHandlers.ofInputStream())
if (response.statusCode() != 200) throw GradleException("Downloading from $source failed with status code ${response.statusCode()}.")
println(response.version())
val isValid = copyVerify(response.body(), target, checksum, algorithm)
if (!isValid) throw GradleException("Data integrity of downloaded file $source could not be verified, checksums do not match.")
}
@OptIn(ExperimentalStdlibApi::class)
private fun copyVerify(from: InputStream, file: Path, checksum: String, algorithm: String): Boolean {
val md = MessageDigest.getInstance(algorithm)
val input = DigestInputStream(from, md)
Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING)
val calculatedChecksum = input.messageDigest.digest().toHexString()
if (calculatedChecksum != checksum) Files.deleteIfExists(file)
return calculatedChecksum == checksum
}
@OptIn(ExperimentalStdlibApi::class)
private fun verify(file: Path, checksum: String, algorithm: String): Boolean {
if (Files.notExists(file)) return false
val md = MessageDigest.getInstance(algorithm)
DigestInputStream(Files.newInputStream(file), md).use { input ->
input.readAllBytes()
}
val calculatedChecksum = md.digest().toHexString()
val isValid = calculatedChecksum == checksum
if (!isValid) Files.deleteIfExists(file)
return isValid
}
}

0 comments on commit 2719388

Please sign in to comment.