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
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.klee0kai.tasktree

import com.github.klee0kai.tasktree.tasks.DiagonDagTask
import com.github.klee0kai.tasktree.tasks.FlatListTask
import com.github.klee0kai.tasktree.tasks.TaskTreeTask
import com.github.klee0kai.tasktree.utils.allRequestedTasks
import com.github.klee0kai.tasktree.utils.taskGraph
Expand All @@ -15,9 +16,10 @@ open class TaskTreePlugin : Plugin<Project> {
val ext = extensions.create("tasktree", TaskTreeExtension::class.java)
val taskTree = tasks.register("tasktree", TaskTreeTask::class.java, ext)
val taskDag = tasks.register("diagonDAG", DiagonDagTask::class.java)
val flatlist = tasks.register("flatlist", FlatListTask::class.java, ext)

taskGraph.whenReady {
val isTaskTreeRequested = hasTask(taskTree.get()) || hasTask(taskDag.get())
val isTaskTreeRequested = hasTask(taskTree.get()) || hasTask(taskDag.get()) || hasTask(flatlist.get())
if (isTaskTreeRequested) {
allRequestedTasks.forEach {
it.enabled = false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.github.klee0kai.tasktree.tasks

import com.github.klee0kai.tasktree.TaskStat
import com.github.klee0kai.tasktree.TaskTreeExtension
import com.github.klee0kai.tasktree.utils.allRequestedTasks
import com.github.klee0kai.tasktree.utils.formatString
import com.github.klee0kai.tasktree.utils.fullName
import com.github.klee0kai.tasktree.utils.simpleClassName
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutput.Style.Description
import org.gradle.internal.logging.text.StyledTextOutput.Style.Identifier
import javax.inject.Inject

open class FlatListTask @Inject constructor(
private val ext: TaskTreeExtension,
) : BaseReportTask() {

private val statHelper = TaskStatHelper()

override fun generate(project: Project) {
statHelper.collectFrom(project)

val allTasksOrdered = project.allRequestedTasks
allTasksOrdered.forEach { render(task = it) }

}

private fun render(task: Task) {
graphRenderer?.visit({
val taskStat = statHelper.taskStat[task] ?: return@visit

printTaskShort(taskStat)

if (ext.printClassName) {
withStyle(Description)
.text(" class: ${task.simpleClassName};")
}

if (task.isIncludedBuild) {
withStyle(Description)
.text(" (included build '${task.project.gradle.rootProject.name}')")
}

val inputs by lazy { task.inputs.files.files }
if (ext.inputs && inputs.isNotEmpty())
withStyle(Description)
.text(" inputs: [ ${inputs.joinToString { it.path }} ] ")

val outputs by lazy { task.outputs.files.files }
if (ext.outputs && outputs.isNotEmpty())
withStyle(Description)
.text(" outputs: [ ${outputs.joinToString { it.path }} ] ")

}, /*last child */ true)
}

private fun StyledTextOutput.printTaskShort(taskStat: TaskStat) = apply {
withStyle(Identifier)
.text(taskStat.task.fullName)

if (ext.printPrice) {
withStyle(Description)
.text(" price: ${taskStat.price};")
}
if (ext.printImportance) {
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()};")
}
}

private val Task.isIncludedBuild get() = this@FlatListTask.project.gradle != project.gradle


}


Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.github.klee0kai.tasktree.tasks

import com.github.klee0kai.tasktree.TaskStat
import com.github.klee0kai.tasktree.utils.allRequestedTasks
import com.github.klee0kai.tasktree.utils.getDeps
import com.github.klee0kai.tasktree.utils.taskGraph
import org.gradle.api.Project
import org.gradle.api.Task

class TaskStatHelper {

val taskStat = mutableMapOf<Task, TaskStat>()

fun collectFrom(project: Project) {
taskStat.clear()

val allTasksSet = project.allRequestedTasks.toSet()
allTasksSet.forEach { task ->
taskStat.putIfAbsent(
task,
TaskStat(
task = task,
allTasks = allTasksSet,
rootProject = project
)
)
}

//https://docs.gradle.org/current/javadoc/org/gradle/api/execution/TaskExecutionGraph.html#getAllTasks--
// use sorted list
allTasksSet.forEach { task ->
val stat = taskStat[task] ?: return@forEach
val deps = project.taskGraph.getDeps(task)
stat.allDepsCount = deps.count() + deps.sumOf { dep ->
taskStat[dep]?.allDepsCount ?: 0
}
}

allTasksSet.reversed().forEach { task ->
val stat = taskStat[task] ?: return@forEach
project.taskGraph.getDeps(task).forEach {
val depStat = taskStat[it] ?: return@forEach
depStat.allDependedOnCount += 1 + stat.allDependedOnCount
if (depStat.task.project != stat.task.project) {
depStat.allDependedOnOutsideProjectCount += 1 + stat.allDependedOnCount
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,59 +14,28 @@ open class TaskTreeTask @Inject constructor(
) : BaseReportTask() {

private val renderedTasks = mutableSetOf<Task>()
private val taskStat = mutableMapOf<Task, TaskStat>()
private val statHelper = TaskStatHelper()

override fun generate(project: Project) {
renderedTasks.clear()
taskStat.clear()

val allTasks = project.allRequestedTasks.toSet()
allTasks.forEach { task ->
taskStat.putIfAbsent(
task,
TaskStat(
task = task,
allTasks = allTasks,
rootProject = project
)
)
}
statHelper.collectFrom(project)

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

}

val topTasks = taskStat.values
.filter { it.allDependedOnCount <= 0 }
.map { it.task }
topTasks.forEach { render(it) }

printMostExpensiveTasksIfNeed()
printMostExpensiveModulesIfNeed()


}

private fun render(task: Task, lastChild: Boolean = true, depth: Int = 0) {
graphRenderer?.visit({
val taskStat = taskStat[task] ?: return@visit
val taskStat = statHelper.taskStat[task] ?: return@visit

printTaskShort(taskStat)

Expand Down Expand Up @@ -115,7 +84,7 @@ open class TaskTreeTask @Inject constructor(

private fun printMostExpensiveTasksIfNeed() {
if (ext.printMostExpensiveTasks) {
val allStat = taskStat.values
val allStat = statHelper.taskStat.values
.filter { it.complexPrice > 0 }
.sortedByDescending { it.complexPrice }
renderer.textOutput
Expand All @@ -134,7 +103,7 @@ open class TaskTreeTask @Inject constructor(

private fun printMostExpensiveModulesIfNeed() {
if (ext.printMostExpensiveModules) {
val allStat = taskStat.values
val allStat = statHelper.taskStat.values
.groupBy { it.task.project }
.map { (pr, stat) -> pr to stat.sumOf { it.complexPriceOutsideProject.toDouble() } }
.sortedByDescending { (_, price) -> price }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.klee0kai.tasktree.utils

import com.github.klee0kai.tasktree.tasks.DiagonDagTask
import com.github.klee0kai.tasktree.tasks.FlatListTask
import com.github.klee0kai.tasktree.tasks.TaskTreeTask
import org.gradle.api.Project
import org.gradle.api.Task
Expand All @@ -25,7 +26,7 @@ val Project.taskGraph get() = gradle.taskGraph as DefaultTaskExecutionGraph

val Project.allRequestedTasks
get() = taskGraph.allTasks
.filter { it !is TaskTreeTask && it !is DiagonDagTask }
.filter { it !is TaskTreeTask && it !is DiagonDagTask && it !is FlatListTask }

val Project.parents
get() = generateSequence(this) {
Expand Down