diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt index b18f1c06..0cd71af6 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt @@ -212,25 +212,39 @@ class TaskManager @Inject constructor(val args: Args, } log(LOG_LEVEL, " Current batch to process: $toProcess") - val invertedReverseDependsOn = reverseMultimap(reverseDependsOn) + // + // Move dependsOn + reverseDependsOn in one multimap called allDepends + // + val allDependsOn = ArrayListMultimap.create() + dependsOn.keySet().forEach { key -> + dependsOn[key].forEach { value -> + allDependsOn.put(key, value) + } + } + reverseDependsOn.keySet().forEach { key -> + reverseDependsOn[key].forEach { value -> + allDependsOn.put(value, key) + } + } + + // + // Process each node one by one + // toProcess.forEach { taskInfo -> val taskName = taskInfo.taskName log(LOG_LEVEL, " ***** Current node: $taskName") - nodeMap[taskName].forEach { processAlways(always, it) } + nodeMap[taskName].forEach { + result.addNode(it) + processAlways(always, it) + } // // dependsOn and reverseDependsOn are considered for all tasks, explicit and implicit // - dependsOn[taskName].forEach { to -> + allDependsOn[taskName].forEach { to -> addEdge(result, taskName, to, newToProcess, "dependsOn") } - reverseDependsOn[taskName].forEach { from -> - addEdge(result, from, taskName, newToProcess, "reverseDependsOn") - } - invertedReverseDependsOn[taskName].forEach { to -> - addEdge(result, taskName, to, newToProcess, "invertedReverseDependsOn") - } // // runBefore and runAfter (task ordering) are only considered for explicit tasks (tasks that were @@ -258,15 +272,15 @@ class TaskManager @Inject constructor(val args: Args, return result } - private fun reverseMultimap(mm: Multimap) : Multimap { - val result = TreeMultimap.create() - mm.keySet().forEach { key -> - mm[key].forEach { value -> - result.put(value, key) - } - } - return result - } +// private fun reverseMultimap(mm: Multimap) : Multimap { +// val result = TreeMultimap.create() +// mm.keySet().forEach { key -> +// mm[key].forEach { value -> +// result.put(value, key) +// } +// } +// return result +// } /** * Create a dynamic graph representing all the tasks that need to be run. diff --git a/src/test/kotlin/com/beust/kobalt/internal/TaskManagerTest.kt b/src/test/kotlin/com/beust/kobalt/internal/TaskManagerTest.kt index 629531f1..c051fdc5 100644 --- a/src/test/kotlin/com/beust/kobalt/internal/TaskManagerTest.kt +++ b/src/test/kotlin/com/beust/kobalt/internal/TaskManagerTest.kt @@ -1,6 +1,7 @@ package com.beust.kobalt.internal import com.beust.kobalt.TestModule +import com.beust.kobalt.misc.log import com.google.common.collect.ArrayListMultimap import com.google.common.collect.Multimap import com.google.common.collect.TreeMultimap @@ -31,23 +32,27 @@ class TaskManagerTest @Inject constructor(val taskManager: TaskManager) { } } - private fun runCompileTasks(tasks: List) : List { - val result = runTasks(tasks, - dependsOn = TreeMultimap.create().apply { - put("assemble", "compile") - }, - reverseDependsOn = TreeMultimap.create().apply { - put("clean", "copyVersion") - put("compile", "postCompile") - }) - return result - } - + // @Test(enabled = false) fun graphTest() { // KobaltLogger.LOG_LEVEL = 3 + fun runCompileTasks(tasks: List) : List { + val result = runTasks(tasks, + dependsOn = TreeMultimap.create().apply { + put("assemble", "compile") + }, + reverseDependsOn = TreeMultimap.create().apply { + put("clean", "copyVersion") + }, + alwaysRunAfter = TreeMultimap.create().apply { + put("postCompile", "compile") + }) + log(1, "GRAPH RUN: " + result) + return result + } + Assert.assertEquals(runCompileTasks(listOf("compile")), listOf("compile", "assemble", "postCompile")) -// Assert.assertEquals(runCompileTasks(listOf("postCompile")), listOf("compile", "assemble", "postCompile")) + Assert.assertEquals(runCompileTasks(listOf("postCompile")), listOf("compile", "assemble", "postCompile")) Assert.assertEquals(runCompileTasks(listOf("compile", "postCompile")), listOf("compile", "assemble", "postCompile")) Assert.assertEquals(runCompileTasks(listOf("clean")), listOf("clean", "copyVersion")) Assert.assertEquals(runCompileTasks(listOf("clean", "compile")), listOf("clean", "compile", "assemble", @@ -80,6 +85,7 @@ class TaskManagerTest @Inject constructor(val taskManager: TaskManager) { dependsOn, reverseDependsOn, runBefore, runAfter, alwaysRunAfter, { it }, { t -> true }) val result = DryRunGraphExecutor(graph).run() +// log(1, "GRAPH RUN: $result") return result } @@ -97,14 +103,15 @@ class TaskManagerTest @Inject constructor(val taskManager: TaskManager) { }), listOf("compile", "copyVersionForWrapper", "assemble")) - Assert.assertEquals(runTasks(listOf("compile"), - dependsOn = TreeMultimap.create().apply { - put("compile", "clean") - }, - reverseDependsOn = TreeMultimap.create().apply { - put("compile", "example") - }), - listOf("clean", "compile", "example")) +// runTasks(listOf("compile"), +// dependsOn = TreeMultimap.create().apply { +// put("compile", "clean") +// }, +// reverseDependsOn = TreeMultimap.create().apply { +// put("compile", "example") +// }).let { runTask -> +// Assert.assertEquals(runTask, listOf("clean", "compile", "example")) +// } Assert.assertEquals(runTasks(listOf("compile"), dependsOn = TreeMultimap.create().apply { @@ -169,7 +176,7 @@ class TaskManagerTest @Inject constructor(val taskManager: TaskManager) { alwaysRunAfter = TreeMultimap.create().apply { put("coverage", "test") }) - Assert.assertTrue(runTasks == listOf("compile", "compileTest", "enableJacoco", "test", "coverage")) + Assert.assertTrue(runTasks == listOf("compile", "compileTest", "enableJacoco", "test", "coverage")) } @Test(enabled = true) @@ -219,15 +226,87 @@ class TaskManagerTest @Inject constructor(val taskManager: TaskManager) { } } - @Test(enabled = true) - fun allDepends() { -// KobaltLogger.LOG_LEVEL = 3 - val runTasks = runTasks(listOf("uploadGithub"), + @Test + fun uploadGithub() { + runTasks(listOf("uploadGithub"), dependsOn = TreeMultimap.create().apply { put("uploadGithub", "assemble") put("uploadBintray", "assemble") - }) - Assert.assertEquals(runTasks, listOf("assemble", "uploadGithub")) + }).let { runTasks -> + Assert.assertEquals(runTasks, listOf("assemble", "uploadGithub")) + } + runTasks(listOf("uploadGithub"), + reverseDependsOn = TreeMultimap.create().apply { + put("assemble", "uploadGithub") + put("assemble", "uploadBintray") + }).let { runTasks -> + Assert.assertEquals(runTasks, listOf("assemble", "uploadGithub")) + } + } + + @Test(enabled = true, description = "Make sure that dependsOn and reverseDependsOn have similar effects") + fun symmetry() { +// KobaltLogger.LOG_LEVEL = 3 + + // Symmetry 1 + runTasks(listOf("task1"), + dependsOn = TreeMultimap.create().apply { + put("task2a", "task1") + put("task2b", "task1") + }).let { runTasks -> + Assert.assertEquals(runTasks, listOf("task1")) + } + runTasks(listOf("task1"), + reverseDependsOn = TreeMultimap.create().apply { + put("task1", "task2a") + put("task1", "task2b") + }).let { runTasks -> + Assert.assertEquals(runTasks, listOf("task1")) + } + + // Symmetry 2 + runTasks(listOf("task2a"), + dependsOn = TreeMultimap.create().apply { + put("task2a", "task1") + put("task2b", "task1") + }).let { runTasks -> + Assert.assertEquals(runTasks, listOf("task1", "task2a")) + } + runTasks(listOf("task2a"), + reverseDependsOn = TreeMultimap.create().apply { + put("task1", "task2a") + put("task1", "task2b") + }).let { runTasks -> + Assert.assertEquals(runTasks, listOf("task1", "task2a")) + } + + // Symmetry 3 + runTasks(listOf("task1"), + dependsOn = TreeMultimap.create().apply { + put("task2", "task1") + }).let { runTasks -> + Assert.assertEquals(runTasks, listOf("task1")) + } + runTasks(listOf("task1"), + reverseDependsOn = TreeMultimap.create().apply { + put("task1", "task2") + }).let { runTasks -> + Assert.assertEquals(runTasks, listOf("task1")) + } + + // Symmetry 4 + runTasks(listOf("task2"), + dependsOn = TreeMultimap.create().apply { + put("task2", "task1") + }).let { runTasks -> + Assert.assertEquals(runTasks, listOf("task1", "task2")) + } + runTasks(listOf("task2"), + reverseDependsOn = TreeMultimap.create().apply { + put("task1", "task2") + }).let { runTasks -> + Assert.assertEquals(runTasks, listOf("task1", "task2")) + } } }