[Gradle][KT-53342] KotlinAndroidSourceSetLayoutCheckers to provide migration from V1 -> V2
This commit is contained in:
committed by
Space
parent
82d92a4e82
commit
6a13c2797b
+5
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType.Companion.jsCompi
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_ABI_SNAPSHOT
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_GRADLE_PLUGIN_COMPATIBILITY_NO_WARN
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION_1_NO_WARN
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_GRANULAR_SOURCE_SETS_METADATA
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_OPTIMISTIC_NUMBER_COMMONIZATION
|
||||
@@ -213,6 +214,9 @@ internal class PropertiesProvider private constructor(private val project: Proje
|
||||
val mppAndroidSourceSetLayoutVersion: Int?
|
||||
get() = property(KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION)?.toIntOrNull()
|
||||
|
||||
val ignoreMppAndroidSourceSetLayoutVersion: Boolean
|
||||
get() = booleanProperty(KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION_1_NO_WARN) ?: false
|
||||
|
||||
val ignoreDisabledCInteropCommonization: Boolean
|
||||
get() = booleanProperty("$KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION.nowarn") ?: false
|
||||
|
||||
@@ -472,6 +476,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
|
||||
const val KOTLIN_MPP_HIERARCHICAL_STRUCTURE_SUPPORT = "kotlin.mpp.hierarchicalStructureSupport"
|
||||
const val KOTLIN_MPP_ANDROID_GRADLE_PLUGIN_COMPATIBILITY_NO_WARN = "kotlin.mpp.androidGradlePluginCompatibility.nowarn"
|
||||
const val KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION = "kotlin.mpp.androidSourceSetLayoutVersion"
|
||||
const val KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION_1_NO_WARN = "${KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION}1.nowarn"
|
||||
const val KOTLIN_NATIVE_DEPENDENCY_PROPAGATION = "kotlin.native.enableDependencyPropagation"
|
||||
const val KOTLIN_MPP_ENABLE_OPTIMISTIC_NUMBER_COMMONIZATION = "kotlin.mpp.enableOptimisticNumberCommonization"
|
||||
const val KOTLIN_KPM_EXPERIMENTAL_MODEL_MAPPING = "kotlin.kpm.experimentalModelMapping"
|
||||
|
||||
+16
-5
@@ -5,29 +5,32 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.sources.android
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.checker.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.configurator.*
|
||||
|
||||
internal data class KotlinAndroidSourceSetLayout(
|
||||
val name: String,
|
||||
val naming: KotlinAndroidSourceSetNaming,
|
||||
val sourceSetConfigurator: KotlinAndroidSourceSetConfigurator
|
||||
val sourceSetConfigurator: KotlinAndroidSourceSetConfigurator,
|
||||
val checker: KotlinAndroidSourceSetLayoutChecker
|
||||
) {
|
||||
override fun toString(): String = "KotlinAndroidSourceSetLayout: $name"
|
||||
}
|
||||
|
||||
internal val singleTargetAndroidSourceSetLayout = KotlinAndroidSourceSetLayout(
|
||||
name = "Kotlin/Android",
|
||||
name = "Kotlin/Android-SourceSetLayout",
|
||||
naming = SingleTargetKotlinAndroidSourceSetNaming,
|
||||
sourceSetConfigurator = KotlinAndroidSourceSetConfigurator(
|
||||
KotlinAndroidSourceSetInfoConfigurator,
|
||||
AndroidKaptSourceSetConfigurator,
|
||||
AndroidSourceSetConventionConfigurator,
|
||||
SingleTargetSourceDirConfigurator,
|
||||
)
|
||||
),
|
||||
checker = KotlinAndroidSourceSetLayoutChecker()
|
||||
)
|
||||
|
||||
internal val multiplatformAndroidSourceSetLayoutV1 = KotlinAndroidSourceSetLayout(
|
||||
name = "Multiplatform/Android V1",
|
||||
name = "Multiplatform/Android-V1-SourceSetLayout",
|
||||
naming = MultiplatformLayoutV1KotlinAndroidSourceSetNaming,
|
||||
sourceSetConfigurator = KotlinAndroidSourceSetConfigurator(
|
||||
KotlinAndroidSourceSetInfoConfigurator,
|
||||
@@ -36,11 +39,14 @@ internal val multiplatformAndroidSourceSetLayoutV1 = KotlinAndroidSourceSetLayou
|
||||
MultiplatformAndroidResourceDirConfigurator,
|
||||
MultiplatformLayoutV1DependsOnConfigurator,
|
||||
MultiplatformLayoutV1SourceDirConfigurator
|
||||
),
|
||||
checker = KotlinAndroidSourceSetLayoutChecker(
|
||||
MultiplatformLayoutV1PromoteV2Checker
|
||||
)
|
||||
)
|
||||
|
||||
internal val multiplatformAndroidSourceSetLayoutV2 = KotlinAndroidSourceSetLayout(
|
||||
name = "Multiplatform/Android V2",
|
||||
name = "Multiplatform/Android-V2-SourceSetLayout",
|
||||
naming = MultiplatformLayoutV2KotlinAndroidSourceSetNaming,
|
||||
sourceSetConfigurator = KotlinAndroidSourceSetConfigurator(
|
||||
KotlinAndroidSourceSetInfoConfigurator,
|
||||
@@ -49,5 +55,10 @@ internal val multiplatformAndroidSourceSetLayoutV2 = KotlinAndroidSourceSetLayou
|
||||
MultiplatformLayoutV2DependsOnConfigurator,
|
||||
MultiplatformLayoutV2SourceDirConfigurator,
|
||||
MultiplatformLayoutV2DefaultManifestLocationConfigurator
|
||||
),
|
||||
checker = KotlinAndroidSourceSetLayoutChecker(
|
||||
MultiplatformLayoutV2AgpRequirementChecker,
|
||||
MultiplatformLayoutV2AndroidStyleSourceDirUsageChecker,
|
||||
MultiplatformLayoutV2MultiplatformLayoutV1StyleSourceDirUsageChecker
|
||||
)
|
||||
)
|
||||
|
||||
+13
-1
@@ -14,12 +14,13 @@ import org.jetbrains.kotlin.gradle.plugin.forEachVariant
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
import org.jetbrains.kotlin.gradle.utils.androidExtension
|
||||
import org.jetbrains.kotlin.gradle.utils.getOrCreate
|
||||
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheck
|
||||
|
||||
internal object KotlinAndroidSourceSets {
|
||||
|
||||
private val logger = Logging.getLogger(this::class.java)
|
||||
|
||||
fun setupKotlinAndroidSourceSets(
|
||||
fun applyKotlinAndroidSourceSetLayout(
|
||||
target: KotlinAndroidTarget,
|
||||
layout: KotlinAndroidSourceSetLayout = target.project.kotlinAndroidSourceSetLayout
|
||||
) {
|
||||
@@ -30,6 +31,11 @@ internal object KotlinAndroidSourceSets {
|
||||
val android = project.androidExtension
|
||||
val naming = layout.naming
|
||||
val configurator = layout.sourceSetConfigurator
|
||||
val checker = layout.checker
|
||||
|
||||
project.runProjectConfigurationHealthCheck {
|
||||
checker.checkBeforeLayoutApplied(target, layout)
|
||||
}
|
||||
|
||||
/* Ensures that each KotlinSourceSet only invokes the 'configurator' once */
|
||||
val configuredKotlinSourceSets = mutableSetOf<KotlinSourceSet>()
|
||||
@@ -45,6 +51,9 @@ internal object KotlinAndroidSourceSets {
|
||||
|
||||
if (configuredKotlinSourceSets.add(kotlinSourceSet)) {
|
||||
configurator.configure(target, kotlinSourceSet, androidSourceSet)
|
||||
project.runProjectConfigurationHealthCheck {
|
||||
checker.checkCreatedSourceSet(target, layout, kotlinSourceSet, androidSourceSet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +67,9 @@ internal object KotlinAndroidSourceSets {
|
||||
|
||||
if (configuredKotlinSourceSets.add(kotlinSourceSet)) {
|
||||
configurator.configure(target, kotlinSourceSet, androidSourceSet)
|
||||
project.runProjectConfigurationHealthCheck {
|
||||
checker.checkCreatedSourceSet(target, layout, kotlinSourceSet, androidSourceSet)
|
||||
}
|
||||
}
|
||||
configurator.configureWithVariant(target, kotlinSourceSet, variant)
|
||||
}
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.checker
|
||||
|
||||
import com.android.build.gradle.api.AndroidSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSetLayout
|
||||
|
||||
internal interface KotlinAndroidSourceSetLayoutChecker {
|
||||
class ProjectMisconfiguredException(message: String) : Exception(message)
|
||||
|
||||
fun checkBeforeLayoutApplied(
|
||||
target: KotlinAndroidTarget,
|
||||
layout: KotlinAndroidSourceSetLayout
|
||||
) = Unit
|
||||
|
||||
fun checkCreatedSourceSet(
|
||||
target: KotlinAndroidTarget,
|
||||
layout: KotlinAndroidSourceSetLayout,
|
||||
kotlinSourceSet: KotlinSourceSet,
|
||||
androidSourceSet: AndroidSourceSet
|
||||
) = Unit
|
||||
}
|
||||
|
||||
internal fun KotlinAndroidSourceSetLayoutChecker(
|
||||
vararg checkers: KotlinAndroidSourceSetLayoutChecker?
|
||||
): KotlinAndroidSourceSetLayoutChecker {
|
||||
return CompositeKotlinAndroidSourceSetLayoutChecker(checkers.filterNotNull())
|
||||
}
|
||||
|
||||
private class CompositeKotlinAndroidSourceSetLayoutChecker(
|
||||
private val checkers: List<KotlinAndroidSourceSetLayoutChecker>
|
||||
) : KotlinAndroidSourceSetLayoutChecker {
|
||||
|
||||
override fun checkBeforeLayoutApplied(target: KotlinAndroidTarget, layout: KotlinAndroidSourceSetLayout) {
|
||||
checkers.forEach { checker -> checker.checkBeforeLayoutApplied(target, layout) }
|
||||
}
|
||||
|
||||
override fun checkCreatedSourceSet(
|
||||
target: KotlinAndroidTarget,
|
||||
layout: KotlinAndroidSourceSetLayout,
|
||||
kotlinSourceSet: KotlinSourceSet,
|
||||
androidSourceSet: AndroidSourceSet
|
||||
) {
|
||||
checkers.forEach { checker ->
|
||||
checker.checkCreatedSourceSet(target, layout, kotlinSourceSet, androidSourceSet)
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.checker
|
||||
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSetLayout
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV2
|
||||
|
||||
/**
|
||||
* Promotes MultiplatformAndroidSourceSetLayoutV2 when requirements are met
|
||||
*/
|
||||
internal object MultiplatformLayoutV1PromoteV2Checker : KotlinAndroidSourceSetLayoutChecker {
|
||||
private val logger = Logging.getLogger(this.javaClass)
|
||||
|
||||
override fun checkBeforeLayoutApplied(target: KotlinAndroidTarget, layout: KotlinAndroidSourceSetLayout) {
|
||||
if (target.project.kotlinPropertiesProvider.ignoreMppAndroidSourceSetLayoutVersion) return
|
||||
runCatching {
|
||||
if (MultiplatformLayoutV2AgpRequirementChecker.isAgpRequirementMet()) {
|
||||
logger.warn(
|
||||
"""
|
||||
w: ${layout.name} is deprecated. Use ${multiplatformAndroidSourceSetLayoutV2.name} instead.
|
||||
To enable ${multiplatformAndroidSourceSetLayoutV2.name}: put the following in your gradle.properties:
|
||||
${PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION}=2
|
||||
|
||||
To suppress this warning: put the following in your gradle.properties:
|
||||
${PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION_1_NO_WARN}=true
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.checker
|
||||
|
||||
import com.android.Version
|
||||
import org.jetbrains.kotlin.gradle.plugin.compareVersionNumbers
|
||||
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"
|
||||
|
||||
override fun checkBeforeLayoutApplied(target: KotlinAndroidTarget, layout: KotlinAndroidSourceSetLayout) {
|
||||
if (!isAgpRequirementMet()) {
|
||||
throw KotlinAndroidSourceSetLayoutChecker.ProjectMisconfiguredException(
|
||||
"""
|
||||
${layout.name} requires Android Gradle Plugin Version >= $AGP_VERSION_MIN.
|
||||
Found ${Version.ANDROID_GRADLE_PLUGIN_VERSION}
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun isAgpRequirementMet(): Boolean {
|
||||
return compareVersionNumbers(Version.ANDROID_GRADLE_PLUGIN_VERSION, AGP_VERSION_MIN) >= 0
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.checker
|
||||
|
||||
import com.android.build.gradle.api.AndroidSourceSet
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSetLayout
|
||||
|
||||
/**
|
||||
* Will detect usage of "Android Style" source directories (like 'src/main/kotlin') and emit a warning
|
||||
*/
|
||||
internal object MultiplatformLayoutV2AndroidStyleSourceDirUsageChecker : KotlinAndroidSourceSetLayoutChecker {
|
||||
|
||||
private val logger = Logging.getLogger(this.javaClass)
|
||||
|
||||
override fun checkCreatedSourceSet(
|
||||
target: KotlinAndroidTarget,
|
||||
layout: KotlinAndroidSourceSetLayout,
|
||||
kotlinSourceSet: KotlinSourceSet,
|
||||
androidSourceSet: AndroidSourceSet
|
||||
) {
|
||||
val androidStyleSourceDir = target.project.file("src/${androidSourceSet.name}/kotlin")
|
||||
if (androidStyleSourceDir in kotlinSourceSet.kotlin.srcDirs && androidStyleSourceDir.exists()) {
|
||||
logger.warn(
|
||||
"""
|
||||
w: ${layout.name}: Usage of 'Android Style' source directory $androidStyleSourceDir is deprecated.
|
||||
Use ${target.project.file("src/${kotlinSourceSet.name}/kotlin")} instead.
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.checker
|
||||
|
||||
import com.android.build.gradle.api.AndroidSourceSet
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSetLayout
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV1
|
||||
|
||||
/**
|
||||
* Detects and warns about usage of source directories from multiplatform layout version 1
|
||||
*/
|
||||
internal object MultiplatformLayoutV2MultiplatformLayoutV1StyleSourceDirUsageChecker : KotlinAndroidSourceSetLayoutChecker {
|
||||
|
||||
private val logger = Logging.getLogger(this.javaClass)
|
||||
|
||||
override fun checkCreatedSourceSet(
|
||||
target: KotlinAndroidTarget,
|
||||
layout: KotlinAndroidSourceSetLayout,
|
||||
kotlinSourceSet: KotlinSourceSet,
|
||||
androidSourceSet: AndroidSourceSet
|
||||
) {
|
||||
val v1kotlinSourceSetName = multiplatformAndroidSourceSetLayoutV1.naming.kotlinSourceSetName(
|
||||
target.disambiguationClassifier, androidSourceSet.name
|
||||
) ?: return
|
||||
|
||||
/* Layouts did agree on the name of this KotlinSourceSet -> LGTM */
|
||||
if (v1kotlinSourceSetName == kotlinSourceSet.name) return
|
||||
|
||||
val v1KotlinSourceDir = target.project.file("src/$v1kotlinSourceSetName/kotlin")
|
||||
if (v1KotlinSourceDir.exists()) {
|
||||
logger.warn(
|
||||
"""
|
||||
w: ${layout.name}: Found used source directory $v1KotlinSourceDir
|
||||
This source directory was supported by: ${multiplatformAndroidSourceSetLayoutV1.name}
|
||||
Current KotlinAndroidSourceSetLayout: ${layout.name}
|
||||
New source directory is: ${target.project.file("src/${kotlinSourceSet.name}/kotlin")}
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
||||
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSets.setupKotlinAndroidSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSets.applyKotlinAndroidSourceSetLayout
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.findKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||
@@ -61,7 +61,7 @@ internal class AndroidProjectHandler(
|
||||
val project = kotlinAndroidTarget.project
|
||||
val ext = project.extensions.getByName("android") as BaseExtension
|
||||
|
||||
setupKotlinAndroidSourceSets(kotlinAndroidTarget)
|
||||
applyKotlinAndroidSourceSetLayout(kotlinAndroidTarget)
|
||||
|
||||
val kotlinOptions = KotlinJvmOptionsImpl()
|
||||
kotlinOptions.noJdk = true
|
||||
|
||||
Reference in New Issue
Block a user