diff --git a/.run/diagonDAG.run.xml b/.run/diagonDAG.run.xml new file mode 100644 index 0000000..0573e23 --- /dev/null +++ b/.run/diagonDAG.run.xml @@ -0,0 +1,25 @@ + + + + + + + false + true + false + true + + + \ No newline at end of file diff --git a/.run/tasktree.run.xml b/.run/tasktree.run.xml new file mode 100644 index 0000000..9973e59 --- /dev/null +++ b/.run/tasktree.run.xml @@ -0,0 +1,25 @@ + + + + + + + false + true + false + true + + + \ No newline at end of file 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 ccd17ca..782dbc7 100644 --- a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/TaskTreePlugin.kt +++ b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/TaskTreePlugin.kt @@ -1,8 +1,8 @@ package com.github.klee0kai.tasktree +import com.github.klee0kai.tasktree.tasks.DiagonDagTask import com.github.klee0kai.tasktree.tasks.TaskTreeTask -import com.github.klee0kai.tasktree.utils.isTaskTreeRequested -import com.github.klee0kai.tasktree.utils.taskGraph +import com.github.klee0kai.tasktree.utils.* import org.gradle.api.Plugin import org.gradle.api.Project @@ -13,11 +13,15 @@ open class TaskTreePlugin : Plugin { private fun Project.applyOnProject() { val ext = extensions.create("tasktree", TaskTreeExtension::class.java) tasks.register("tasktree", TaskTreeTask::class.java, ext) + tasks.register("diagonDAG", DiagonDagTask::class.java) taskGraph.whenReady { - if (isTaskTreeRequested) { - tasks.filter { it !is TaskTreeTask } - .forEach { it.enabled = false } + if (isTaskTreeRequested || isDiagonGraphRequested) { + requestedTasks + ?.flatMap { project.taskGraph.getAllDeps(it) } + ?.forEach { + it.enabled = false + } } } } diff --git a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/DiagonDagTask.kt b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/DiagonDagTask.kt new file mode 100644 index 0000000..1b3c8c2 --- /dev/null +++ b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/tasks/DiagonDagTask.kt @@ -0,0 +1,72 @@ +package com.github.klee0kai.tasktree.tasks + +import com.github.klee0kai.tasktree.utils.* +import org.apache.tools.ant.util.TeeOutputStream +import org.gradle.api.Project +import org.gradle.api.model.ObjectFactory +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.diagnostics.ProjectReportTask +import org.gradle.process.internal.ExecActionFactory +import org.gradle.process.internal.ExecException +import java.io.ByteArrayOutputStream +import java.io.IOException +import javax.inject.Inject + +open class DiagonDagTask @Inject constructor( + @Input + val objectFactory: ObjectFactory, + @Input + val execAction: ExecActionFactory, +) : ProjectReportTask() { + + @Internal + override fun getDescription(): String = + "Draw tasktree graph use Diagon. More: https://github.com/ArthurSonzogni/Diagon" + + + override fun generate(project: Project) { + super.generate(project) + val allTasks = project.requestedTasks?.flatMap { + setOf(it) + project.taskGraph.getAllDeps(it) + }?.toSet() ?: emptySet() + + + val depsCode = allTasks.joinToString("\n") { task -> + project.taskGraph.getDeps(task).joinToString("\n") { dep -> + "${dep.fullName} -> ${task.fullName}" + } + } + + val result = sh(cmd = arrayOf("diagon", "GraphDAG"), input = depsCode) + + println("------------------ Diagon DAG graph ----------- ") + println(result) + println("------------------ ---------------- ----------- ") + } + + + private fun sh(cmd: Array, input: String): String { + val execAction = execAction.newExecAction() + + val localErrStream = ByteArrayOutputStream() + val localOutputStream = ByteArrayOutputStream() + + try { + execAction.commandLine(*cmd) + execAction.errorOutput = TeeOutputStream(localErrStream, System.err) + execAction.standardInput = input.byteInputStream() + execAction.standardOutput = localOutputStream + val result = execAction.execute() + + if (result.exitValue != 0) { + throw ExecException("Cmd ${cmd.joinToString(" ")} finished with exit code ${result.exitValue}") + } + return String(localOutputStream.toByteArray()) + } catch (e: Exception) { + val errStreamText = String(localErrStream.toByteArray()) + throw IOException("can't run ${cmd.joinToString(" ")}\n ${e.message} $errStreamText", e) + } + } + +} \ 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 d9a78d5..7fb34e0 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 @@ -52,7 +52,7 @@ open class TaskTreeTask @Inject constructor( } withStyle(Identifier) - .text(task.name) + .text(task.fullName) if (ext.printPrice) { withStyle(Description) 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 96e8c35..61088f5 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,5 +1,6 @@ package com.github.klee0kai.tasktree.utils +import com.github.klee0kai.tasktree.tasks.DiagonDagTask import com.github.klee0kai.tasktree.tasks.TaskTreeTask import org.gradle.api.Project import org.gradle.api.Task @@ -13,7 +14,14 @@ val Project.executionPlan get() = taskGraph.executionPlan val Project.isTaskTreeRequested get() = executionPlan?.requestedTasks?.any { it is TaskTreeTask } ?: false -val Project.requestedTasks get() = executionPlan?.requestedTasks?.filter { it !is TaskTreeTask } +val Project.isDiagonGraphRequested get() = executionPlan?.requestedTasks?.any { it is DiagonDagTask } ?: false + +val Project.requestedTasks + get() = executionPlan?.requestedTasks?.filter { + it !is TaskTreeTask && it !is DiagonDagTask + } + +val Project.parents get() = generateSequence(this) { it.parent } fun DefaultTaskExecutionGraph.getAllDeps(task: Task): Set = getDeps(task) diff --git a/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/utils/TaskExt.kt b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/utils/TaskExt.kt new file mode 100644 index 0000000..8f0e9ee --- /dev/null +++ b/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/utils/TaskExt.kt @@ -0,0 +1,16 @@ +package com.github.klee0kai.tasktree.utils + +import org.gradle.api.Task + +val Task.fullName + get() = buildString { + project.parents + .toList() + .reversed() + .forEach { project -> + val isRoot = project.parent == null + if (!isRoot) append(":${project.name}") + } + append(":${name}") + } +