1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 08:27:12 -07:00

GITHUB-231: Fix the incorrect order of builds.

Fixes https://github.com/cbeust/kobalt/issues/231
This commit is contained in:
Cedric Beust 2016-06-10 21:52:21 -08:00
parent 5a540f3474
commit 7e983ed529
5 changed files with 113 additions and 42 deletions

View file

@ -4,10 +4,7 @@ import com.beust.kobalt.*
import com.beust.kobalt.api.*
import com.beust.kobalt.api.annotation.IncrementalTask
import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.misc.Strings
import com.beust.kobalt.misc.benchmarkMillis
import com.beust.kobalt.misc.kobaltError
import com.beust.kobalt.misc.log
import com.beust.kobalt.misc.*
import com.google.common.annotations.VisibleForTesting
import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.ListMultimap
@ -182,34 +179,40 @@ class TaskManager @Inject constructor(val args: Args,
*/
fun calculateDependentTaskNames(taskNames: List<String>, projects: List<Project>): List<TaskInfo> {
val projectMap = hashMapOf<String, Project>().apply {
projects.forEach { put(it.name, it)}
}
val result = ArrayList(taskNames.map { TaskInfo(it) })
val toProcess = ArrayList(result)
val newToProcess = arrayListOf<TaskInfo>()
val seen = hashSetOf<TaskInfo>()
var stop = false
while (! stop) {
toProcess.forEach { ti ->
projectMap[ti.project]?.let { project ->
project.projectExtra.dependsOn.forEach { dp ->
val newTask = TaskInfo(dp.projectName, ti.taskName)
// Insert the project at the top of the list since we haven't added its dependents yet
result.add(0, newTask)
if (! seen.contains(newTask)) {
newToProcess.add(newTask)
seen.add(newTask)
}
}
}
}
stop = newToProcess.isEmpty()
toProcess.clear()
toProcess.addAll(newToProcess)
newToProcess.clear()
projects.forEach { project -> put(project.name, project)}
}
return result
val allTaskInfos = HashSet(taskNames.map { TaskInfo(it) })
with(Topological<TaskInfo>()) {
val toProcess = ArrayList(allTaskInfos)
val seen = HashSet(allTaskInfos)
val newTasks = hashSetOf<TaskInfo>()
while (toProcess.any()) {
toProcess.forEach { ti ->
val project = projectMap[ti.project]
val dependents = project!!.projectExtra.dependsOn
if (dependents.any()) {
dependents.forEach { depProject ->
val tiDep = TaskInfo(depProject.name, ti.taskName)
allTaskInfos.add(tiDep)
addEdge(ti, tiDep)
if (! seen.contains(tiDep)) {
newTasks.add(tiDep)
seen.add(tiDep)
}
}
} else {
allTaskInfos.add(ti)
addNode(ti)
}
}
toProcess.clear()
toProcess.addAll(newTasks)
newTasks.clear()
}
val result = sort()
return result
}
}
val LOG_LEVEL = 3

View file

@ -10,22 +10,25 @@ import java.util.*
*/
class Topological<T> {
private val dependingOn = ArrayListMultimap.create<T, T>()
private val nodes = hashSetOf<T>()
fun addNode(t: T) = nodes.add(t)
fun addEdge(t: T, other: T) {
addNode(t)
addNode(other)
dependingOn.put(t, other)
}
fun addEdge(t: T, others: Array<out T>) {
dependingOn.putAll(t, others.toMutableList())
}
/**
* @return the Ts sorted topologically.
*/
fun sort(all: ArrayList<T>) : List<T> {
fun sort() : List<T> {
val all = ArrayList<T>(nodes)
val result = arrayListOf<T>()
var dependMap = HashMultimap.create<T, T>()
dependingOn.keySet().forEach { dependMap.putAll(it, dependingOn.get(it))}
nodes.forEach { dependMap.putAll(it, emptyList())}
while (all.size > 0) {
val freeNodes = all.filter {
dependMap.get(it).isEmpty()