Skip to content

Commit d89407b

Browse files
authored
Support usage in projects using Gradle 8.10 by avoiding using Project.equals (#257)
* Replace usage of Set<Project> with Map<ProjectPath, Project> to avoid Project inequivalence in newer Gradle versions * Fix compilation error in sample project
1 parent cd343a9 commit d89407b

File tree

5 files changed

+183
-67
lines changed

5 files changed

+183
-67
lines changed

Diff for: affectedmoduledetector/src/main/kotlin/com/dropbox/affectedmoduledetector/AffectedModuleDetector.kt

+20-12
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ import java.io.File
5656
*/
5757
enum class ProjectSubset { DEPENDENT_PROJECTS, CHANGED_PROJECTS, ALL_AFFECTED_PROJECTS, NONE }
5858

59+
/**
60+
* An identifier for a project, ensuring that projects are always identified by their path.
61+
*/
62+
@JvmInline
63+
value class ProjectPath(val path: String)
64+
5965
/**
6066
* A utility class that can discover which files are changed based on git history.
6167
*
@@ -344,7 +350,7 @@ class AffectedModuleDetectorImpl constructor(
344350
}
345351

346352
private val allProjects by lazy {
347-
rootProject.subprojects.toSet()
353+
rootProject.subprojects.associateBy { it.projectPath }
348354
}
349355

350356
private val projectGraph by lazy {
@@ -369,7 +375,7 @@ class AffectedModuleDetectorImpl constructor(
369375

370376
override fun shouldInclude(project: Project): Boolean {
371377
val isRootProject = project.isRoot
372-
val isProjectAffected = affectedProjects.contains(project)
378+
val isProjectAffected = affectedProjects.contains(project.projectPath)
373379
val isProjectProvided = isProjectProvided2(project)
374380
val isModuleExcludedByName = config.excludedModules.contains(project.name)
375381
val isModuleExcludedByRegex = config.excludedModules.any { project.path.matches(it.toRegex()) }
@@ -390,10 +396,10 @@ class AffectedModuleDetectorImpl constructor(
390396

391397
override fun getSubset(project: Project): ProjectSubset {
392398
return when {
393-
changedProjects.contains(project) -> {
399+
changedProjects.contains(project.projectPath) -> {
394400
ProjectSubset.CHANGED_PROJECTS
395401
}
396-
dependentProjects.contains(project) -> {
402+
dependentProjects.contains(project.projectPath) -> {
397403
ProjectSubset.DEPENDENT_PROJECTS
398404
}
399405
else -> {
@@ -410,7 +416,7 @@ class AffectedModuleDetectorImpl constructor(
410416
private fun findChangedProjects(
411417
top: Sha,
412418
includeUncommitted: Boolean = true
413-
): Set<Project> {
419+
): Map<ProjectPath, Project> {
414420
git.findChangedFiles(
415421
top = top,
416422
includeUncommitted = includeUncommitted
@@ -421,7 +427,7 @@ class AffectedModuleDetectorImpl constructor(
421427
changedFiles.add(fileName)
422428
}
423429

424-
val changedProjects = mutableSetOf<Project>()
430+
val changedProjects = mutableMapOf<ProjectPath, Project>()
425431

426432
for (filePath in changedFiles) {
427433
val containingProject = findContainingProject(filePath)
@@ -432,7 +438,7 @@ class AffectedModuleDetectorImpl constructor(
432438
"Adding to unknownFiles."
433439
)
434440
} else {
435-
changedProjects.add(containingProject)
441+
changedProjects[containingProject.projectPath] = containingProject
436442
logger?.info(
437443
"For file $filePath containing project is $containingProject. " +
438444
"Adding to changedProjects."
@@ -447,10 +453,10 @@ class AffectedModuleDetectorImpl constructor(
447453
* Gets all dependent projects from the set of changedProjects. This doesn't include the
448454
* original changedProjects. Always build is still here to ensure at least 1 thing is built
449455
*/
450-
private fun findDependentProjects(): Set<Project> {
451-
return changedProjects.flatMap {
452-
dependencyTracker.findAllDependents(it)
453-
}.toSet()
456+
private fun findDependentProjects(): Map<ProjectPath, Project> {
457+
return changedProjects.flatMap { (_, project) ->
458+
dependencyTracker.findAllDependents(project).entries
459+
}.associate { it.key to it.value }
454460
}
455461

456462
/**
@@ -466,7 +472,7 @@ class AffectedModuleDetectorImpl constructor(
466472
* Also detects modules whose tests are codependent at runtime.
467473
*/
468474
@Suppress("ComplexMethod")
469-
private fun findAffectedProjects(): Set<Project> {
475+
private fun findAffectedProjects(): Map<ProjectPath, Project> {
470476
// In this case we don't care about any of the logic below, we're only concerned with
471477
// running the changed projects in this test runner
472478
if (projectSubset == ProjectSubset.CHANGED_PROJECTS) {
@@ -525,3 +531,5 @@ class AffectedModuleDetectorImpl constructor(
525531
}
526532

527533
val Project.isRoot get() = this == rootProject
534+
535+
val Project.projectPath: ProjectPath get() = ProjectPath(path)

Diff for: affectedmoduledetector/src/main/kotlin/com/dropbox/affectedmoduledetector/AffectedModuleDetectorPlugin.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ class AffectedModuleDetectorPlugin : Plugin<Project> {
229229
val tracker = DependencyTracker(project, null)
230230
project.tasks.configureEach { task ->
231231
if (task.name.contains(ANDROID_TEST_PATTERN)) {
232-
tracker.findAllDependents(project).forEach { dependentProject ->
232+
tracker.findAllDependents(project).forEach { (_, dependentProject) ->
233233
dependentProject.tasks.forEach { dependentTask ->
234234
AffectedModuleDetector.configureTaskGuard(dependentTask)
235235
}

Diff for: affectedmoduledetector/src/main/kotlin/com/dropbox/affectedmoduledetector/DependencyTracker.kt

+7-6
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,22 @@ class DependencyTracker constructor(
5454
result
5555
}
5656

57-
fun findAllDependents(project: Project): Set<Project> {
57+
fun findAllDependents(project: Project): Map<ProjectPath, Project> {
5858
logger?.info("finding dependents of ${project.path}")
59-
val result = mutableSetOf<Project>()
59+
val result = mutableMapOf<ProjectPath, Project>()
6060
fun addAllDependents(project: Project) {
61-
if (result.add(project)) {
61+
if (result.put(project.projectPath, project) == null) {
6262
dependentList[project]?.forEach(::addAllDependents)
6363
}
6464
}
6565
addAllDependents(project)
6666
logger?.info(
67-
"dependents of ${project.path} is ${result.map {
68-
it.path
67+
"dependents of ${project.path} is ${result.map { (path, _) ->
68+
path.path
6969
}}"
7070
)
7171
// the project isn't a dependent of itself
72-
return result.minus(project)
72+
result.remove(project.projectPath)
73+
return result
7374
}
7475
}

0 commit comments

Comments
 (0)