From cb1aaf6a755ff7075515f7d043cf32bb40c85fde Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 21 Dec 2015 00:32:55 +0400 Subject: [PATCH] Incremental manager work. --- .../kobalt/internal/IncrementalManager.kt | 68 +++++++++++++++++++ .../kobalt/internal/IncrementalManagerTest.kt | 31 +++++++++ 2 files changed, 99 insertions(+) create mode 100644 modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/IncrementalManager.kt create mode 100644 src/test/kotlin/com/beust/kobalt/internal/IncrementalManagerTest.kt diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/IncrementalManager.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/IncrementalManager.kt new file mode 100644 index 00000000..3ff1536f --- /dev/null +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/IncrementalManager.kt @@ -0,0 +1,68 @@ +package com.beust.kobalt.internal + +import com.beust.kobalt.misc.KFiles +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import java.io.File +import java.io.FileReader +import java.nio.charset.Charset +import java.nio.file.Files +import java.nio.file.Paths +import java.util.* + +data class TaskInfo(val taskName: String, var inputChecksum: String? = null, var outputChecksum: String? = null) + +class BuildInfo(var tasks: List) + +/** + * Manage the file .kobalt/build-info.kt, which keeps track of input and output checksums to manage + * incremental builds. + */ +class IncrementalManager(val fileName: String = IncrementalManager.BUILD_INFO_FILE) { + companion object { + val BUILD_INFO_FILE = KFiles.joinDir(KFiles.KOBALT_DOT_DIR, "build-info.json") + } + + private fun buildInfo() = File(fileName).let { file -> + if (file.exists()) { + Gson().fromJson(FileReader(file), BuildInfo::class.java) ?: BuildInfo(emptyList()) + } else { + BuildInfo(emptyList()) + } + } + + private fun taskInfos() = hashMapOf().apply { + buildInfo().tasks.forEach { + put(it.taskName, it) + } + } + + private fun save(map: Map) { + val bi = BuildInfo(map.values.toList()) + val json = GsonBuilder().setPrettyPrinting().create().toJson(bi) + Files.write(Paths.get(fileName), json.toByteArray(Charset.defaultCharset())) + } + + private fun taskInfoFor(taskInfos: HashMap, taskName: String) + = taskInfos.getOrPut(taskName, { -> TaskInfo(taskName) }) + + fun saveInputChecksum(taskName: String, inputChecksum: String) { + with(taskInfos()) { + taskInfoFor(this, taskName).inputChecksum = inputChecksum + save(this) + } + } + + fun inputChecksumFor(taskName: String) : String? = + taskInfoFor(taskInfos(), taskName).inputChecksum + + fun saveOutputChecksum(taskName: String, outputChecksum: String) { + with(taskInfos()) { + taskInfoFor(this, taskName).outputChecksum = outputChecksum + save(this) + } + } + + fun outputChecksumFor(taskName: String) : String? = + taskInfoFor(taskInfos(), taskName).outputChecksum +} diff --git a/src/test/kotlin/com/beust/kobalt/internal/IncrementalManagerTest.kt b/src/test/kotlin/com/beust/kobalt/internal/IncrementalManagerTest.kt new file mode 100644 index 00000000..7600d17e --- /dev/null +++ b/src/test/kotlin/com/beust/kobalt/internal/IncrementalManagerTest.kt @@ -0,0 +1,31 @@ +package com.beust.kobalt.internal + +import org.testng.Assert +import org.testng.annotations.Test +import java.io.File + +@Test +class IncrementalManagerTest { + val TASK = "task" + val TASK2 = "task2" + + fun shouldSave() { + val file = File.createTempFile("kobalt-", "") + println("File: $file") + val im = IncrementalManager(file.absolutePath) + val v = im.inputChecksumFor(TASK) + Assert.assertNull(v) + im.saveInputChecksum(TASK, "44") + Assert.assertEquals(im.inputChecksumFor(TASK), "44") + im.saveInputChecksum(TASK, "42") + Assert.assertEquals(im.inputChecksumFor(TASK), "42") + + im.saveInputChecksum(TASK2, "45") + Assert.assertEquals(im.inputChecksumFor(TASK2), "45") + + Assert.assertEquals(im.inputChecksumFor(TASK), "42") + + im.saveOutputChecksum(TASK, "49") + Assert.assertEquals(im.outputChecksumFor(TASK), "49") + } +}