Skip to content

Commit 252d05b

Browse files
authored
Improved compatibility with AGP/KMP (#349)
1 parent d5d1b5f commit 252d05b

4 files changed

Lines changed: 61 additions & 48 deletions

File tree

plugin/src/main/kotlin/com/github/gmazzo/buildconfig/internal/bindings/AndroidBinder.kt

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.github.gmazzo.buildconfig.internal.BuildConfigSourceSetInternal
66
import com.github.gmazzo.buildconfig.internal.bindings.JavaBinder.registerExtension
77
import com.github.gmazzo.buildconfig.internal.capitalized
88
import groovy.lang.Closure
9+
import java.lang.reflect.InvocationTargetException
910
import org.gradle.api.Action
1011
import org.gradle.api.Named
1112
import org.gradle.api.NamedDomainObjectContainer
@@ -110,21 +111,44 @@ internal object AndroidBinder {
110111
}
111112

112113
sourcesJavaAddGeneratedSourceDirectory(spec.generateTask, BuildConfigTask::outputDir)
113-
sourcesKotlinAddGeneratedSourceDirectory(spec.generateTask, BuildConfigTask::outputDir)
114+
try {
115+
sourcesKotlinAddGeneratedSourceDirectory(spec.generateTask, BuildConfigTask::outputDir)
116+
} catch (_: InvocationTargetException) {
117+
// this may fail on older AGP versions
118+
}
114119
}
115120

116121
private val Project.androidComponents: ExtensionAware
117122
get() = extensions.getByName("androidComponents") as ExtensionAware
118123

119124
private fun ExtensionAware/*AndroidComponentsExtension*/.onVariants(onVariant: Action<Any>) {
120-
val selectorsAll = with(javaClass.getMethod("selector").invoke(this)) {
121-
javaClass.getMethod("all").invoke(this)
125+
val selectorsAll = try {
126+
with(javaClass.getMethod("selector").invoke(this)) {
127+
javaClass.getMethod("all").invoke(this)
128+
}
129+
} catch (_: NoSuchMethodException) {
130+
null
122131
}
123-
val selectorInterface = selectorsAll.javaClass.superclass.interfaces[0]
124132

125-
@Suppress("UNCHECKED_CAST")
126-
javaClass.getMethod("onVariants", selectorInterface, Action::class.java)
127-
.invoke(this, selectorsAll, onVariant)
133+
val selectorInterface = selectorsAll?.javaClass?.superclass?.interfaces[0]
134+
135+
fun callMethod(name: String) {
136+
@Suppress("UNCHECKED_CAST")
137+
javaClass.getMethod(name, *listOfNotNull(selectorInterface, Action::class.java).toTypedArray())
138+
.invoke(this, *listOfNotNull(selectorsAll, onVariant).toTypedArray())
139+
}
140+
141+
try {
142+
callMethod("onVariants")
143+
144+
} catch (ex: NoSuchMethodException) {
145+
try {
146+
callMethod("onVariant")
147+
148+
} catch (_: NoSuchMethodException) {
149+
throw ex
150+
}
151+
}
128152
}
129153

130154
private fun ExtensionAware/*AndroidComponentsExtension*/.finalizeDsl(callback: (Any/*AndroidBaseExtension*/) -> Unit) {

plugin/src/test/kotlin/com/github/gmazzo/buildconfig/BuildConfigPluginBaseTest.kt

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -112,25 +112,29 @@ abstract class BuildConfigPluginBaseTest(private val isKMP: Boolean = false) {
112112
""".trimIndent()
113113
)
114114

115-
val kotlinPluginId = when {
116-
isKMP -> "org.jetbrains.kotlin.multiplatform"
117-
androidVersion != null -> "org.jetbrains.kotlin.android"
118-
else -> "org.jetbrains.kotlin.jvm"
119-
}
120-
121-
val plugins = when (androidVersion) {
122-
null -> when (kotlinVersion) {
123-
null -> listOf("java")
124-
else -> listOf("id(\"$kotlinPluginId\") version \"$kotlinVersion\"")
125-
}
126-
127-
else -> when (kotlinVersion) {
128-
null -> listOf("id(\"com.android.application\") version \"$androidVersion\"")
115+
val plugins = when (isKMP) {
116+
true -> when (androidVersion) {
117+
null -> listOf("org.jetbrains.kotlin.multiplatform" to kotlinVersion)
129118
else -> listOf(
130-
"id(\"com.android.application\") version \"$androidVersion\"",
131-
"id(\"$kotlinPluginId\") version \"$kotlinVersion\"",
119+
"org.jetbrains.kotlin.multiplatform" to kotlinVersion,
120+
"com.android.kotlin.multiplatform.library" to androidVersion,
132121
)
133122
}
123+
124+
else -> when (androidVersion) {
125+
null -> when (kotlinVersion) {
126+
null -> listOf("java" to null)
127+
else -> listOf("org.jetbrains.kotlin.jvm" to kotlinVersion)
128+
}
129+
130+
else -> when (kotlinVersion) {
131+
null -> listOf("com.android.application" to androidVersion)
132+
else -> listOf(
133+
"org.jetbrains.kotlin.android" to kotlinVersion,
134+
"com.android.application" to androidVersion,
135+
)
136+
}
137+
}
134138
}
135139

136140
if (androidVersion != null) {
@@ -143,7 +147,7 @@ abstract class BuildConfigPluginBaseTest(private val isKMP: Boolean = false) {
143147
(if (kotlinVersion != null) "import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion\n\n" else "") +
144148
"""
145149
plugins {
146-
${plugins.joinToString(separator = "\n") { " $it" }}
150+
${plugins.joinToString(separator = "\n") { (id, version) -> " id(\"$id\")" + (version?.let { " version \"$it\"" } ?: "") }}
147151
id("com.github.gmazzo.buildconfig")
148152
}
149153
""" + (if (withPackage) """
@@ -166,21 +170,9 @@ abstract class BuildConfigPluginBaseTest(private val isKMP: Boolean = false) {
166170
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
167171
168172
""" + (if (androidVersion != null) """
169-
android {
170-
compileSdkVersion(33)
173+
${if (isKMP) "kotlin.androidLibrary" else "android "}{
174+
compileSdk = 33
171175
namespace = "org.test"
172-
173-
compileOptions {
174-
sourceCompatibility = JavaVersion.VERSION_17
175-
targetCompatibility = JavaVersion.VERSION_17
176-
}
177-
178-
publishing {
179-
singleVariant("release") {
180-
withSourcesJar()
181-
withJavadocJar()
182-
}
183-
}
184176
}
185177
""" else """
186178
java {

plugin/src/test/kotlin/com/github/gmazzo/buildconfig/BuildConfigPluginKMPExpectActualTest.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,24 @@ class BuildConfigPluginKMPExpectActualTest : BuildConfigPluginBaseTest(isKMP = t
44

55
override fun testBuild() = listOf(
66
Args(gradleVersion = gradleLatest, kotlinVersion = kotlinCurrent, androidVersion = androidCurrent),
7-
Args(gradleVersion = gradleMin, kotlinVersion = kotlinMin, androidVersion = "8.0.0"),
7+
Args(gradleVersion = gradleMin, kotlinVersion = kotlinMin, androidVersion = "8.2.0"),
88
)
99

1010
override fun Args.buildConfigFieldsContent() = """
1111
buildConfigField("String", "API_BASE_URL", expect(expression("\"https://localhost:8080/\"")))
1212
13-
sourceSets.named("androidDebug") {
13+
sourceSets.named("androidMain") {
1414
buildConfigField("String", "API_BASE_URL", "\"https://10.0.2.2:8080/\"")
1515
}
1616
""".trimIndent()
1717

1818
override fun Args.extraBuildContent() = """
1919
kotlin {
2020
jvm()
21-
androidTarget()
21+
androidLibrary {
22+
withAndroidTestOnJvm { }
23+
}
2224
js { browser() }
23-
applyDefaultHierarchyTemplate()
2425
2526
sourceSets.commonTest.dependencies {
2627
implementation("org.jetbrains.kotlin:kotlin-test")
@@ -65,8 +66,7 @@ class BuildConfigPluginKMPExpectActualTest : BuildConfigPluginBaseTest(isKMP = t
6566
}
6667

6768
writeActuals("jvmTest")
68-
writeActuals("androidUnitTestDebug", "10.0.2.2")
69-
writeActuals("androidUnitTestRelease")
69+
writeActuals("androidHostTest", "10.0.2.2")
7070
writeActuals("jsTest")
7171
}
7272

plugin/src/test/kotlin/com/github/gmazzo/buildconfig/BuildConfigTaskCacheabilityTest.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ class BuildConfigTaskCacheabilityTest {
2929
.withArguments("clean", "jar")
3030
.forwardOutput()
3131

32-
// to generate unique build cache entry per run
33-
private val uuid = UUID.randomUUID()
34-
3532
@BeforeEach
3633
fun setup() {
3734
projectDir.deleteRecursively()
@@ -65,7 +62,7 @@ class BuildConfigTaskCacheabilityTest {
6562
6663
buildConfig {
6764
buildConfigField("String", "SOME_FIELD", "\"aValue\"")
68-
buildConfigField("String", "UUID", "\"${uuid}\"")
65+
buildConfigField("String", "UUID", "\"${UUID.randomUUID()}\"")
6966
}
7067
7168
""".trimIndent()

0 commit comments

Comments
 (0)