Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion example/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,33 @@ plugins {
id("tasktree")
}

tasks.create("simple_first_task") {
val firstTask = tasks.create("simple_first_task") {
doLast { println("run simple_first_task") }

tasks.getByName("assemble").dependsOn(this)
}


tasks.create("sub_first_task") {
doLast { println("run sub_first_task") }

firstTask.dependsOn(this)
}


val secondTask = tasks.create("simple_second_task") {
doLast { println("run simple_second_task") }

tasks.getByName("assemble").dependsOn(this)
}


tasks.create("sub_second_task") {
doLast { println("run sub_second_task") }

secondTask.dependsOn(this)
}

tasktree {

inputs = false
Expand All @@ -17,6 +38,9 @@ tasktree {
printPrice = true
printImportance = true
printComplexPrice = true
printDoubles = true
printImportanceOutSide = true


}

Expand Down
37 changes: 11 additions & 26 deletions tasktree/src/main/kotlin/com/github/klee0kai/tasktree/TaskStat.kt
Original file line number Diff line number Diff line change
@@ -1,42 +1,27 @@
package com.github.klee0kai.tasktree

import com.github.klee0kai.tasktree.utils.getAllDeps
import com.github.klee0kai.tasktree.utils.taskGraph
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.kotlin.dsl.provideDelegate

class TaskStat(
val task: Task,
val allTasks: Set<Task>,
val rootProject: Project,
) {

val allDepsCount by lazy { rootProject.taskGraph.getAllDeps(task).count() }
val allDependedOnCount by lazy {
allTasks.count {
rootProject.taskGraph
.getAllDeps(it)
.contains(task)
}
}
val price by lazy { allDepsCount }
val importance by lazy { allDependedOnCount }
var allDepsCount: Long = 0
var allDependedOnCount: Long = 0
var allDependedOnOutsideProjectCount: Long = 0

val complexPrice by lazy {
(price * importance).toFloat() / allTasks.size
}

val price get() = allDepsCount
val importance get() = allDependedOnCount

val complexPrice get() = (price * importance).toFloat() / allTasks.size


// ---- outside of project ------
val allDependedOnOutsideProjectCount by lazy {
allTasks.count {
it.project != task.project &&
rootProject.taskGraph
.getAllDeps(it)
.contains(task)
}
}
val importanceOutsideProject by lazy { allDependedOnOutsideProjectCount }
val complexPriceOutsideProject by lazy { (price * importanceOutsideProject).toFloat() / allTasks.size }
val importanceOutsideProject get() = allDependedOnOutsideProjectCount
val complexPriceOutsideProject get() = (price * importanceOutsideProject).toFloat() / allTasks.size

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,20 @@ open class TaskTreeExtension {
var printDoubles: Boolean = false

/**
* Print dependency count for task
* Print the number of dependencies for a task
*/
var printPrice: Boolean = false

/**
* Print depended task count
* Print number of dependent tasks
*/
var printImportance: Boolean = false

/**
* Print the number of dependent tasks from another project
*/
var printImportanceOutSide: Boolean = false

/**
* Complex price
* ```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ open class TaskTreeTask @Inject constructor(
private val renderedTasks = mutableSetOf<Task>()
private val taskStat = mutableMapOf<Task, TaskStat>()


override fun generate(project: Project) {
val allTasks = project.allRequestedTasks.toSet()
renderedTasks.clear()
taskStat.clear()

val allTasks = project.allRequestedTasks.toSet()
allTasks.forEach { task ->
taskStat.putIfAbsent(
task,
Expand All @@ -31,6 +32,27 @@ open class TaskTreeTask @Inject constructor(
)
}

//https://docs.gradle.org/current/javadoc/org/gradle/api/execution/TaskExecutionGraph.html#getAllTasks--
// use sorted list
allTasks.forEach { task ->
val stat = taskStat[task]!!
val deps = project.taskGraph.getDeps(task)
stat.allDepsCount = deps.count() + deps.sumOf { dep ->
taskStat[dep]!!.allDepsCount
}
}
allTasks.reversed().forEach { task ->
val stat = taskStat[task]!!
project.taskGraph.getDeps(task).forEach {
val depStat = taskStat[it]!!
depStat.allDependedOnCount += 1 + stat.allDependedOnCount
if (depStat.task.project != stat.task.project) {
depStat.allDependedOnOutsideProjectCount += 1 + stat.allDependedOnCount
}
}

}

val topTasks = taskStat.values
.filter { it.allDependedOnCount <= 0 }
.map { it.task }
Expand All @@ -39,7 +61,7 @@ open class TaskTreeTask @Inject constructor(
printMostExpensiveTasksIfNeed()
printMostExpensiveModulesIfNeed()

renderedTasks.clear()

}

private fun render(task: Task, lastChild: Boolean = true, depth: Int = 0) {
Expand Down Expand Up @@ -149,6 +171,10 @@ open class TaskTreeTask @Inject constructor(
withStyle(Description)
.text(" importance: ${taskStat.importance};")
}
if (ext.printImportanceOutSide) {
withStyle(Description)
.text(" importance outside: ${taskStat.importanceOutsideProject};")
}
if (ext.printComplexPrice) {
withStyle(Description)
.text(" complexPrice: ${taskStat.complexPrice.formatString()};")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.execution.taskgraph.DefaultTaskExecutionGraph

private const val RECURSIVE_DETECT = 10_000

val Project.fullName
get() = buildString {
parents
Expand All @@ -24,18 +26,11 @@ val Project.taskGraph get() = gradle.taskGraph as DefaultTaskExecutionGraph
val Project.allRequestedTasks
get() = taskGraph.allTasks
.filter { it !is TaskTreeTask && it !is DiagonDagTask }
.flatMap { setOf(it) + taskGraph.getAllDeps(it) }
.toSet()

val Project.parents get() = generateSequence(this) { runCatching { it.parent }.getOrNull() }

fun DefaultTaskExecutionGraph.getAllDeps(task: Task): Set<Task> =
getDeps(task)
.flatMap {
setOf(it) + getAllDeps(it)
}
.toSet()

val Project.parents
get() = generateSequence(this) {
runCatching { it.parent }.getOrNull()
}.take(RECURSIVE_DETECT)

fun DefaultTaskExecutionGraph.getDeps(task: Task): Set<Task> =
try {
Expand Down