From 495847f98505c98ec94b8d430ca2ad6480aa7aac Mon Sep 17 00:00:00 2001 From: klee0kai Date: Fri, 9 Aug 2024 21:08:15 +0400 Subject: [PATCH 1/2] tasks flat list. little fix to show ordered tasks in tree report --- .../klee0kai/tasktree/TaskTreePlugin.kt | 4 +- .../klee0kai/tasktree/tasks/FlatListTask.kt | 92 +++++++++++++++++++ .../klee0kai/tasktree/tasks/TaskStatHelper.kt | 51 ++++++++++ .../klee0kai/tasktree/tasks/TaskTreeTask.kt | 51 ++-------- .../klee0kai/tasktree/utils/ProjectExt.kt | 3 +- 5 files changed, 158 insertions(+), 43 deletions(-) create mode 100644 tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/FlatListTask.kt create mode 100644 tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/TaskStatHelper.kt diff --git a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/TaskTreePlugin.kt b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/TaskTreePlugin.kt index f90913a..a2b0415 100644 --- a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/TaskTreePlugin.kt +++ b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/TaskTreePlugin.kt @@ -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 @@ -15,9 +16,10 @@ open class TaskTreePlugin : Plugin { 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 diff --git a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/FlatListTask.kt b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/FlatListTask.kt new file mode 100644 index 0000000..ad9b8ed --- /dev/null +++ b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/FlatListTask.kt @@ -0,0 +1,92 @@ +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, + lastChild = true, + depth = 0, + ) + } + + } + + private fun render(task: Task, lastChild: Boolean = true, depth: Int = 0) { + 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 }} ] ") + + }, lastChild) + } + + 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 + + +} + + diff --git a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/TaskStatHelper.kt b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/TaskStatHelper.kt new file mode 100644 index 0000000..6caf860 --- /dev/null +++ b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/TaskStatHelper.kt @@ -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() + + 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 + } + } + } + } + +} \ No newline at end of file diff --git a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/TaskTreeTask.kt b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/TaskTreeTask.kt index 412c7ab..266360e 100644 --- a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/TaskTreeTask.kt +++ b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/TaskTreeTask.kt @@ -14,59 +14,28 @@ open class TaskTreeTask @Inject constructor( ) : BaseReportTask() { private val renderedTasks = mutableSetOf() - private val taskStat = mutableMapOf() + 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) @@ -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 @@ -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 } diff --git a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/utils/ProjectExt.kt b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/utils/ProjectExt.kt index 031276e..2882054 100644 --- a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/utils/ProjectExt.kt +++ b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/utils/ProjectExt.kt @@ -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 @@ -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) { From 0ad97efe42f65aba7cf895c064569f4e44a8fe65 Mon Sep 17 00:00:00 2001 From: klee0kai Date: Fri, 9 Aug 2024 21:10:17 +0400 Subject: [PATCH 2/2] optimize code changes --- .../github/klee0kai/tasktree/tasks/FlatListTask.kt | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/FlatListTask.kt b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/FlatListTask.kt index ad9b8ed..1d2fe6d 100644 --- a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/FlatListTask.kt +++ b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/FlatListTask.kt @@ -23,17 +23,11 @@ open class FlatListTask @Inject constructor( statHelper.collectFrom(project) val allTasksOrdered = project.allRequestedTasks - allTasksOrdered.forEach { - render( - task = it, - lastChild = true, - depth = 0, - ) - } + allTasksOrdered.forEach { render(task = it) } } - private fun render(task: Task, lastChild: Boolean = true, depth: Int = 0) { + private fun render(task: Task) { graphRenderer?.visit({ val taskStat = statHelper.taskStat[task] ?: return@visit @@ -59,7 +53,7 @@ open class FlatListTask @Inject constructor( withStyle(Description) .text(" outputs: [ ${outputs.joinToString { it.path }} ] ") - }, lastChild) + }, /*last child */ true) } private fun StyledTextOutput.printTaskShort(taskStat: TaskStat) = apply {