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
7 changes: 6 additions & 1 deletion .run/taskTree.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,26 @@
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="--stacktrace" />
<option name="scriptParameters" value="--rerun-tasks" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="taskTree" />
<option value="--outputJson" />
<option value="file:/$PROJECT_DIR$/output.json" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<ExternalSystemDebugDisabled>false</ExternalSystemDebugDisabled>
<DebugAllEnabled>false</DebugAllEnabled>
<RunAsTest>false</RunAsTest>
<GradleProfilingDisabled>false</GradleProfilingDisabled>
<GradleCoverageDisabled>false</GradleCoverageDisabled>
<method v="2" />
</configuration>
</component>
23 changes: 22 additions & 1 deletion libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,35 @@
[versions]

tasktree = "0.0.12"
tasktree = "0.0.13"

kotlin = "2.2.21"
kotlin-serialization = "1.10.0"
ktor = "3.1.3"

[libraries]

kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlin-serialization" }

ktor-serialization-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-utils = { group = "io.ktor", name = "ktor-utils", version.ref = "ktor" }
ktor-io = { group = "io.ktor", name = "ktor-io", version.ref = "ktor" }

ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor" }
ktor-client-okhttp = { group = "io.ktor", name = "ktor-client-okhttp", version.ref = "ktor" }
ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" }
ktor-client-logging = { group = "io.ktor", name = "ktor-client-logging", version.ref = "ktor" }
ktor-client-android = { group = "io.ktor", name = "ktor-client-android", version.ref = "ktor" }
ktor-client-plugins = { group = "io.ktor", name = "ktor-client-plugins", version.ref = "ktor" }

[bundles]

ktor-common = ["ktor-serialization-json", "ktor-utils", "ktor-io"]
ktor-client = ["ktor-client-core", "ktor-client-okhttp", "ktor-client-content-negotiation",
"ktor-client-logging", "ktor-client-android"]

[plugins]

publish-plugin = { id = "com.gradle.plugin-publish", version = "1.1.0" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
tasktree = { id = "com.github.klee0kai.tasktree", version.ref = "tasktree" }

6 changes: 4 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Apply plugin in your module's `build.gradle`:

```kotlin
plugins {
id("com.github.klee0kai.tasktree") version "0.0.12"
id("com.github.klee0kai.tasktree") version "0.0.13"
}

tasktree {
Expand All @@ -20,6 +20,8 @@ tasktree {
}
```

All params available [here](https://github.com/klee0kai/tasktree/blob/dev/tasktree/src/main/kotlin/com/github/klee0kai/tasktree/TaskTreeExtension.kt)

Project build report in the form of a build graph. [Diagon](https://github.com/ArthurSonzogni/Diagon) must be installed

```bash
Expand Down Expand Up @@ -66,7 +68,7 @@ initscript {
maven(url = "https://jitpack.io")
}
dependencies {
classpath("com.github.klee0kai:tasktree:0.0.12")
classpath("com.github.klee0kai:tasktree:0.0.13")
}
}

Expand Down
4 changes: 4 additions & 0 deletions tasktree/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
`kotlin-dsl`
`java-gradle-plugin`
alias(libs.plugins.publish.plugin)
alias(libs.plugins.kotlin.serialization)
}

group = libs.plugins.tasktree.get().pluginId
Expand All @@ -23,6 +24,9 @@ tasks.withType<Test>().configureEach {

dependencies {
implementation(gradleApi())
implementation(libs.kotlinx.serialization.json)
implementation(libs.bundles.ktor.common)
implementation(libs.bundles.ktor.client)
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.github.klee0kai.tasktree

open class TaskTreeExtension {
import org.gradle.api.provider.Property
import java.net.URL

abstract class TaskTreeExtension {

/**
* Graph max depth
Expand Down Expand Up @@ -38,6 +41,15 @@ open class TaskTreeExtension {
*/
var printMostExpensive: Boolean = false


/**
* output url
* Examples :
* - file:/home/user/test.txt
* - http://localhost:2334/
*/
abstract val output: Property<URL>

}


Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,18 @@ open class TaskTreePlugin : Plugin<Project> {
val flatlist = tasks.register("flatList", FlatListTask::class.java, ext)

taskGraph.whenReady {
val isTaskTreeRequested =
hasTask(taskTree.get()) || hasTask(taskDag.get()) || hasTask(flatlist.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
@@ -1,15 +1,14 @@
package com.github.klee0kai.tasktree.info

import org.gradle.api.tasks.diagnostics.internal.ProjectDetails

class TaskInfo(
val id: Int = 0,
val path: String,
val taskName: String,
val group: String,
val description: String,
val termDir: String,
val className: Class<*>? = null,
val simpleClassName: String? = null,
val projectName: String? = null,
val projectDetails: ProjectDetails? = null,
val rootProjectDetails: ProjectDetails? = null,
val dependencies: MutableList<TaskInfo> = mutableListOf()
val dependencies: MutableList<TaskInfo> = mutableListOf(),
)

Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package com.github.klee0kai.tasktree.info

import org.gradle.api.tasks.diagnostics.internal.ProjectDetails
import java.util.*

class TaskStat(
val id: Int = 0,
val path: String,
val taskName: String,
val className: Class<*>? = null,
val simpleClassName: String? = null,
val projectName: String? = null,
val projectDetails: ProjectDetails? = null,
val rootProjectDetails: ProjectDetails? = null,
val dependencies: MutableSet<TaskStat> = mutableSetOf(),
val dependedOnTasks: MutableSet<TaskStat> = mutableSetOf(),
) {
Expand Down Expand Up @@ -43,45 +40,46 @@ class TaskStat(
private set
get() {
if (field.isNotEmpty()) return field
val checked = mutableMapOf<Int, List<TaskStat>>()
val checked = mutableMapOf<String, List<TaskStat>>()
val deps = LinkedList(dependencies.map { listOf(this@TaskStat, it) }.toMutableList())
while (deps.isNotEmpty()) {
val dep = deps.pollFirst()
val checkedDepthDeps = checked.getOrDefault(dep.last().id, emptyList())
val checkedDepthDeps = checked.getOrDefault(dep.last().path, emptyList())
if (checkedDepthDeps.size >= dep.size
|| checkedDepthDeps.isNotEmpty()
&& dep.take(checkedDepthDeps.size).map { it.id } == checkedDepthDeps.map { it.id } // ignore doubles
&& dep.take(checkedDepthDeps.size)
.map { it.path } == checkedDepthDeps.map { it.path } // ignore doubles
) {
continue
}
checked[dep.last().id] = dep
deps.removeAll { task -> task.last().id in dep.last().dependencies.map { it.id } }
checked[dep.last().path] = dep
deps.removeAll { task -> task.last().path in dep.last().dependencies.map { it.path } }
deps.addAll(0, dep.last().dependencies.map { dep + it })
}
field = checked.values.maxByOrNull { it.size } ?: emptyList()
return field
}

val allDependencies = sequence {
val sent = mutableSetOf<Int>()
val sent = mutableSetOf<String>()
val deps = LinkedList(dependencies.toMutableList())
while (deps.isNotEmpty()) {
val dep = deps.pollFirst()
if (sent.contains(dep.id)) continue
if (sent.contains(dep.path)) continue
yield(dep)
sent.add(dep.id)
sent.add(dep.path)
deps.addAll(dep.dependencies)
}
}

val allDependedOnTasks = sequence {
val sent = mutableSetOf<Int>()
val sent = mutableSetOf<String>()
val deps = LinkedList(dependedOnTasks.toMutableList())
while (deps.isNotEmpty()) {
val dep = deps.pollFirst()
if (sent.contains(dep.id)) continue
if (sent.contains(dep.path)) continue
yield(dep)
sent.add(dep.id)
sent.add(dep.path)
deps.addAll(dep.dependedOnTasks)
}
}
Expand All @@ -99,11 +97,9 @@ class TaskStat(

fun TaskInfo.toTaskStat(
) = TaskStat(
id,
taskName,
className,
simpleClassName,
projectName,
projectDetails,
rootProjectDetails,
path = path,
taskName = taskName,
className = className,
simpleClassName = simpleClassName,
projectName = projectName,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,30 @@ package com.github.klee0kai.tasktree.info
import com.github.klee0kai.tasktree.utils.fullName
import com.github.klee0kai.tasktree.utils.simpleClassName
import org.gradle.api.Project
import org.gradle.api.tasks.diagnostics.internal.ProjectDetails

object TaskStatHelper {

fun collectAllTasksInfo(project: Project): List<TaskInfo> {
val allTasks = project.tasks.toList()
val tasksInfos = allTasks.map { task ->

TaskInfo(
id = System.identityHashCode(task),
path = task.path,
taskName = task.name,
group = task.group ?: "",
description = task.description ?: "",
termDir = task.temporaryDir.path,
className = task::class.java,
simpleClassName = task.simpleClassName,
projectName = project.fullName,
projectDetails = ProjectDetails.of(project),
rootProjectDetails = ProjectDetails.of(project.rootProject),
)
}.associateBy { task -> task.id }
}.associateBy { task -> task.path }

allTasks.forEach { task ->
runCatching {
task.taskDependencies.getDependencies(task).forEach { dependsOn ->
val taskStat = tasksInfos[System.identityHashCode(dependsOn)] ?: return@forEach
tasksInfos[System.identityHashCode(task)]?.dependencies?.add(taskStat)
val taskStat = tasksInfos[dependsOn.path] ?: return@forEach
tasksInfos[dependsOn.path]?.dependencies?.add(taskStat)
}
}
}
Expand All @@ -34,7 +35,7 @@ object TaskStatHelper {

fun calcToTaskStats(taskInfos: List<TaskInfo>): List<TaskStat> {
val taskStats = taskInfos.map { taskInfo -> taskInfo.toTaskStat() }
.associateBy { task -> task.id }
.associateBy { task -> task.path }

taskStats.values.forEach { task ->
task.allTasksCount = taskInfos.size
Expand All @@ -43,7 +44,7 @@ object TaskStatHelper {

taskInfos.forEach { taskInfo ->
taskInfo.dependencies.forEach { dependsOn ->
taskStats[taskInfo.id]?.dependencies?.add(taskStats[dependsOn.id] ?: return@forEach)
taskStats[taskInfo.path]?.dependencies?.add(taskStats[dependsOn.path] ?: return@forEach)
}
}

Expand All @@ -65,11 +66,11 @@ object TaskStatHelper {

fun filterByRequestedTasks(
tasksStats: List<TaskStat>,
allRequestedTasksIds: Set<Int>,
allRequestedTasksIds: Set<String>,
): List<TaskStat> {
if (allRequestedTasksIds.isEmpty()) return tasksStats
return tasksStats.filter {
it.id in allRequestedTasksIds
it.path in allRequestedTasksIds
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.github.klee0kai.tasktree.output

import kotlinx.serialization.Serializable

@Serializable
data class ProjectNode(
val id: Int,
val name: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.github.klee0kai.tasktree.output

import com.github.klee0kai.tasktree.info.TaskInfo
import kotlinx.serialization.Serializable

@Serializable
data class TaskNode(
val path: String,
val name: String,
val className: String,
val projectName: String,
val group: String,
val description: String,
val termDir: String,
val dependencies: List<String> = mutableListOf(),
)


fun TaskInfo.toTaskNode(
): TaskNode = TaskNode(
path = path,
name = taskName,
group = group,
description = description,
termDir = termDir,
className = className!!.canonicalName,
projectName = projectName ?: "",
dependencies = dependencies.map { it.path }.toSet().toList(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.github.klee0kai.tasktree.output

import kotlinx.serialization.Serializable

@Serializable
data class TaskTreeResult(
val projects: List<ProjectNode>,
val tasks: List<TaskNode>,
)
Loading
Loading