Skip to content

Commit

Permalink
[FEAT/#22] 의존 그래프 만들기
Browse files Browse the repository at this point in the history
  • Loading branch information
leeeyubin committed Jun 20, 2024
1 parent 81a2c91 commit 3c6f2ae
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 1 deletion.
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ plugins {
id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
id 'org.jetbrains.kotlin.jvm' version '1.9.0' apply false
id 'com.google.dagger.hilt.android' version '2.48.1' apply false
id "com.vanniktech.dependency.graph.generator" version "0.7.0"
}

ext {
Expand All @@ -19,4 +18,8 @@ allprojects {
jvmTarget = "1.8"
}
}
}

apply {
from("gradle/projectDependencyGraph.gradle")
}
127 changes: 127 additions & 0 deletions gradle/projectDependencyGraph.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
task projectDependencyGraph {
doLast {
def dot = new File(rootProject.rootDir, 'project.dot')
dot.parentFile.mkdirs()
dot.delete()

dot << 'digraph {\n'
dot << " graph [label=\"${rootProject.name}\\n \",labelloc=t,fontsize=30,ranksep=1.4];\n"
dot << ' node [style=filled, fillcolor="#bbbbbb"];\n'
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 androidDynamicFeatureProjects = []
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('kotlin2js')) {
jsProjects.add(project)
}
if (project.plugins.hasPlugin('com.android.library') ||
project.plugins.hasPlugin('com.android.application')) {
androidProjects.add(project)
}
if (project.plugins.hasPlugin('com.android.dynamic-feature')) {
androidDynamicFeatureProjects.add(project)
}
if (project.plugins.hasPlugin('java-library') || project.plugins.hasPlugin('java')) {
javaProjects.add(project)
}

project.configurations.all { config ->
if (config.name.toLowerCase().contains("test")) return
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 (androidDynamicFeatureProjects.contains(project)) {
traits.add('fillcolor="#c9baff"')
} 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 dotPath = "C:/Program Files/Graphviz/bin/dot"
def p = "${dotPath} -Tpng -O project.dot".execute([], dot.parentFile)

p.waitFor()
if (p.exitValue() != 0) {
throw new RuntimeException(p.errorStream.text)
}
dot.delete()

println("Project module dependency graph created at ${dot.absolutePath}.png")
}
}

0 comments on commit 3c6f2ae

Please sign in to comment.