diff options
Diffstat (limited to 'gradle/dependencyGraph.gradle')
-rw-r--r-- | gradle/dependencyGraph.gradle | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/gradle/dependencyGraph.gradle b/gradle/dependencyGraph.gradle new file mode 100644 index 0000000..29eafa4 --- /dev/null +++ b/gradle/dependencyGraph.gradle @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2021 E FOUNDATION + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +/** + * Taken from https://github.com/JakeWharton/SdkSearch/blob/master/gradle/projectDependencyGraph.gradle + */ + +def font = "Helvetica" + +task projectDependencyGraph { + doLast { + def dot = new File(rootProject.buildDir, 'reports/dependency-graph/project.dot') + dot.parentFile.mkdirs() + dot.delete() + + dot << 'digraph {\n' + dot << " graph [label=\"${rootProject.name}\\n \",labelloc=t,fontsize=30,ranksep=1.4,fontname=\"$font\"];\n" + dot << " node [style=filled, fillcolor=\"#bbbbbb\", fontname=\"$font\"];\n" + dot << " edge [fontname = \"$font\"];" + dot << ' rankdir=TB;\n' + + def rootProjects = [] + def queue = [rootProject] + while (!queue.isEmpty()) { + def project = queue.remove(0) + rootProjects.add(project) + queue.addAll(project.childProjects.values()) + } + + def projects = new LinkedHashSet<Project>() + def dependencies = new LinkedHashMap<Tuple2<Project, Project>, List<String>>() + def multiplatformProjects = [] + def jsProjects = [] + def androidProjects = [] + def javaProjects = [] + + queue = [rootProject] + while (!queue.isEmpty()) { + def project = queue.remove(0) + queue.addAll(project.childProjects.values()) + + if (project.plugins.hasPlugin('org.jetbrains.kotlin.multiplatform')) { + multiplatformProjects.add(project) + } + if (project.plugins.hasPlugin('org.jetbrains.kotlin.js')) { + jsProjects.add(project) + } + if (project.plugins.hasPlugin('com.android.library') || project.plugins.hasPlugin('com.android.application')) { + androidProjects.add(project) + } + if (project.plugins.hasPlugin('java-library') || project.plugins.hasPlugin('java')) { + javaProjects.add(project) + } + + project.configurations.all { config -> + config.dependencies + .withType(ProjectDependency) + .collect { it.dependencyProject } + .each { dependency -> + projects.add(project) + projects.add(dependency) + rootProjects.remove(dependency) + + def graphKey = new Tuple2<Project, Project>(project, dependency) + def traits = dependencies.computeIfAbsent(graphKey) { new ArrayList<String>() } + + if (config.name.toLowerCase().endsWith('implementation')) { + traits.add('style=dotted') + } + } + } + } + + projects = projects.sort { it.path } + + dot << '\n # Projects\n\n' + for (project in projects) { + def traits = [] + + if (rootProjects.contains(project)) { + traits.add('shape=box') + } + + if (multiplatformProjects.contains(project)) { + traits.add('fillcolor="#ffd2b3"') + } else if (jsProjects.contains(project)) { + traits.add('fillcolor="#ffffba"') + } else if (androidProjects.contains(project)) { + traits.add('fillcolor="#baffc9"') + } else if (javaProjects.contains(project)) { + traits.add('fillcolor="#ffb3ba"') + } else { + traits.add('fillcolor="#eeeeee"') + } + + dot << " \"${project.path}\" [${traits.join(", ")}];\n" + } + + dot << '\n {rank = same;' + for (project in projects) { + if (rootProjects.contains(project)) { + dot << " \"${project.path}\";" + } + } + dot << '}\n' + + dot << '\n # Dependencies\n\n' + dependencies.forEach { key, traits -> + dot << " \"${key.first.path}\" -> \"${key.second.path}\"" + if (!traits.isEmpty()) { + dot << " [${traits.join(", ")}]" + } + dot << '\n' + } + + dot << '}\n' + + def p = 'dot -Tpng -O project.dot'.execute([], dot.parentFile) + p.waitFor() + if (p.exitValue() != 0) { + throw new RuntimeException(p.errorStream.text) + } + + println("Project module dependency graph created at ${dot.absolutePath}.png") + } +}
\ No newline at end of file |