Skip to content

Commit cfa9388

Browse files
runningcodeclaude
andauthored
ref(snapshot): Use AGP addGeneratedSourceDirectory API (#1117)
* ref(snapshot): Use AGP addGeneratedSourceDirectory API Replace manual source set wiring and regex-based task dependency matching with the proper AGP `addGeneratedSourceDirectory` API. This lets AGP handle the source directory registration and task dependency setup automatically per variant. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(snapshot): Use per-variant task and java sources API The previous approach used a single task and `sources.kotlin` which is broken in AGP (https://issuetracker.google.com/issues/268248348). Switch to `sources.java` and register a per-variant task so each variant's unit test compilation gets its own generated source directory. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ref(snapshot): Apply spotless formatting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(snapshot): Use per-variant output directory Each variant's task was writing to the same output path, causing overlapping-output errors and build cache corruption. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(snapshot): Use AGP 9.0 hostTests API for source registration AGP 9.0 deprecated `variant.unitTest` in favor of `variant.hostTests`. Use the new API when running on AGP 9.0+ while keeping the old path for older versions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(snapshot): Suppress deprecation error for unitTest on older AGP Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ref(snapshot): Apply spotless formatting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Release: 6.2.0 --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 771e6b7 commit cfa9388

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/GenerateSnapshotTestsTask.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package io.sentry.android.gradle.snapshot
22

3+
import com.android.build.api.variant.ApplicationVariant
4+
import com.android.build.gradle.BaseExtension
5+
import io.sentry.android.gradle.SentryTasksProvider.capitalized
36
import java.io.File
47
import org.gradle.api.DefaultTask
58
import org.gradle.api.Project
@@ -52,10 +55,11 @@ abstract class GenerateSnapshotTestsTask : DefaultTask() {
5255
fun register(
5356
project: Project,
5457
extension: SentrySnapshotExtension,
55-
android: com.android.build.gradle.BaseExtension,
58+
android: BaseExtension,
59+
variant: ApplicationVariant,
5660
): TaskProvider<GenerateSnapshotTestsTask> {
5761
return project.tasks.register(
58-
"generateSnapshotTests",
62+
"generateSentrySnapshotTests${variant.name.capitalized}",
5963
GenerateSnapshotTestsTask::class.java,
6064
) { task ->
6165
task.includePrivatePreviews.set(extension.includePrivatePreviews)
@@ -65,7 +69,9 @@ abstract class GenerateSnapshotTestsTask : DefaultTask() {
6569
packages.ifEmpty { listOf(android.namespace!!) }
6670
}
6771
)
68-
task.outputDir.set(project.layout.buildDirectory.dir("generated/sentry/snapshotTests"))
72+
task.outputDir.set(
73+
project.layout.buildDirectory.dir("generated/sentry/snapshotTests/${variant.name}")
74+
)
6975
}
7076
}
7177

plugin-build/src/main/kotlin/io/sentry/android/gradle/snapshot/SentrySnapshotPlugin.kt

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package io.sentry.android.gradle.snapshot
22

3+
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
4+
import com.android.build.api.variant.HostTestBuilder
35
import com.android.build.gradle.BaseExtension
6+
import io.sentry.android.gradle.util.AgpVersions
7+
import kotlin.jvm.java
48
import org.gradle.api.Plugin
59
import org.gradle.api.Project
610

@@ -17,20 +21,33 @@ class SentrySnapshotPlugin : Plugin<Project> {
1721
project.pluginManager.withPlugin("app.cash.paparazzi") {
1822
val android = project.extensions.getByType(BaseExtension::class.java)
1923

20-
val generateTask = GenerateSnapshotTestsTask.register(project, extension, android)
21-
2224
project.dependencies.add(
2325
"testImplementation",
2426
"io.github.sergio-sastre.ComposablePreviewScanner:android:0.8.1",
2527
)
2628

27-
// Wire source set and task dependencies eagerly — afterEvaluate is too late
28-
// for the Kotlin compiler to pick up the generated sources.
29-
android.sourceSets.getByName("test").kotlin.srcDir(generateTask.flatMap { it.outputDir })
29+
val androidComponents =
30+
project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java)
3031

31-
project.tasks.configureEach { task ->
32-
if (task.name.matches(Regex("(compile|ksp).*UnitTestKotlin"))) {
33-
task.dependsOn(generateTask)
32+
androidComponents.onVariants { variant ->
33+
val generateTask = GenerateSnapshotTestsTask.register(project, extension, android, variant)
34+
if (AgpVersions.isAGP90(AgpVersions.CURRENT)) {
35+
// Right now it seems we only have HostTestBuilder.UNIT_TEST_TYPE as the key but we are
36+
// creating screenshot tests like HostTestBuilder.SCREENSHOT_TEST_TYPE
37+
// We should adjust this once the API is stable and documented.
38+
variant.hostTests[HostTestBuilder.UNIT_TEST_TYPE]
39+
// Using `sources?.kotlin` is broken so we have to use sources?.java:
40+
// https://issuetracker.google.com/issues/268248348
41+
?.sources
42+
?.java
43+
?.addGeneratedSourceDirectory(generateTask, GenerateSnapshotTestsTask::outputDir)
44+
} else {
45+
// `unitTest` is deprecated, the replacement above is complex
46+
@Suppress("DEPRECATION_ERROR")
47+
variant.unitTest
48+
?.sources
49+
?.java
50+
?.addGeneratedSourceDirectory(generateTask, GenerateSnapshotTestsTask::outputDir)
3451
}
3552
}
3653
}

plugin-build/src/main/kotlin/io/sentry/android/gradle/util/Versions.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ internal object AgpVersions {
88
val CURRENT: SemVer = SemVer.parse(Version.ANDROID_GRADLE_PLUGIN_VERSION)
99
val VERSION_7_4_0: SemVer = SemVer.parse("7.4.0-rc01")
1010
val VERSION_8_3_0: SemVer = SemVer.parse("8.3.0")
11+
val VERSION_9_0_0: SemVer = SemVer.parse("9.0.0")
1112

1213
fun isAGP74(current: SemVer) = current >= VERSION_7_4_0
1314

1415
fun isAGP83(current: SemVer) = current >= VERSION_8_3_0
16+
17+
fun isAGP90(current: SemVer) = current >= VERSION_9_0_0
1518
}
1619

1720
internal object GradleVersions {

0 commit comments

Comments
 (0)