[Gradle] Setup kotlin sources directly on AndroidSourceSet for AGP >= 7.0
^KT-54033 Verification Pending
This commit is contained in:
committed by
Space
parent
958c7e72da
commit
f286588e4c
+10
-5
@@ -58,14 +58,19 @@ internal data class AndroidGradlePluginVersion(
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* The currently applied/accessible Android Gradle Plugin version
|
||||
*/
|
||||
val current: AndroidGradlePluginVersion? = try {
|
||||
val currentOrNull: AndroidGradlePluginVersion? = try {
|
||||
AndroidGradlePluginVersion(Version.ANDROID_GRADLE_PLUGIN_VERSION)
|
||||
} catch (_: LinkageError) {
|
||||
null
|
||||
}
|
||||
|
||||
/**
|
||||
* The currently applied/accessible Android Gradle Plugin version
|
||||
*/
|
||||
val current: AndroidGradlePluginVersion
|
||||
get() = currentOrNull ?: throw IllegalStateException(
|
||||
"Can't infer current AndroidGradlePluginVersion: Is the Android plugin applied?"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,4 +86,4 @@ internal fun AndroidGradlePluginVersion?.isAtLeast(versionString: String): Boole
|
||||
internal fun AndroidGradlePluginVersion?.isAtLeast(version: AndroidGradlePluginVersion): Boolean {
|
||||
if (this == null) return false
|
||||
return this >= version
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ internal object KotlinMultiplatformAndroidGradlePluginCompatibilityHealthCheck {
|
||||
|
||||
object Default : AndroidGradlePluginVersionProvider {
|
||||
override fun getAndroidGradlePluginVersion(): AndroidGradlePluginVersion? {
|
||||
return AndroidGradlePluginVersion.current
|
||||
return AndroidGradlePluginVersion.currentOrNull
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -737,7 +737,7 @@ internal open class KotlinAndroidPlugin(
|
||||
private const val MINIMAL_SUPPORTED_AGP_VERSION = "3.6.4"
|
||||
fun androidTargetHandler(): AndroidProjectHandler {
|
||||
val tasksProvider = KotlinTasksProvider()
|
||||
val androidGradlePluginVersion = AndroidGradlePluginVersion.current
|
||||
val androidGradlePluginVersion = AndroidGradlePluginVersion.currentOrNull
|
||||
|
||||
if (androidGradlePluginVersion != null) {
|
||||
if (androidGradlePluginVersion < MINIMAL_SUPPORTED_AGP_VERSION) {
|
||||
|
||||
+10
-2
@@ -5,6 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.sources.android
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.AndroidGradlePluginVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.compareTo
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.checker.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.configurator.*
|
||||
|
||||
@@ -23,7 +25,10 @@ internal val singleTargetAndroidSourceSetLayout = KotlinAndroidSourceSetLayout(
|
||||
sourceSetConfigurator = KotlinAndroidSourceSetConfigurator(
|
||||
KotlinAndroidSourceSetInfoConfigurator,
|
||||
AndroidKaptSourceSetConfigurator,
|
||||
AndroidSourceSetConventionConfigurator,
|
||||
GradleConventionAddKotlinSourcesToAndroidSourceSetConfigurator,
|
||||
Agp7AddKotlinSourcesToAndroidSourceSetConfigurator
|
||||
.onlyIf { AndroidGradlePluginVersion.current >= "7.0.0" },
|
||||
|
||||
SingleTargetSourceDirConfigurator,
|
||||
),
|
||||
checker = KotlinAndroidSourceSetLayoutChecker()
|
||||
@@ -35,7 +40,9 @@ internal val multiplatformAndroidSourceSetLayoutV1 = KotlinAndroidSourceSetLayou
|
||||
sourceSetConfigurator = KotlinAndroidSourceSetConfigurator(
|
||||
KotlinAndroidSourceSetInfoConfigurator,
|
||||
AndroidKaptSourceSetConfigurator,
|
||||
AndroidSourceSetConventionConfigurator,
|
||||
GradleConventionAddKotlinSourcesToAndroidSourceSetConfigurator,
|
||||
Agp7AddKotlinSourcesToAndroidSourceSetConfigurator
|
||||
.onlyIf { AndroidGradlePluginVersion.current >= "7.0.0" },
|
||||
MultiplatformAndroidResourceDirConfigurator,
|
||||
MultiplatformLayoutV1DependsOnConfigurator,
|
||||
MultiplatformLayoutV1SourceDirConfigurator
|
||||
@@ -53,6 +60,7 @@ internal val multiplatformAndroidSourceSetLayoutV2 = KotlinAndroidSourceSetLayou
|
||||
AndroidKaptSourceSetConfigurator,
|
||||
MultiplatformAndroidResourceDirConfigurator,
|
||||
MultiplatformLayoutV2DependsOnConfigurator,
|
||||
Agp7AddKotlinSourcesToAndroidSourceSetConfigurator,
|
||||
MultiplatformLayoutV2SourceDirConfigurator,
|
||||
MultiplatformLayoutV2DefaultManifestLocationConfigurator
|
||||
),
|
||||
|
||||
+9
-6
@@ -6,13 +6,14 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.sources.android.checker
|
||||
|
||||
import com.android.Version
|
||||
import org.jetbrains.kotlin.gradle.plugin.compareVersionNumbers
|
||||
import org.jetbrains.kotlin.gradle.plugin.AndroidGradlePluginVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.isAtLeast
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSetLayout
|
||||
|
||||
internal object MultiplatformLayoutV2AgpRequirementChecker : KotlinAndroidSourceSetLayoutChecker {
|
||||
|
||||
private const val AGP_VERSION_MIN = "7.0.0"
|
||||
internal val minimumRequiredAgpVersion = AndroidGradlePluginVersion(7, 0, 0)
|
||||
|
||||
override fun checkBeforeLayoutApplied(
|
||||
diagnosticReporter: KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter,
|
||||
@@ -20,21 +21,23 @@ internal object MultiplatformLayoutV2AgpRequirementChecker : KotlinAndroidSource
|
||||
layout: KotlinAndroidSourceSetLayout
|
||||
) {
|
||||
if (!isAgpRequirementMet()) {
|
||||
diagnosticReporter.error(AgpRequirementNotMetDiagnostic(AGP_VERSION_MIN, Version.ANDROID_GRADLE_PLUGIN_VERSION))
|
||||
diagnosticReporter.error(
|
||||
AgpRequirementNotMetDiagnostic(minimumRequiredAgpVersion.toString(), Version.ANDROID_GRADLE_PLUGIN_VERSION)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun isAgpRequirementMet(): Boolean {
|
||||
return compareVersionNumbers(Version.ANDROID_GRADLE_PLUGIN_VERSION, AGP_VERSION_MIN) >= 0
|
||||
return AndroidGradlePluginVersion.currentOrNull.isAtLeast(minimumRequiredAgpVersion)
|
||||
}
|
||||
|
||||
internal data class AgpRequirementNotMetDiagnostic(
|
||||
val requiredMinAgpVersion: String,
|
||||
val minimumRequiredAgpVersion: String,
|
||||
val currentAgpVersion: String
|
||||
) : KotlinAndroidSourceSetLayoutChecker.Diagnostic {
|
||||
override val message: String
|
||||
get() = """
|
||||
requires Android Gradle Plugin Version >= $requiredMinAgpVersion.
|
||||
requires Android Gradle Plugin Version >= $minimumRequiredAgpVersion.
|
||||
Found $currentAgpVersion
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.sources.android.configurator
|
||||
|
||||
import com.android.build.gradle.api.AndroidSourceDirectorySet
|
||||
import com.android.build.gradle.api.AndroidSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
|
||||
object Agp7AddKotlinSourcesToAndroidSourceSetConfigurator: KotlinAndroidSourceSetConfigurator {
|
||||
override fun configure(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, androidSourceSet: AndroidSourceSet) {
|
||||
val androidKotlinSourceDirectorySet = androidSourceSet.javaClass.getMethod("getKotlin")
|
||||
.invoke(androidSourceSet) as AndroidSourceDirectorySet
|
||||
|
||||
androidKotlinSourceDirectorySet.srcDirs(target.project.provider { kotlinSourceSet.kotlin.srcDirs })
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -6,9 +6,7 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.sources.android.configurator
|
||||
|
||||
import com.android.build.gradle.api.AndroidSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KOTLIN_DSL_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.addConvention
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
|
||||
/*
|
||||
@@ -16,7 +14,7 @@ Used by AGP com.android.build.gradle.internal.utils.syncAgpAndKgpSources to auto
|
||||
from this KotlinSourceSet. This mechanism is deprecated.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
internal object AndroidSourceSetConventionConfigurator : KotlinAndroidSourceSetConfigurator {
|
||||
internal object GradleConventionAddKotlinSourcesToAndroidSourceSetConfigurator : KotlinAndroidSourceSetConfigurator {
|
||||
override fun configure(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, androidSourceSet: AndroidSourceSet) {
|
||||
androidSourceSet.addConvention(KOTLIN_DSL_NAME, kotlinSourceSet)
|
||||
}
|
||||
+21
@@ -27,6 +27,27 @@ internal interface KotlinAndroidSourceSetConfigurator {
|
||||
) = Unit
|
||||
}
|
||||
|
||||
internal fun KotlinAndroidSourceSetConfigurator.onlyIf(
|
||||
condition: (target: KotlinAndroidTarget) -> Boolean
|
||||
): KotlinAndroidSourceSetConfigurator {
|
||||
return KotlinAndroidSourceSetConfigurationWithCondition(this, condition)
|
||||
}
|
||||
|
||||
/* Conditional implementation */
|
||||
private class KotlinAndroidSourceSetConfigurationWithCondition(
|
||||
private val underlying: KotlinAndroidSourceSetConfigurator,
|
||||
private val condition: (KotlinAndroidTarget) -> Boolean
|
||||
) : KotlinAndroidSourceSetConfigurator {
|
||||
override fun configure(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, androidSourceSet: AndroidSourceSet) {
|
||||
if (condition(target)) underlying.configure(target, kotlinSourceSet, androidSourceSet)
|
||||
}
|
||||
|
||||
override fun configureWithVariant(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, variant: BaseVariant) {
|
||||
if (condition(target)) underlying.configureWithVariant(target, kotlinSourceSet, variant)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Composite implementation */
|
||||
|
||||
internal fun KotlinAndroidSourceSetConfigurator(
|
||||
|
||||
+1
-5
@@ -5,18 +5,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.sources.android.configurator
|
||||
|
||||
import com.android.build.gradle.api.AndroidSourceDirectorySet
|
||||
import com.android.build.gradle.api.AndroidSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
|
||||
internal object MultiplatformLayoutV2SourceDirConfigurator : KotlinAndroidSourceSetConfigurator {
|
||||
override fun configure(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, androidSourceSet: AndroidSourceSet) {
|
||||
val androidKotlinSourceDirectorySet = androidSourceSet.javaClass.getMethod("getKotlin")
|
||||
.invoke(androidSourceSet) as AndroidSourceDirectorySet
|
||||
|
||||
androidKotlinSourceDirectorySet.srcDirs(target.project.provider { kotlinSourceSet.kotlin.srcDirs })
|
||||
kotlinSourceSet.kotlin.srcDir(target.project.provider { androidSourceSet.java.srcDirs })
|
||||
kotlinSourceSet.kotlin.srcDir("src/${androidSourceSet.name}/kotlin")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+29
@@ -197,6 +197,35 @@ class MultiplatformAndroidSourceSetLayoutV1Test {
|
||||
assertSame(kotlin.sourceSets.getByName("androidAndroidTest"), androidTest.kotlinSourceSetByConvention())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `AndroidSourceSet kotlin AndroidSourceDirectorySet`() {
|
||||
kotlin.android()
|
||||
project.evaluate()
|
||||
android.libraryVariants.all { variant ->
|
||||
val main = variant.sourceSets.first { it.name == "main" }
|
||||
assertEquals(
|
||||
project.files("src/main/kotlin", "src/main/java", "src/androidMain/kotlin").toSet(),
|
||||
main.kotlinDirectories.toSet()
|
||||
)
|
||||
}
|
||||
|
||||
android.unitTestVariants.all { variant ->
|
||||
val test = variant.sourceSets.first { it.name == "test" }
|
||||
assertEquals(
|
||||
project.files("src/test/kotlin", "src/test/java", "src/androidTest/kotlin").toSet(),
|
||||
test.kotlinDirectories.toSet()
|
||||
)
|
||||
}
|
||||
|
||||
android.testVariants.all { variant ->
|
||||
val androidTest = variant.sourceSets.first { it.name == "androidTest" }
|
||||
assertEquals(
|
||||
project.files("src/androidTest/java", "src/androidAndroidTest/kotlin").toSet(),
|
||||
androidTest.kotlinDirectories.toSet()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val AndroidSourceSet.kotlinSourceSet
|
||||
get() = project.findKotlinSourceSet(this) ?: fail("Missing KotlinSourceSet for AndroidSourceSet: $name")
|
||||
}
|
||||
|
||||
+38
-12
@@ -7,14 +7,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.sources.android
|
||||
|
||||
import com.android.build.gradle.BaseExtension
|
||||
import com.android.build.gradle.LibraryExtension
|
||||
import com.android.build.gradle.LibraryPlugin
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.testfixtures.ProjectBuilder
|
||||
import org.jetbrains.kotlin.gradle.addBuildEventsListenerRegistryMock
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPluginWrapper
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.utils.androidExtension
|
||||
import org.junit.Test
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.assertEquals
|
||||
@@ -23,16 +22,16 @@ import kotlin.test.assertSame
|
||||
class SingleTargetAndroidSourceSetLayoutTest {
|
||||
private val project = ProjectBuilder.builder().build() as ProjectInternal
|
||||
|
||||
private val android: BaseExtension = run {
|
||||
private val android: LibraryExtension = run {
|
||||
addBuildEventsListenerRegistryMock(project)
|
||||
project.plugins.apply(LibraryPlugin::class.java)
|
||||
project.androidExtension
|
||||
project.extensions.getByName("android") as LibraryExtension
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
fun setup() {
|
||||
project.plugins.apply(KotlinAndroidPluginWrapper::class.java)
|
||||
android.compileSdkVersion(31)
|
||||
android.compileSdk = 31
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -57,17 +56,44 @@ class SingleTargetAndroidSourceSetLayoutTest {
|
||||
|
||||
@Test
|
||||
fun `test - with flavors - AndroidSourceSet has associated KotlinSourceSet`() {
|
||||
android.flavorDimensions("price", "market")
|
||||
android.productFlavors {
|
||||
it.create("free").dimension = "price"
|
||||
it.create("paid").dimension = "price"
|
||||
it.create("german").dimension = "market"
|
||||
it.create("usa").dimension = "market"
|
||||
}
|
||||
android.flavorDimensions.add("market")
|
||||
android.flavorDimensions.add("price")
|
||||
android.productFlavors.create("german").dimension = "market"
|
||||
android.productFlavors.create("usa").dimension = "market"
|
||||
android.productFlavors.create("paid").dimension = "price"
|
||||
android.productFlavors.create("free").dimension = "price"
|
||||
|
||||
android.sourceSets.all { androidSourceSet ->
|
||||
val kotlinSourceSet = project.getKotlinSourceSetOrFail(androidSourceSet)
|
||||
assertEquals(androidSourceSet.name, kotlinSourceSet.name)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `AndroidSourceSet kotlin AndroidSourceDirectorySet`() {
|
||||
project.evaluate()
|
||||
android.libraryVariants.all { variant ->
|
||||
val main = variant.sourceSets.first { it.name == "main" }
|
||||
assertEquals(
|
||||
project.files("src/main/kotlin", "src/main/java").toSet(),
|
||||
main.kotlinDirectories.toSet()
|
||||
)
|
||||
}
|
||||
|
||||
android.unitTestVariants.all { variant ->
|
||||
val test = variant.sourceSets.first { it.name == "test" }
|
||||
assertEquals(
|
||||
project.files("src/test/kotlin", "src/test/java").toSet(),
|
||||
test.kotlinDirectories.toSet()
|
||||
)
|
||||
}
|
||||
|
||||
android.testVariants.all { variant ->
|
||||
val androidTest = variant.sourceSets.first { it.name == "androidTest" }
|
||||
assertEquals(
|
||||
project.files("src/androidTest/kotlin", "src/androidTest/java").toSet(),
|
||||
androidTest.kotlinDirectories.toSet()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user