Gradle: Implement smart downloads which avoid download if the file exists and is valid.

This commit is contained in:
Kenneth Endfinger 2022-01-14 20:36:15 -05:00
parent 8f34209aff
commit 9d156d250b
No known key found for this signature in database
GPG Key ID: C4E68E5647420E10
3 changed files with 69 additions and 9 deletions

View File

@ -12,6 +12,7 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-serialization:1.6.10")
implementation("gradle.plugin.com.github.johnrengelman:shadow:7.1.1")
implementation("com.google.code.gson:gson:2.8.9")
implementation("org.bouncycastle:bcprov-jdk15on:1.70")
}
java.sourceCompatibility = JavaVersion.VERSION_1_8

View File

@ -59,14 +59,11 @@ open class SetupPaperServer : DefaultTask() {
val build = builds.last()
val download = build.downloads["application"]!!
val url = paperVersionClient.resolveDownloadUrl(build, download)
ant.invokeMethod(
"get", mapOf(
"src" to url.toString(),
"dest" to paperJarFile.absolutePath
)
)
logger.lifecycle("Installed Paper Server ${build.version} build ${build.build}")
val downloader = SmartDownload(paperJarFile.toPath(), url, download.sha256)
if (downloader.download()) {
logger.lifecycle("Installed Paper Server ${build.version} build ${build.build}")
} else {
logger.lifecycle("Paper Server ${build.version} build ${build.build} is up-to-date")
}
}
}

View File

@ -0,0 +1,62 @@
package cloud.kubelet.foundation.gradle
import java.net.URI
import java.nio.file.Files
import java.nio.file.Path
import java.security.MessageDigest
class SmartDownload(val localFilePath: Path, val remoteDownloadUrl: URI, val sha256: String) {
fun download(): Boolean {
if (!checkLocalFileHash()) {
downloadRemoteFile()
return true
}
return false
}
private fun downloadRemoteFile() {
val url = remoteDownloadUrl.toURL()
val remoteFileStream = url.openStream()
val localFileStream = Files.newOutputStream(localFilePath)
remoteFileStream.transferTo(localFileStream)
if (!checkLocalFileHash()) {
throw RuntimeException("Download of ${remoteDownloadUrl} did not result in valid hash.")
}
}
private fun checkLocalFileHash(): Boolean {
if (!Files.exists(localFilePath)) {
return false
}
val digest = MessageDigest.getInstance("SHA-256")
val localFileStream = Files.newInputStream(localFilePath)
val buffer = ByteArray(16 * 1024)
while (true) {
val size = localFileStream.read(buffer)
if (size <= 0) {
break
}
val bytes = buffer.take(size).toByteArray()
digest.update(bytes)
}
val sha256Bytes = digest.digest()
val localSha256Hash = bytesToHex(sha256Bytes)
return localSha256Hash.equals(sha256, ignoreCase = true)
}
private fun bytesToHex(hash: ByteArray): String {
val hexString = StringBuilder(2 * hash.size)
for (i in hash.indices) {
val hex = Integer.toHexString(0xff and hash[i].toInt())
if (hex.length == 1) {
hexString.append('0')
}
hexString.append(hex)
}
return hexString.toString()
}
}