dev.sunnyday.test.impact.plugin.domain.graph.ProjectGraphResolver.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of test-impact-plugin Show documentation
Show all versions of test-impact-plugin Show documentation
Skip test runtime of unchanged gradle modules
package dev.sunnyday.test.impact.plugin.domain.graph
import dev.sunnyday.test.impact.plugin.domain.model.ImpactProject
import dev.sunnyday.test.impact.plugin.domain.model.ProjectPath
import org.gradle.api.Project
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.kotlin.dsl.withType
internal class ProjectGraphResolver(
rootProject: Project,
) {
private val projects = getProjectsMap(rootProject)
private val roots = projects.values.mapTo(hashSetOf(), ImpactProject::path)
private val graph = projects.values.associateTo(hashMapOf()) { it.path to mutableListOf() }
private val pathTrie = buildProjectsPathTrie(projects.values)
var isCompleted: Boolean = false
private set
private fun getProjectsMap(rootProject: Project): Map {
return hashMapOf().apply {
val projectsQueue = ArrayDeque()
projectsQueue.add(rootProject)
while (projectsQueue.isNotEmpty()) {
val project = projectsQueue.removeFirst()
project.childProjects.values.forEach(projectsQueue::add)
this[project.path] = ImpactProject(
path = project.path,
dirPath = project.relativePathToRoot,
)
}
}
}
fun onProjectEvaluated(project: Project) {
val impactProject = projects.getValue(project.path)
var isRemovedFromRoots = false
val configurationNameRegEx = "(?i).*(api|implementation)$".toRegex()
project.configurations
.filter { it.name.matches(configurationNameRegEx) }
.flatMap { configuration ->
configuration.dependencies.withType()
.map { dependency -> configuration to dependency }
}
.forEach { (configuration, dependency) ->
if (!isRemovedFromRoots && !configuration.name.contains("test", ignoreCase = true)) {
roots.remove(impactProject.path)
isRemovedFromRoots = true
}
val dependencyNode = projects.getValue(dependency.dependencyProject.path)
val dependencyList = graph.getValue(dependencyNode.path)
dependencyList.add(impactProject.path)
}
}
fun getProjectsGraph(): ImpactProjectGraph {
return ImpactProjectGraph(
roots = roots,
projects = projects,
graph = graph,
filePathTrie = pathTrie,
)
}
fun markGraphCompleted() {
isCompleted = true
}
private fun buildProjectsPathTrie(projects: Iterable): ProjectFilePathTrie {
val trie = ProjectFilePathTrie()
projects.forEach(trie::add)
return trie
}
private val Project.relativePathToRoot: String
get() = projectDir.relativeTo(rootDir).path
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy