diff --git a/src/main/kotlin/com/beust/kobalt/maven/ArtifactFetcher.kt b/src/main/kotlin/com/beust/kobalt/maven/ArtifactFetcher.kt index 112a90fd..82ce7cd1 100644 --- a/src/main/kotlin/com/beust/kobalt/maven/ArtifactFetcher.kt +++ b/src/main/kotlin/com/beust/kobalt/maven/ArtifactFetcher.kt @@ -52,17 +52,6 @@ class ArtifactFetcher @Inject constructor(@Assisted("url") val url: String, private val estimatedSize: Int get() = if (url.contains("kotlin-compiler")) 18000000 else 1000000 - private fun toMd5(bytes: ByteArray) : String { - val result = StringBuilder() - val md5 = MessageDigest.getInstance("MD5").digest(bytes) - md5.forEach { - val byte = it.toInt() and 0xff - if (byte < 16) result.append("0") - result.append(Integer.toHexString(byte)) - } - return result.toString() - } - private fun getBytes(url: String) : ByteArray { log(2, "$url: downloading to $fileName") val body = http.get(url) @@ -86,7 +75,7 @@ class ArtifactFetcher @Inject constructor(@Assisted("url") val url: String, val file = File(fileName) file.parentFile.mkdirs() val bytes = getBytes(url) - if (remoteMd5 != null && remoteMd5 != toMd5(bytes)) { + if (remoteMd5 != null && remoteMd5 != Md5.toMd5(bytes)) { throw KobaltException("MD5 not matching for $url") } else { log(2, "No md5 found for $url, skipping md5 check") diff --git a/src/main/kotlin/com/beust/kobalt/maven/Md5.kt b/src/main/kotlin/com/beust/kobalt/maven/Md5.kt new file mode 100644 index 00000000..08aeae9b --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/maven/Md5.kt @@ -0,0 +1,25 @@ +package com.beust.kobalt.maven + +import com.beust.kobalt.file +import java.io.File +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths +import java.security.MessageDigest + +public class Md5 { + companion object { + fun toMd5(file: File) = toMd5(Files.readAllBytes(Paths.get(file.toURI()))) + + fun toMd5(bytes: ByteArray): String { + val result = StringBuilder() + val md5 = MessageDigest.getInstance("MD5").digest(bytes) + md5.forEach { + val byte = it.toInt() and 0xff + if (byte < 16) result.append("0") + result.append(Integer.toHexString(byte)) + } + return result.toString() + } + } +} diff --git a/src/main/kotlin/com/beust/kobalt/plugin/publish/JCenterApi.kt b/src/main/kotlin/com/beust/kobalt/plugin/publish/JCenterApi.kt index 6a632e64..f98ca261 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/publish/JCenterApi.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/publish/JCenterApi.kt @@ -5,6 +5,7 @@ import com.beust.kobalt.api.Project import com.beust.kobalt.internal.TaskResult import com.beust.kobalt.maven.Http import com.beust.kobalt.maven.KobaltException +import com.beust.kobalt.maven.Md5 import com.beust.kobalt.misc.KobaltLogger import com.google.inject.assistedinject.Assisted import com.squareup.okhttp.Response @@ -12,9 +13,12 @@ import org.jetbrains.annotations.Nullable import java.io.ByteArrayInputStream import java.io.File import java.nio.charset.Charset +import java.nio.file.Files +import java.nio.file.Paths import javax.inject.Inject data class JCenterPackage(val jo: JsonObject) { + @Suppress("UNCHECKED_CAST") val latestPublishedVersion = (jo.get("versions") as JsonArray).get(0) } @@ -82,35 +86,54 @@ public class JCenterApi @Inject constructor (@Nullable @Assisted("username") val project.group!!.replace(".", "/"), project.artifactId!!, project.version!!, - f.getName()) + f.name) .join("/") } - return upload(files, configuration, fileToPath) + return upload(files, configuration, fileToPath, true) } - fun uploadFile(file: File, url: String, configuration: JCenterConfiguration) = + fun uploadFile(file: File, url: String, configuration: JCenterConfiguration, generateMd5: Boolean = false) = upload(arrayListOf(file), configuration, { - f: File -> "${UnauthenticatedJCenterApi.BINTRAY_URL_API_CONTENT}/${username}/generic/${url}" - }) + f: File -> "${UnauthenticatedJCenterApi.BINTRAY_URL_API_CONTENT}/$username/generic/$url" + }, generateMd5) - private fun upload(files: List, configuration : JCenterConfiguration?, fileToPath: (File) -> String) - : TaskResult { + private fun upload(files: List, configuration : JCenterConfiguration?, fileToPath: (File) -> String, + generateMd5: Boolean = false) : TaskResult { val successes = arrayListOf() val failures = hashMapOf() + val filesToUpload = arrayListOf() files.forEach { + + // Create the md5 for this file + filesToUpload.add(it) + if (generateMd5) { + with(File(it.absolutePath)) { + val md5: String = Md5.toMd5(this) + val md5File = File(absolutePath + ".md5") + md5File.writeText(md5) + filesToUpload.add(md5File) + } + } + } + + // + // If any configuration was given, apply them so the URL reflects them, e.g. ?publish=1 + // + val options = arrayListOf() + if (configuration?.publish == true) options.add("publish=1") + + // + // TODO: These files should be uploaded from a thread pool instead of serially + // + log(1, "Found ${filesToUpload.size()} artifacts to upload") + filesToUpload.forEach { var path = fileToPath(it) - - // Apply the configurations for this project, if any - val options = arrayListOf() - if (configuration?.publish == true) options.add("publish=1") - // This actually needs to be done -// options.add("list_in_downloads=1") - if (options.size() > 0) { path += "?" + options.join("&") } + log(1, " Uploading $it to $path") http.uploadFile(username, password, path, it, { r: Response -> successes.add(it) }, { r: Response -> @@ -120,7 +143,7 @@ public class JCenterApi @Inject constructor (@Nullable @Assisted("username") val } val result: TaskResult - if (successes.size() == files.size()) { + if (successes.size() == filesToUpload.size()) { log(1, "All artifacts successfully uploaded") result = TaskResult(true) } else { diff --git a/src/main/kotlin/com/beust/kobalt/plugin/publish/PublishPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/publish/PublishPlugin.kt index f63ca471..f89ed1b5 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/publish/PublishPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/publish/PublishPlugin.kt @@ -52,7 +52,6 @@ public class PublishPlugin @Inject constructor(val http: Http, val files: com.be val result = files.findRecursively(File(project.directory, project.buildDirectory)) { file -> VALID.any { file.endsWith(it)} and file.contains(project.version!!) }.map { it -> File(it) } - log(1, "${project.name}: Found ${result.size()} artifacts to upload") return result }