From 798687e68044b9d1c4479694c0ebc96b71651b10 Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Fri, 24 Mar 2017 13:58:18 +0700 Subject: [PATCH] tools: Report dependency downloading progress --- .../src/main/kotlin/DependencyDownloader.kt | 71 +++++++++++++++---- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/tools/helpers/src/main/kotlin/DependencyDownloader.kt b/tools/helpers/src/main/kotlin/DependencyDownloader.kt index 274ee841bee..c7637dc087a 100644 --- a/tools/helpers/src/main/kotlin/DependencyDownloader.kt +++ b/tools/helpers/src/main/kotlin/DependencyDownloader.kt @@ -1,13 +1,11 @@ package org.jetbrains.kotlin.konan -import java.io.File -import java.io.RandomAccessFile +import java.io.* import java.net.URL -import java.nio.file.* -import java.util.* +import java.util.Properties +import kotlin.concurrent.thread // TODO: Try to use some dependency management system (Ivy?) -// TODO: Show % and size during downloading class DependencyDownloader(dependenciesRoot: File, val properties: Properties, val dependencies: List) { val dependenciesRoot = dependenciesRoot.apply { mkdirs() } @@ -63,16 +61,65 @@ class DependencyDownloader(dependenciesRoot: File, val properties: Properties, v } } + private val Long.humanReadable: String + get() { + if (this < 0) { + return "-" + } + if (this < 1024) { + return "$this bytes" + } + val exp = (Math.log(this.toDouble()) / Math.log(1024.0)).toInt() + val prefix = "kMGTPE"[exp-1] + return "%.1f %sB".format(this / Math.pow(1024.0, exp.toDouble()), prefix) + } + + private fun updateProgressMsg(url: String, currentBytes: Long, totalBytes: Long) { + print("\rDownload dependency: $url (${currentBytes.humanReadable}/${totalBytes.humanReadable}). ") + } + private fun download(dependencyName: String): File { - val to = File(dependenciesRoot.canonicalPath, "$dependencyName.tar.gz") - if (!to.exists()) { - val from = URL("$dependenciesUrl/$dependencyName.tar.gz") - println("Download dependency: $dependencyName from $from") - from.openStream().use { - Files.copy(it, Paths.get(to.toURI()), StandardCopyOption.REPLACE_EXISTING) + val outputFile = File(dependenciesRoot.canonicalPath, "$dependencyName.tar.gz") + if (!outputFile.exists()) { + val url = URL("$dependenciesUrl/$dependencyName.tar.gz") + val connection = url.openConnection() + val totalBytes = connection.contentLengthLong + + var currentBytes = 0L + var done = false + var downloadError: Throwable? = null + + thread { + try { + url.openStream().use { from -> + outputFile.outputStream().use { to -> + val buffer = ByteArray(DEFAULT_BUFFER_SIZE) + var read = from.read(buffer) + while (read != -1) { + to.write(buffer, 0, read) + currentBytes += read + read = from.read(buffer) + } + } + } + } catch (e: Throwable) { + downloadError = e + } + done = true + } + + // TODO: Improve console logging + var msgLen = 0 + while (!done) { + Thread.sleep(1000) // We can use condition variable here. + updateProgressMsg(url.toString(), currentBytes, totalBytes) + } + println("Done.") + if (downloadError != null) { + throw RuntimeException("Cannot download dependency: $url", downloadError) } } - return to + return outputFile } fun run() {