Skip to content

Commit 05f9c88

Browse files
authored
Handle each KotlinCompile depends task to have a dedicated output directory (#154)
* Handle each KotlinCompile depends task to have a dedicated output directory * Look for stability-info.json in build/stability/ (supports both old and new layouts)
1 parent 842ce91 commit 05f9c88

5 files changed

Lines changed: 34 additions & 58 deletions

File tree

compose-stability-analyzer-idea/src/main/kotlin/com/skydoves/compose/stability/idea/toolwindow/ComposableStabilityCollector.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,16 @@ public class ComposableStabilityCollector(private val project: Project) {
5858
val contentRoots = moduleRootManager.contentRoots
5959

6060
for (contentRoot in contentRoots) {
61-
// Look for build/stability/stability-info.json
62-
val jsonFile = File(contentRoot.path, "build/stability/stability-info.json")
63-
if (!jsonFile.exists()) {
64-
continue
65-
}
61+
// Look for stability-info.json in build/stability/ (supports both old and new layouts)
62+
val stabilityDir = File(contentRoot.path, "build/stability")
63+
val legacyFile = File(stabilityDir, "stability-info.json")
64+
val jsonFile = if (legacyFile.exists()) {
65+
legacyFile
66+
} else {
67+
stabilityDir.listFiles { file -> file.isDirectory }
68+
?.map { File(it, "stability-info.json") }
69+
?.firstOrNull { it.exists() }
70+
} ?: continue
6671

6772
try {
6873
val jsonContent = jsonFile.readText()

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ kotlin.mpp.androidGradlePluginCompatibility.nowarn=true
4848

4949
# Maven publishing
5050
GROUP=com.github.skydoves
51-
VERSION_NAME=0.7.4
51+
VERSION_NAME=0.7.5-SNAPSHOT
5252

5353
POM_URL=https://github.com/skydoves/compose-stability-analyzer/
5454
POM_SCM_URL=https://github.com/skydoves/compose-stability-analyzer/

stability-gradle/src/main/kotlin/com/skydoves/compose/stability/gradle/StabilityAnalyzerGradlePlugin.kt

Lines changed: 19 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
4747

4848
// This version should match the version in gradle.properties
4949
// Update this when bumping the library version
50-
private const val VERSION = "0.7.4"
50+
private const val VERSION = "0.7.5-SNAPSHOT"
5151

5252
// Compiler option keys
5353
private const val OPTION_ENABLED = "enabled"
@@ -73,9 +73,9 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
7373
registerTasksAndroid(target, extension, androidComponents)
7474
}
7575

76-
// Add output parameter to the Kotlin tasks to ensure it is compatible with the Build Cache
76+
// Per-task output directory to avoid shared output conflicts with other plugins (Issue #153)
7777
target.tasks.withType(KotlinCompile::class.java).configureEach {
78-
val stabilityDir = target.layout.buildDirectory.dir("stability").get()
78+
val stabilityDir = target.layout.buildDirectory.dir("stability/$name")
7979
outputs.dir(stabilityDir).optional(true)
8080
}
8181
}
@@ -91,7 +91,9 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
9191
) {
9292
projectName.set(target.name)
9393
stabilityInputFiles.setFrom(
94-
target.layout.buildDirectory.file("stability/stability-info.json"),
94+
target.fileTree(target.layout.buildDirectory.dir("stability")) {
95+
include("*/stability-info.json")
96+
},
9597
)
9698
outputDir.set(extension.stabilityValidation.outputDir)
9799
ignoredPackages.set(extension.stabilityValidation.ignoredPackages)
@@ -107,7 +109,9 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
107109
) {
108110
projectName.set(target.name)
109111
stabilityInputFiles.from(
110-
target.layout.buildDirectory.file("stability/stability-info.json"),
112+
target.fileTree(target.layout.buildDirectory.dir("stability")) {
113+
include("*/stability-info.json")
114+
},
111115
)
112116
stabilityReferenceFiles.from(extension.stabilityValidation.outputDir)
113117
ignoredPackages.set(extension.stabilityValidation.ignoredPackages)
@@ -158,7 +162,9 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
158162
) {
159163
projectName.set(target.name)
160164
stabilityInputFiles.setFrom(
161-
target.layout.buildDirectory.file("stability/stability-info.json"),
165+
target.layout.buildDirectory.file(
166+
"stability/compile${variantNameUpperCase}Kotlin/stability-info.json",
167+
),
162168
)
163169
outputDir.set(extension.stabilityValidation.outputDir)
164170
ignoredPackages.set(extension.stabilityValidation.ignoredPackages)
@@ -175,7 +181,9 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
175181
) {
176182
projectName.set(target.name)
177183
stabilityInputFiles.from(
178-
target.layout.buildDirectory.file("stability/stability-info.json"),
184+
target.layout.buildDirectory.file(
185+
"stability/compile${variantNameUpperCase}Kotlin/stability-info.json",
186+
),
179187
)
180188
stabilityReferenceFiles.from(extension.stabilityValidation.outputDir)
181189
ignoredPackages.set(extension.stabilityValidation.ignoredPackages)
@@ -266,8 +274,10 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
266274
return project.provider {
267275
val projectDependencies = collectProjectDependencies(project)
268276

269-
// Write project dependencies to a file to avoid empty string issues with SubpluginOption
270-
val stabilityDir = project.layout.buildDirectory.dir("stability").get().asFile
277+
// Per-compilation output directory to avoid shared output conflicts (Issue #153)
278+
val compileTaskName = kotlinCompilation.compileTaskProvider.name
279+
val stabilityDir = project.layout.buildDirectory
280+
.dir("stability/$compileTaskName").get().asFile
271281
stabilityDir.mkdirs()
272282
val dependenciesFile = java.io.File(stabilityDir, "project-dependencies.txt")
273283
dependenciesFile.writeText(projectDependencies.joinToString("\n"))
@@ -356,7 +366,6 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
356366

357367
// Configure dependencies lazily using TaskProvider
358368
stabilityDumpTask.configure {
359-
// Use provider to lazily collect Kotlin compile task names
360369
dependsOn(
361370
includeTestsProvider.map { includeTests ->
362371
project.tasks.matching { task ->
@@ -365,27 +374,9 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
365374
}
366375
},
367376
)
368-
369-
if (filter != null) {
370-
// For now, stability check compiler plugin still creates the same files
371-
// for different variant tasks. That means that even though our variant task
372-
// is not dependent on the other-variant kotlin tasks, it is still implicitly coupled
373-
// with them as it reads the same files. To mitigate for this,
374-
// we tell Gradle that this task must run after any kotlin tasks, even
375-
// if their variant does not match ours
376-
mustRunAfter(
377-
includeTestsProvider.map { includeTests ->
378-
project.tasks.matching { task ->
379-
isKotlinTaskApplicable(task.name, includeTests) &&
380-
!task.name.contains(filter)
381-
}
382-
},
383-
)
384-
}
385377
}
386378

387379
stabilityCheckTask.configure {
388-
// Use provider to lazily collect Kotlin compile task names
389380
dependsOn(
390381
includeTestsProvider.map { includeTests ->
391382
project.tasks.matching { task ->
@@ -394,26 +385,6 @@ public class StabilityAnalyzerGradlePlugin : KotlinCompilerPluginSupportPlugin {
394385
}
395386
},
396387
)
397-
398-
if (filter != null) {
399-
// For now, stability check compiler plugin still creates the same files
400-
// for different variant tasks. That means that even though our variant task
401-
// is not dependent on the other-variant kotlin tasks, it is still implicitly coupled
402-
// with them as it reads the same files. To mitigate for this,
403-
// we tell Gradle that this task must run after any kotlin tasks, even
404-
// if their variant does not match ours
405-
mustRunAfter(
406-
includeTestsProvider.map { includeTests ->
407-
project.tasks.matching { task ->
408-
isKotlinTaskApplicable(
409-
task.name,
410-
includeTests,
411-
) &&
412-
!task.name.contains(filter)
413-
}
414-
},
415-
)
416-
}
417388
}
418389
}
419390

stability-gradle/src/main/kotlin/com/skydoves/compose/stability/gradle/StabilityCheckTask.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ public abstract class StabilityCheckTask : DefaultTask() {
107107

108108
@TaskAction
109109
public fun check() {
110-
val inputFile = stabilityInputFiles.files.firstOrNull()
111-
if (inputFile == null || !inputFile.exists()) {
110+
val inputFile = stabilityInputFiles.files.firstOrNull { it.exists() }
111+
if (inputFile == null) {
112112
// If the file doesn't exist, it means the module has no composable functions
113113
// This is expected for modules like activities or utilities without composables
114114
logger.lifecycle(

stability-gradle/src/main/kotlin/com/skydoves/compose/stability/gradle/StabilityDumpTask.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ public abstract class StabilityDumpTask : DefaultTask() {
9292

9393
@TaskAction
9494
public fun dump() {
95-
val inputFile = stabilityInputFiles.singleOrNull()
96-
if (inputFile == null || !inputFile.exists()) {
95+
val inputFile = stabilityInputFiles.files.firstOrNull { it.exists() }
96+
if (inputFile == null) {
9797
// If the file doesn't exist, it means the module has no composable functions
9898
// This is expected for modules like activities or utilities without composables
9999
logger.lifecycle("ℹ️ No composables found in :${projectName.get()}, skipping stability dump")

0 commit comments

Comments
 (0)