Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions oss-licenses-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ dependencies {
testImplementation("com.google.guava:guava:33.7.1-jre")
testImplementation("com.google.truth:truth:1.4.5")
testImplementation("com.google.code.gson:gson:2.14.0")
testImplementation("org.semver4j:semver4j:6.0.0")
testImplementation("com.android.tools.build:gradle:9.2.1") {
because("Needed for DependencyTaskTest.")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.semver4j.Semver
import java.io.File

/**
Expand All @@ -41,9 +42,6 @@ abstract class EndToEndTest {
?: error("Missing ${javaClass.simpleName}.gradleVersion — add to e2eVersions in build.gradle.kts")

companion object {
private val AGP_VERSION_REGEX = Regex("""agp = ".*"""")
private val KOTLIN_VERSION_REGEX = Regex("""kotlin = ".*"""")

// AGP 9+ has built-in Kotlin support; AGP 8.x requires the standalone KGP with legacy config.
private val AGP_9_KOTLIN_BLOCK = """
kotlin {
Expand Down Expand Up @@ -100,33 +98,43 @@ abstract class EndToEndTest {
}

private fun patchVersions() {
val agpBundlesKgp = agpVersion.substringBefore('.').toIntOrNull()?.let { it >= 9 } ?: false
val agp = Semver(agpVersion)
val agpBundlesKgp = agp.isGreaterThanOrEqualTo("9.0.0")
// Compose BOM 2026.09.00+ (Compose 1.12.1+) requires minAgpVersion 9.1.0 in AAR metadata.
val supportsLatestComposeBom = agp.isGreaterThanOrEqualTo("9.1.0")

// Patch AGP (and optionally Kotlin) version in the version catalog
val tomlFile = File(projectDir, "gradle/libs.versions.toml")
var tomlContent = tomlFile.readText()
check(AGP_VERSION_REGEX.containsMatchIn(tomlContent)) {
"libs.versions.toml missing expected 'agp = \"...\"' entry — has the testapp template changed?"
}
tomlContent = tomlContent.replace(AGP_VERSION_REGEX, "agp = \"$agpVersion\"")
.replaceVersionCatalogEntry("agp", agpVersion)

if (!agpBundlesKgp) {
check(KOTLIN_VERSION_REGEX.containsMatchIn(tomlContent)) {
"libs.versions.toml missing expected 'kotlin = \"...\"' entry — has the testapp template changed?"
}
tomlContent = tomlContent.replace(KOTLIN_VERSION_REGEX, "kotlin = \"2.1.10\"")
tomlContent = tomlContent.replaceVersionCatalogEntry("kotlin", "2.1.10")
patchLegacyKotlinBuildConfig()
}
if (!supportsLatestComposeBom) {
tomlContent = tomlContent.replaceVersionCatalogEntry("androidx-compose-bom", "2026.06.00")
}

tomlFile.writeText(tomlContent)
}

// AGP 8.x doesn't have built-in Kotlin support — replace with standalone KGP config
if (!agpBundlesKgp) {
val buildFile = File(projectDir, "app/build.gradle.kts")
val original = buildFile.readText()
val patched = original.replace(AGP_9_KOTLIN_BLOCK, AGP_8_KOTLIN_BLOCK)
check(patched != original) {
"Failed to patch Kotlin block in app/build.gradle.kts — has the testapp template changed?"
}
buildFile.writeText(patched)
private fun String.replaceVersionCatalogEntry(key: String, version: String): String {
val regex = Regex("""${Regex.escape(key)} = ".*"""")
check(regex.containsMatchIn(this)) {
"libs.versions.toml missing expected '$key = \"...\"' entry — has the testapp template changed?"
}
return replace(regex, """$key = "$version"""")
}

private fun patchLegacyKotlinBuildConfig() {
// AGP 8.x doesn't have built-in Kotlin support — replace with standalone KGP config.
val buildFile = File(projectDir, "app/build.gradle.kts")
val original = buildFile.readText()
val patched = original.replace(AGP_9_KOTLIN_BLOCK, AGP_8_KOTLIN_BLOCK)
check(patched != original) {
"Failed to patch Kotlin block in app/build.gradle.kts — has the testapp template changed?"
}
buildFile.writeText(patched)
}

private fun createRunner(vararg arguments: String): GradleRunner {
Expand Down
5 changes: 5 additions & 0 deletions oss-licenses-plugin/testapp/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ tasks.withType<Test>().configureEach {
val javaToolchains = project.extensions.getByType<JavaToolchainService>()
javaLauncher.set(javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(21)) })

// Robolectric 4.17's FileDescriptorInterceptor reflects on jdk.internal.access.SharedSecrets
// when ApplicationSharedMemory.create() initializes on SDK 36+, which requires opening
// java.base/jdk.internal.access to unnamed modules on JDK 21+.
jvmArgs("--add-opens=java.base/jdk.internal.access=ALL-UNNAMED")

// Enable parallel execution for faster Robolectric runs
maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Global Robolectric Configuration
# Note: SDK 36 (Baklava) requires Java 21+ — Robolectric will fail to run it on older JVMs.
sdk=24, 33, 34, 35, 36
# Note: SDK 36+ requires Java 21+ — Robolectric will fail to run it on older JVMs.
sdk=24, 33, 34, 35, 36, 37
12 changes: 6 additions & 6 deletions oss-licenses-plugin/testapp/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
[versions]
agp = "9.4.0"
agp = "9.4.1"
androidx-activity = "1.13.0"
androidx-appcompat = "1.8.0"
androidx-compose-bom = "2026.06.00"
androidx-compose-bom = "2026.09.00"
androidx-test = "1.7.0"
androidx-test-espresso = "3.7.0"
androidx-test-ext = "1.3.0"
compileSdk = "36"
compileSdk = "37"
junit = "4.13.2"
kotlin = "2.4.10"
kotlin = "2.4.20"
minSdk = "24"
oss-licenses-plugin = "+"
oss-licenses-library = "+" # Always use the latest available
robolectric = "4.16.1"
targetSdk = "36"
robolectric = "4.17"
targetSdk = "37"

[libraries]
androidx-activity = { module = "androidx.activity:activity", version.ref = "androidx-activity" }
Expand Down
Loading