|
| 1 | +// import org.gradle.api.Plugin |
| 2 | +// import org.gradle.api.Project |
| 3 | +// import org.gradle.api.artifacts.ProjectDependency |
| 4 | +// import java.util.Locale |
| 5 | +// |
| 6 | +// class ProjectDependencyGraphPlugin : Plugin<Project> { |
| 7 | +// override fun apply(target: Project) { |
| 8 | +// // from: https://github.com/JakeWharton/SdkSearch/blob/3351cad9bfacb0a364858e843774147143f58c7a/gradle/projectDependencyGraph.gradle |
| 9 | +// // you need to command `brew install graphviz` |
| 10 | +// with(target) { |
| 11 | +// task("projectDependencyGraph") { |
| 12 | +// doLast { |
| 13 | +// val dot = rootProject.buildDir.resolve("reports/dependency-graph/project.dot") |
| 14 | +// dot.parentFile.mkdirs() |
| 15 | +// dot.delete() |
| 16 | +// |
| 17 | +// dot.writeText("digraph {\n") |
| 18 | +// dot.appendText(" graph [label=\"${rootProject.name}\\n \",labelloc=t,fontsize=30,ranksep=1.4];\n") |
| 19 | +// dot.appendText(" node [style=filled, fillcolor=\"#bbbbbb\"];\n") |
| 20 | +// dot.appendText(" rankdir=TB;\n") |
| 21 | +// val rootProjects = mutableListOf(rootProject) |
| 22 | +// val queue: MutableList<Project> = mutableListOf(rootProject) |
| 23 | +// |
| 24 | +// while (queue.isNotEmpty()) { |
| 25 | +// val project = queue.removeAt(0) |
| 26 | +// rootProjects.add(project) |
| 27 | +// queue.addAll(project.childProjects.values) |
| 28 | +// } |
| 29 | +// var projects = mutableSetOf<Project>() |
| 30 | +// val dependencies = mutableMapOf<Pair<Project, Project>, List<String>>() |
| 31 | +// val multiplatformProjects = mutableListOf<Project>() |
| 32 | +// val jsProjects = mutableListOf<Project>() |
| 33 | +// val androidProjects = mutableListOf<Project>() |
| 34 | +// val javaProjects = mutableListOf<Project>() |
| 35 | +// |
| 36 | +// queue.add(rootProject) |
| 37 | +// while (queue.isNotEmpty()) { |
| 38 | +// val project = queue.removeAt(0) |
| 39 | +// queue.addAll(project.childProjects.values) |
| 40 | +// |
| 41 | +// if (project.plugins.hasPlugin("org.jetbrains.kotlin.multiplatform")) { |
| 42 | +// multiplatformProjects.add(project) |
| 43 | +// } |
| 44 | +// if (project.plugins.hasPlugin("kotlin2js")) { |
| 45 | +// jsProjects.add(project) |
| 46 | +// } |
| 47 | +// if (project.plugins.hasPlugin("com.android.library") || project.plugins.hasPlugin( |
| 48 | +// "com.android.application" |
| 49 | +// ) |
| 50 | +// ) { |
| 51 | +// androidProjects.add(project) |
| 52 | +// } |
| 53 | +// if (project.plugins.hasPlugin("java-library") || project.plugins.hasPlugin("java")) { |
| 54 | +// javaProjects.add(project) |
| 55 | +// } |
| 56 | +// |
| 57 | +// project.configurations.forEach { config -> |
| 58 | +// config.dependencies |
| 59 | +// .withType(ProjectDependency::class.java) |
| 60 | +// .forEach { dependency -> |
| 61 | +// val graphKey = Pair(project, dependency.dependencyProject) |
| 62 | +// projects.add(project) |
| 63 | +// projects.add(dependency.dependencyProject) |
| 64 | +// rootProjects.remove(dependency.dependencyProject) |
| 65 | +// val traits = |
| 66 | +// dependencies.computeIfAbsent(graphKey) { mutableListOf<String>() } |
| 67 | +// .toMutableList() |
| 68 | +// |
| 69 | +// if (config.name.lowercase().endsWith("implementation")) { |
| 70 | +// traits.add("style=dotted") |
| 71 | +// } |
| 72 | +// } |
| 73 | +// } |
| 74 | +// } |
| 75 | +// |
| 76 | +// projects = projects.sortedBy { it.path }.toHashSet() |
| 77 | +// |
| 78 | +// dot.appendText("\n # Projects\n\n") |
| 79 | +// for (project in projects) { |
| 80 | +// val traits = mutableListOf<String>() |
| 81 | +// |
| 82 | +// if (rootProjects.contains(project)) { |
| 83 | +// traits.add("shape=box") |
| 84 | +// } |
| 85 | +// |
| 86 | +// if (multiplatformProjects.contains(project)) { |
| 87 | +// traits.add("fillcolor=\"#ffd2b3\"") |
| 88 | +// } else if (jsProjects.contains(project)) { |
| 89 | +// traits.add("fillcolor=\"#ffffba\"") |
| 90 | +// } else if (androidProjects.contains(project)) { |
| 91 | +// traits.add("fillcolor=\"#baffc9\"") |
| 92 | +// } else if (javaProjects.contains(project)) { |
| 93 | +// traits.add("fillcolor=\"#ffb3ba\"") |
| 94 | +// } else { |
| 95 | +// traits.add("fillcolor=\"#eeeeee\"") |
| 96 | +// } |
| 97 | +// |
| 98 | +// dot.appendText(" \"${project.path}\" [${traits.joinToString(", ")}];\n") |
| 99 | +// } |
| 100 | +// |
| 101 | +// dot.appendText("\n {rank = same;") |
| 102 | +// for (project in projects) { |
| 103 | +// if (rootProjects.contains(project)) { |
| 104 | +// dot.appendText(" \"${project.path}\";") |
| 105 | +// } |
| 106 | +// } |
| 107 | +// dot.appendText("}\n") |
| 108 | +// |
| 109 | +// dot.appendText("\n # Dependencies\n\n") |
| 110 | +// dependencies.forEach { (key, traits) -> |
| 111 | +// dot.appendText(" \"${key.first.path}\" -> \"${key.second.path}\"") |
| 112 | +// if (traits.isNotEmpty()) { |
| 113 | +// dot.appendText(" [${traits.joinToString(", ")}]") |
| 114 | +// } |
| 115 | +// dot.appendText("\n") |
| 116 | +// } |
| 117 | +// |
| 118 | +// dot.appendText("}\n") |
| 119 | +// val p = ProcessBuilder("dot", "-Tpng", "-O", "project.dot").start() |
| 120 | +// p.waitFor() |
| 121 | +// if (p.exitValue() != 0) { |
| 122 | +// throw RuntimeException(p.errorStream.toString()) |
| 123 | +// } |
| 124 | +// |
| 125 | +// println("Project module dependency graph created at ${dot.absolutePath}.png") |
| 126 | +// } |
| 127 | +// } |
| 128 | +// } |
| 129 | +// } |
| 130 | +// } |
0 commit comments