Skip to content

Commit 9af4e57

Browse files
authored
Merge pull request #6 from OndraBasler/feature/dependency-optimization
Optimize graph generation
2 parents 4f3c94e + a1e8944 commit 9af4e57

File tree

4 files changed

+72
-44
lines changed

4 files changed

+72
-44
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ gradle-app.setting
2727

2828
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
2929
gradle-wrapper.jar
30-
path/to/standalone/plugin/project/
30+
path/to/standalone/plugin/project/
31+
/local.properties

build.gradle.kts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ plugins {
55
id("java")
66
id("java-gradle-plugin")
77
id("maven-publish")
8-
kotlin("jvm") version "1.8.0"
9-
id("com.gradle.plugin-publish") version "1.2.1"
8+
kotlin("jvm") version "2.1.0"
9+
id("com.gradle.plugin-publish") version "1.3.0"
1010
}
1111

1212
repositories {
1313
mavenCentral()
1414
}
1515

16+
@Suppress("UnstableApiUsage")
1617
gradlePlugin {
1718
website.set("https://github.com/ivancarras/graphfity")
1819
vcsUrl.set("https://github.com/ivancarras/graphfity.git")
@@ -42,11 +43,4 @@ publishing {
4243
url = uri("path/to/standalone/plugin/project")
4344
}
4445
}
45-
}
46-
47-
dependencies {
48-
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.0")
49-
implementation("org.codehaus.groovy:groovy-all:3.0.16")
50-
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2")
51-
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2")
52-
}
46+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

src/main/kotlin/com/github/ivancarras/graphfity/plugin/task/GraphfityTask.kt

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,40 @@ abstract class GraphfityTask : DefaultTask() {
3434
val nodesLevel = HashMap<String, Int>()
3535
val dotFile = createDotFile(dotPath)
3636

37-
obtainDependenciesData(rootProject, nodes, dependencies, nodeTypes, nodesLevel)
38-
addNodesToFile(dotFile, nodes)
39-
addDependenciesToFile(dotFile, dependencies)
40-
addNodeLevelsToFile(dotFile, nodesLevel)
41-
generateGraph(dotFile)
37+
obtainNodesAndDependencies(
38+
project = rootProject,
39+
nodes = nodes,
40+
dependencies = dependencies,
41+
nodeTypes = nodeTypes
42+
)
43+
obtainNodesLevels(
44+
rootProjectName = projectRootName,
45+
dependencies = dependencies,
46+
nodeLevel = nodesLevel
47+
)
48+
addNodesToFile(
49+
dotFile = dotFile,
50+
nodes = nodes
51+
)
52+
addDependenciesToFile(
53+
dotFile = dotFile,
54+
dependencies = dependencies
55+
)
56+
addNodeLevelsToFile(
57+
dotFile = dotFile,
58+
nodeLevels = nodesLevel
59+
)
60+
generateGraph(
61+
dotFile = dotFile
62+
)
4263
}
4364

4465
private fun getRootProject(projectRootName: String): Project {
45-
return project.findProject(projectRootName)
46-
?: throw kotlin.IllegalArgumentException("The property provided as projectRootPath: $projectRootName does not correspond to any project")
66+
return requireNotNull(
67+
project.findProject(projectRootName)
68+
) {
69+
"The property provided as projectRootPath: $projectRootName does not correspond to any project"
70+
}
4771
}
4872

4973
private fun loadNodeTypes(nodeTypesPath: String): List<NodeType> {
@@ -86,55 +110,63 @@ abstract class GraphfityTask : DefaultTask() {
86110
}
87111
}
88112

89-
private fun obtainDependenciesData(
113+
private fun obtainNodesAndDependencies(
90114
project: Project,
91-
projects: HashSet<NodeData>,
115+
nodes: HashSet<NodeData>,
92116
dependencies: HashSet<Pair<NodeData, NodeData>>,
93117
nodeTypes: List<NodeType>,
94-
nodesLevel: HashMap<String, Int>,
95-
level: Int = 0
96118
) {
97119
val projectNodeData = mapProjectToNode(project, nodeTypes)
98120

99121
if (projectNodeData != null && projectNodeData.nodeType.isEnabled) {
100-
projects.add(projectNodeData)
101-
102-
val nodeLevel = nodesLevel[project.path]
103-
if (nodeLevel == null || level > nodeLevel) {
104-
nodesLevel[projectNodeData.path] = level
105-
}
122+
nodes.add(projectNodeData)
106123
}
107124

108125
project.configurations.forEach { config ->
109126
config.dependencies
110127
.withType(ProjectDependency::class.java)
111-
.map { it.dependencyProject }
128+
.map { project.project(it.path) }
112129
.filterNot { project == it.project }
113130
.forEach { dependencyProject ->
114131
val dependencyProjectNodeData = mapProjectToNode(dependencyProject, nodeTypes)
115132
if (dependencyProjectNodeData != null && projectNodeData != null &&
116133
dependencyProjectNodeData.nodeType.isEnabled
117134
) {
118-
projects.add(dependencyProjectNodeData)
135+
dependencies.add(Pair(projectNodeData, dependencyProjectNodeData))
119136

120-
val nodeLevel = nodesLevel[dependencyProjectNodeData.path]
121-
if (nodeLevel == null || level > nodeLevel) {
122-
nodesLevel[dependencyProjectNodeData.path] = level + 1
137+
if (dependencyProjectNodeData !in nodes) {
138+
obtainNodesAndDependencies(
139+
project = dependencyProject,
140+
nodes = nodes,
141+
dependencies = dependencies,
142+
nodeTypes = nodeTypes,
143+
)
123144
}
124-
dependencies.add(Pair(projectNodeData, dependencyProjectNodeData))
125-
obtainDependenciesData(
126-
dependencyProject,
127-
projects,
128-
dependencies,
129-
nodeTypes,
130-
nodesLevel,
131-
level + 1
132-
)
133145
}
134146
}
135147
}
136148
}
137149

150+
private fun obtainNodesLevels(
151+
rootProjectName: String,
152+
dependencies: HashSet<Pair<NodeData, NodeData>>,
153+
nodeLevel: HashMap<String, Int>,
154+
) {
155+
var currentLevel = listOf(rootProjectName)
156+
var level = 0
157+
while (currentLevel.isNotEmpty()) {
158+
currentLevel
159+
.forEach { nodeLevel[it] = level }
160+
161+
val nextLevel = dependencies
162+
.filter { it.first.path in currentLevel }
163+
.map { it.second.path }
164+
165+
currentLevel = nextLevel
166+
level++
167+
}
168+
}
169+
138170
private fun createDotFile(dotPath: String): File = File(dotPath + DOT_FILE).apply {
139171
delete()
140172
parentFile.mkdirs()
@@ -179,7 +211,8 @@ abstract class GraphfityTask : DefaultTask() {
179211
}
180212

181213
private fun addNodeLevelsToFile(
182-
dotFile: File, nodeLevels: HashMap<String, Int>
214+
dotFile: File,
215+
nodeLevels: HashMap<String, Int>
183216
) {
184217
nodeLevels.asSequence().groupBy({ it.value }, { it.key }).forEach {
185218
dotFile.appendText("\n{ rank=same;")

0 commit comments

Comments
 (0)