[mpp] Migrate AndroidSourceSetLayout checks to the new infra

This commit is contained in:
Dmitry Savvinov
2023-03-15 16:57:12 +01:00
committed by Space Team
parent 4e479cb54b
commit bb3dc145e5
13 changed files with 144 additions and 215 deletions
@@ -6,7 +6,10 @@
package org.jetbrains.kotlin.gradle.plugin.diagnostics
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnostic.Severity.WARNING
import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV1
import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV2
@InternalKotlinGradlePluginApi // used in integration tests
object KotlinToolingDiagnostics {
@@ -75,4 +78,53 @@ object KotlinToolingDiagnostics {
return build(cause + "\n" + details)
}
}
object PromoteAndroidSourceSetLayoutV2Warning : ToolingDiagnosticFactory(WARNING) {
operator fun invoke() = build(
"""
${multiplatformAndroidSourceSetLayoutV1.name} is deprecated. Use ${multiplatformAndroidSourceSetLayoutV2.name} instead.
To enable ${multiplatformAndroidSourceSetLayoutV2.name}: put the following in your gradle.properties:
${PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION}=2
To suppress this warning: put the following in your gradle.properties:
${PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION_1_NO_WARN}=true
Learn more: https://kotlinlang.org/docs/whatsnew18.html#kotlin-multiplatform-a-new-android-source-set-layout
""".trimIndent()
)
}
object AgpRequirementNotMetForAndroidSourceSetLayoutV2 : ToolingDiagnosticFactory(WARNING) {
operator fun invoke(minimumRequiredAgpVersion: String, currentAgpVersion: String) = build(
"""
${multiplatformAndroidSourceSetLayoutV2.name} requires Android Gradle Plugin Version >= $minimumRequiredAgpVersion.
Found $currentAgpVersion
""".trimIndent()
)
}
object AndroidStyleSourceDirUsageWarning : ToolingDiagnosticFactory(WARNING) {
operator fun invoke(androidStyleSourceDirInUse: String, kotlinStyleSourceDirToUse: String) = build(
"""
Usage of 'Android Style' source directory $androidStyleSourceDirInUse is deprecated.
Use $kotlinStyleSourceDirToUse instead.
To suppress this warning: put the following in your gradle.properties:
${PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_ANDROID_STYLE_NO_WARN}=true
Learn more: https://kotlinlang.org/docs/whatsnew18.html#kotlin-multiplatform-a-new-android-source-set-layout
""".trimIndent()
)
}
object SourceSetLayoutV1StyleDirUsageWarning : ToolingDiagnosticFactory(WARNING) {
operator fun invoke(v1StyleSourceDirInUse: String, currentLayoutName: String, v2StyleSourceDirToUse: String) = build(
"""
Found used source directory $v1StyleSourceDirInUse
This source directory was supported by: ${multiplatformAndroidSourceSetLayoutV1.name}
Current KotlinAndroidSourceSetLayout: $currentLayoutName
New source directory is: $v2StyleSourceDirToUse
""".trimIndent()
)
}
}
@@ -10,8 +10,8 @@ import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.sources.android.checker.KotlinAndroidSourceSetLayoutChecker
import org.jetbrains.kotlin.gradle.utils.getOrCreate
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheck
@@ -19,7 +19,7 @@ internal class KotlinAndroidSourceSetFactory(
private val target: KotlinAndroidTarget,
private val kotlin: KotlinProjectExtension,
private val layout: KotlinAndroidSourceSetLayout,
private val diagnosticReporter: KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter,
private val diagnosticsCollector: KotlinToolingDiagnosticsCollector
) {
private val configuredKotlinSourceSets = mutableSetOf<KotlinSourceSet>()
@@ -29,7 +29,7 @@ internal class KotlinAndroidSourceSetFactory(
layout.sourceSetConfigurator.configure(target, kotlinSourceSet, androidSourceSet)
target.project.runProjectConfigurationHealthCheck {
val layout = this@KotlinAndroidSourceSetFactory.layout
layout.checker.checkCreatedSourceSet(diagnosticReporter, target, layout, kotlinSourceSet, androidSourceSet)
layout.checker.checkCreatedSourceSet(diagnosticsCollector, target, layout, kotlinSourceSet, androidSourceSet)
}
}
return kotlinSourceSet
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.gradle.plugin.sources.android
import org.gradle.api.logging.Logging
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.diagnostics.kotlinToolingDiagnosticsCollector
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.sources.android.checker.KotlinAndroidSourceSetLayoutChecker
import org.jetbrains.kotlin.gradle.utils.androidExtension
import org.jetbrains.kotlin.gradle.utils.forAllAndroidVariants
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheck
@@ -23,12 +23,13 @@ internal object KotlinAndroidSourceSets {
) {
logger.debug("Applying ${KotlinAndroidSourceSetLayout::class.java.simpleName}: ${layout.name}")
val android = target.project.androidExtension
val diagnosticReporter = KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter.create(target.project, logger, layout)
val factory = KotlinAndroidSourceSetFactory(target, target.project.kotlinExtension, layout, diagnosticReporter)
val project = target.project
val android = project.androidExtension
val diagnosticsCollector = project.kotlinToolingDiagnosticsCollector
val factory = KotlinAndroidSourceSetFactory(target, project.kotlinExtension, layout, diagnosticsCollector)
target.project.runProjectConfigurationHealthCheck {
layout.checker.checkBeforeLayoutApplied(diagnosticReporter, target, layout)
project.runProjectConfigurationHealthCheck {
layout.checker.checkBeforeLayoutApplied(diagnosticsCollector, target, layout)
}
/*
@@ -46,7 +47,7 @@ internal object KotlinAndroidSourceSets {
}
/* Hook into Android's variant creation: This is invoked in 'afterEvaluate' */
target.project.forAllAndroidVariants { variant ->
project.forAllAndroidVariants { variant ->
variant.sourceSets.forEach { sourceProvider ->
val androidSourceSet = android.sourceSets.findByName(sourceProvider.name) ?: return@forEach
@@ -60,5 +61,3 @@ internal object KotlinAndroidSourceSets {
}
}
}
@@ -6,38 +6,20 @@
package org.jetbrains.kotlin.gradle.plugin.sources.android.checker
import com.android.build.gradle.api.AndroidSourceSet
import org.gradle.api.Project
import org.gradle.api.logging.Logger
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSetLayout
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
internal interface KotlinAndroidSourceSetLayoutChecker {
open class ProjectMisconfiguredException(message: String) : Exception(message)
interface DiagnosticReporter {
fun error(diagnostic: Diagnostic): Nothing
fun warning(diagnostic: Diagnostic)
companion object {
fun create(project: Project, logger: Logger, layout: KotlinAndroidSourceSetLayout): DiagnosticReporter =
DiagnosticReporterImpl(project, logger, layout)
}
}
interface Diagnostic {
val message: String
}
fun checkBeforeLayoutApplied(
diagnosticReporter: DiagnosticReporter,
diagnosticsCollector: KotlinToolingDiagnosticsCollector,
target: KotlinAndroidTarget,
layout: KotlinAndroidSourceSetLayout
) = Unit
fun checkCreatedSourceSet(
diagnosticReporter: DiagnosticReporter,
diagnosticsCollector: KotlinToolingDiagnosticsCollector,
target: KotlinAndroidTarget,
layout: KotlinAndroidSourceSetLayout,
kotlinSourceSet: KotlinSourceSet,
@@ -45,20 +27,6 @@ internal interface KotlinAndroidSourceSetLayoutChecker {
) = Unit
}
private class DiagnosticReporterImpl(
private val project: Project,
private val logger: Logger,
private val layout: KotlinAndroidSourceSetLayout
) : KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter {
override fun error(diagnostic: KotlinAndroidSourceSetLayoutChecker.Diagnostic): Nothing {
throw KotlinAndroidSourceSetLayoutChecker.ProjectMisconfiguredException("${layout.name}: ${diagnostic.message}")
}
override fun warning(diagnostic: KotlinAndroidSourceSetLayoutChecker.Diagnostic) {
SingleWarningPerBuild.show(project, logger, "w: ${layout.name}: ${diagnostic.message}\n")
}
}
/* Composite Implementation */
internal fun KotlinAndroidSourceSetLayoutChecker(
@@ -72,22 +40,22 @@ private class CompositeKotlinAndroidSourceSetLayoutChecker(
) : KotlinAndroidSourceSetLayoutChecker {
override fun checkBeforeLayoutApplied(
diagnosticReporter: KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter,
diagnosticsCollector: KotlinToolingDiagnosticsCollector,
target: KotlinAndroidTarget,
layout: KotlinAndroidSourceSetLayout
) {
checkers.forEach { checker -> checker.checkBeforeLayoutApplied(diagnosticReporter, target, layout) }
checkers.forEach { checker -> checker.checkBeforeLayoutApplied(diagnosticsCollector, target, layout) }
}
override fun checkCreatedSourceSet(
diagnosticReporter: KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter,
diagnosticsCollector: KotlinToolingDiagnosticsCollector,
target: KotlinAndroidTarget,
layout: KotlinAndroidSourceSetLayout,
kotlinSourceSet: KotlinSourceSet,
androidSourceSet: AndroidSourceSet
) {
checkers.forEach { checker ->
checker.checkCreatedSourceSet(diagnosticReporter, target, layout, kotlinSourceSet, androidSourceSet)
checker.checkCreatedSourceSet(diagnosticsCollector, target, layout, kotlinSourceSet, androidSourceSet)
}
}
}
@@ -6,42 +6,27 @@
package org.jetbrains.kotlin.gradle.plugin.sources.android.checker
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
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
import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV2
/**
* Promotes MultiplatformAndroidSourceSetLayoutV2 when requirements are met
*/
internal object MultiplatformLayoutV1PromoteV2Checker : KotlinAndroidSourceSetLayoutChecker {
override fun checkBeforeLayoutApplied(
diagnosticReporter: KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter,
diagnosticsCollector: KotlinToolingDiagnosticsCollector,
target: KotlinAndroidTarget,
layout: KotlinAndroidSourceSetLayout
) {
if (target.project.kotlinPropertiesProvider.ignoreMppAndroidSourceSetLayoutVersion) return
runCatching {
if (MultiplatformLayoutV2AgpRequirementChecker.isAgpRequirementMet()) {
diagnosticReporter.warning(PromoteV2LayoutDiagnostic)
diagnosticsCollector.reportOncePerGradleBuild(
target.project, KotlinToolingDiagnostics.PromoteAndroidSourceSetLayoutV2Warning()
)
}
}
}
object PromoteV2LayoutDiagnostic : KotlinAndroidSourceSetLayoutChecker.Diagnostic {
override val message: String
get() = """
${multiplatformAndroidSourceSetLayoutV1.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
Learn more: https://kotlinlang.org/docs/whatsnew18.html#kotlin-multiplatform-a-new-android-source-set-layout
""".trimIndent()
override fun toString(): String = "PromoteV2LayoutDiagnostic"
}
}
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.gradle.plugin.sources.android.checker
import com.android.Version
import org.jetbrains.kotlin.gradle.plugin.AndroidGradlePluginVersion
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
import org.jetbrains.kotlin.gradle.plugin.isAtLeast
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSetLayout
@@ -16,13 +18,17 @@ internal object MultiplatformLayoutV2AgpRequirementChecker : KotlinAndroidSource
internal val minimumRequiredAgpVersion = AndroidGradlePluginVersion(7, 0, 0)
override fun checkBeforeLayoutApplied(
diagnosticReporter: KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter,
diagnosticsCollector: KotlinToolingDiagnosticsCollector,
target: KotlinAndroidTarget,
layout: KotlinAndroidSourceSetLayout
) {
if (!isAgpRequirementMet()) {
diagnosticReporter.error(
AgpRequirementNotMetDiagnostic(minimumRequiredAgpVersion.toString(), Version.ANDROID_GRADLE_PLUGIN_VERSION)
diagnosticsCollector.reportOncePerGradleBuild(
target.project,
KotlinToolingDiagnostics.AgpRequirementNotMetForAndroidSourceSetLayoutV2(
minimumRequiredAgpVersion.toString(),
Version.ANDROID_GRADLE_PLUGIN_VERSION
)
)
}
}
@@ -30,15 +36,4 @@ internal object MultiplatformLayoutV2AgpRequirementChecker : KotlinAndroidSource
internal fun isAgpRequirementMet(): Boolean {
return AndroidGradlePluginVersion.currentOrNull.isAtLeast(minimumRequiredAgpVersion)
}
internal data class AgpRequirementNotMetDiagnostic(
val minimumRequiredAgpVersion: String,
val currentAgpVersion: String
) : KotlinAndroidSourceSetLayoutChecker.Diagnostic {
override val message: String
get() = """
requires Android Gradle Plugin Version >= $minimumRequiredAgpVersion.
Found $currentAgpVersion
""".trimIndent()
}
}
@@ -6,13 +6,12 @@
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.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSetLayout
import java.io.File
/**
* Will detect usage of "Android Style" source directories (like 'src/main/kotlin') and emit a warning
@@ -20,33 +19,24 @@ import java.io.File
internal object MultiplatformLayoutV2AndroidStyleSourceDirUsageChecker : KotlinAndroidSourceSetLayoutChecker {
override fun checkCreatedSourceSet(
diagnosticReporter: KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter,
diagnosticsCollector: KotlinToolingDiagnosticsCollector,
target: KotlinAndroidTarget,
layout: KotlinAndroidSourceSetLayout,
kotlinSourceSet: KotlinSourceSet,
androidSourceSet: AndroidSourceSet
) {
if (target.project.kotlinPropertiesProvider.ignoreMppAndroidSourceSetLayoutV2AndroidStyleDirs) return
val projectRoot = target.project.rootDir
val androidStyleSourceDir = target.project.file("src/${androidSourceSet.name}/kotlin")
if (androidStyleSourceDir in kotlinSourceSet.kotlin.srcDirs && androidStyleSourceDir.exists()) {
val kotlinStyleSourceDirToUse = target.project.file("src/${kotlinSourceSet.name}/kotlin")
diagnosticReporter.warning(AndroidStyleSourceDirUsageDiagnostic(androidStyleSourceDir, kotlinStyleSourceDirToUse))
diagnosticsCollector.report(
target.project,
KotlinToolingDiagnostics.AndroidStyleSourceDirUsageWarning(
androidStyleSourceDir.relativeTo(projectRoot).toString(),
kotlinStyleSourceDirToUse.relativeTo(projectRoot).toString(),
)
)
}
}
data class AndroidStyleSourceDirUsageDiagnostic(
val androidStyleSourceDirInUse: File,
val kotlinStyleSourceDirToUse: File
) : KotlinAndroidSourceSetLayoutChecker.Diagnostic {
override val message: String
get() = """
Usage of 'Android Style' source directory $androidStyleSourceDirInUse is deprecated.
Use $kotlinStyleSourceDirToUse instead.
To suppress this warning: put the following in your gradle.properties:
${PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_ANDROID_STYLE_NO_WARN}=true
Learn more: https://kotlinlang.org/docs/whatsnew18.html#kotlin-multiplatform-a-new-android-source-set-layout
""".trimIndent()
}
}
@@ -6,22 +6,25 @@
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.diagnostics.KotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
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.androidSourceSetInfo
import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV1
import org.jetbrains.kotlin.gradle.utils.androidExtension
import java.io.File
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.relativeTo
/**
* Detects and warns about usage of source directories from multiplatform layout version 1
*/
internal object MultiplatformLayoutV2MultiplatformLayoutV1StyleSourceDirUsageChecker : KotlinAndroidSourceSetLayoutChecker {
@OptIn(ExperimentalPathApi::class)
override fun checkCreatedSourceSet(
diagnosticReporter: KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter,
diagnosticsCollector: KotlinToolingDiagnosticsCollector,
target: KotlinAndroidTarget,
layout: KotlinAndroidSourceSetLayout,
kotlinSourceSet: KotlinSourceSet,
@@ -41,29 +44,18 @@ internal object MultiplatformLayoutV2MultiplatformLayoutV1StyleSourceDirUsageChe
*/
if (target.project.androidExtension.sourceSets.findByName(v1kotlinSourceSetName) != null) return
val rootDirPath = target.project.rootDir.toPath()
val v1KotlinSourceDir = target.project.file("src/$v1kotlinSourceSetName/kotlin")
if (v1KotlinSourceDir.exists()) {
diagnosticReporter.warning(
V1StyleSourceDirUsageDiagnostic(
layout = layout,
v1StyleSourceDirInUse = v1KotlinSourceDir,
v2StyleSourceDirToUse = target.project.file("src/${kotlinSourceSet.name}/kotlin")
val v2SourceDirToUse = target.project.file("src/${kotlinSourceSet.name}/kotlin")
diagnosticsCollector.report(
target.project,
KotlinToolingDiagnostics.SourceSetLayoutV1StyleDirUsageWarning(
v1KotlinSourceDir.toPath().relativeTo(rootDirPath).toString(),
layout.name,
v2SourceDirToUse.toPath().relativeTo(rootDirPath).toString()
)
)
}
}
data class V1StyleSourceDirUsageDiagnostic(
private val layout: KotlinAndroidSourceSetLayout,
val v1StyleSourceDirInUse: File,
val v2StyleSourceDirToUse: File
) : KotlinAndroidSourceSetLayoutChecker.Diagnostic {
override val message: String
get() = """
Found used source directory $v1StyleSourceDirInUse
This source directory was supported by: ${multiplatformAndroidSourceSetLayoutV1.name}
Current KotlinAndroidSourceSetLayout: ${layout.name}
New source directory is: $v2StyleSourceDirToUse
""".trimIndent()
}
}
@@ -12,19 +12,14 @@ import org.gradle.api.Project
import org.gradle.api.internal.project.ProjectInternal
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.sources.android.checker.MultiplatformLayoutV2AndroidStyleSourceDirUsageChecker.AndroidStyleSourceDirUsageDiagnostic
import org.jetbrains.kotlin.gradle.plugin.sources.android.checker.MultiplatformLayoutV2MultiplatformLayoutV1StyleSourceDirUsageChecker.V1StyleSourceDirUsageDiagnostic
import org.jetbrains.kotlin.gradle.plugin.diagnostics.kotlinToolingDiagnosticsCollector
import org.jetbrains.kotlin.gradle.plugin.sources.android.findAndroidSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV2
import org.jetbrains.kotlin.gradle.util.*
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.fail
class MultiplatformAndroidSourceSetLayoutV2DiagnosticsTest {
private val diagnosticsReporter = TestDiagnosticsReporter()
private fun buildMinimalAndroidMultiplatformProject(): ProjectInternal = buildProjectWithMPP {
setMultiplatformAndroidSourceSetLayoutVersion(2)
plugins.apply(LibraryPlugin::class.java)
@@ -36,14 +31,12 @@ class MultiplatformAndroidSourceSetLayoutV2DiagnosticsTest {
}
}
private fun Project.checkCreatedSourceSets(
diagnosticsReporter: TestDiagnosticsReporter = this@MultiplatformAndroidSourceSetLayoutV2DiagnosticsTest.diagnosticsReporter
) {
private fun Project.checkCreatedSourceSets() {
/* Invoke checkers on all source sets */
project.multiplatformExtension.sourceSets.forEach { kotlinSourceSet ->
val androidSourceSet = project.findAndroidSourceSet(kotlinSourceSet) ?: return@forEach
multiplatformAndroidSourceSetLayoutV2.checker.checkCreatedSourceSet(
diagnosticReporter = diagnosticsReporter,
diagnosticsCollector = project.kotlinToolingDiagnosticsCollector,
target = project.multiplatformExtension.androidTarget(),
layout = multiplatformAndroidSourceSetLayoutV2,
kotlinSourceSet = kotlinSourceSet,
@@ -63,10 +56,7 @@ class MultiplatformAndroidSourceSetLayoutV2DiagnosticsTest {
/* Invoke checkers on all source sets */
project.checkCreatedSourceSets()
val diagnostic = assertIsInstance<AndroidStyleSourceDirUsageDiagnostic>(diagnosticsReporter.assertSingleWarning())
assertEquals(androidTestKotlinSourceDir, diagnostic.androidStyleSourceDirInUse)
assertEquals(project.file("src/androidInstrumentedTest/kotlin"), diagnostic.kotlinStyleSourceDirToUse)
project.checkDiagnostics("kt53709AndroidTest_kotlinInUse")
}
@Test
@@ -80,25 +70,7 @@ class MultiplatformAndroidSourceSetLayoutV2DiagnosticsTest {
project.evaluate()
project.checkCreatedSourceSets()
val warnings = diagnosticsReporter.warnings
if (warnings.size != 2) fail("Expected exactly two warnings emitted. Found $warnings")
val androidMainWarning = warnings.filterIsInstance<AndroidStyleSourceDirUsageDiagnostic>()
.find { warning -> warning.androidStyleSourceDirInUse == androidStyleMain }
?: fail("Missing warning for '$androidStyleMain'. Found $warnings")
assertEquals(
project.file("src/androidMain/kotlin"), androidMainWarning.kotlinStyleSourceDirToUse
)
val androidUnitTestWarning = warnings.filterIsInstance<AndroidStyleSourceDirUsageDiagnostic>()
.find { warning -> warning.androidStyleSourceDirInUse == androidStyleUnitTest }
?: fail("Missing warning for '$androidStyleUnitTest'. Found $warnings")
assertEquals(
project.file("src/androidUnitTest/kotlin"), androidUnitTestWarning.kotlinStyleSourceDirToUse
)
project.checkDiagnostics("androidStyleSourceDirUsage")
}
@Test
@@ -115,9 +87,7 @@ class MultiplatformAndroidSourceSetLayoutV2DiagnosticsTest {
project.evaluate()
project.checkCreatedSourceSets()
val warnings = diagnosticsReporter.warnings
if (warnings.isNotEmpty()) fail("Expected no warnings emitted. Found $warnings")
project.checkDiagnostics("androidStyleSourceDirUsageNoWarn")
}
@Test
@@ -127,15 +97,6 @@ class MultiplatformAndroidSourceSetLayoutV2DiagnosticsTest {
v1StyleInstrumentedTest.mkdirs()
project.evaluate()
project.checkCreatedSourceSets()
val warning = assertIsInstance<V1StyleSourceDirUsageDiagnostic>(diagnosticsReporter.assertSingleWarning())
assertEquals(
v1StyleInstrumentedTest, warning.v1StyleSourceDirInUse,
)
assertEquals(
project.file("src/androidInstrumentedTest/kotlin"), warning.v2StyleSourceDirToUse
)
project.checkDiagnostics("v1LayoutStyleSourceDirUsage")
}
}
}
@@ -1,39 +0,0 @@
/*
* 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.unitTests.sources.android
import org.jetbrains.kotlin.gradle.plugin.sources.android.checker.KotlinAndroidSourceSetLayoutChecker
import kotlin.test.fail
internal class TestDiagnosticsReporter : KotlinAndroidSourceSetLayoutChecker.DiagnosticReporter {
class ErrorDiagnosticException(diagnostic: KotlinAndroidSourceSetLayoutChecker.Diagnostic) :
KotlinAndroidSourceSetLayoutChecker.ProjectMisconfiguredException(diagnostic.message)
private val _errors = mutableListOf<KotlinAndroidSourceSetLayoutChecker.Diagnostic>()
private val _warnings = mutableListOf<KotlinAndroidSourceSetLayoutChecker.Diagnostic>()
val errors get() = _errors.toList()
val warnings get() = _warnings.toList()
override fun error(diagnostic: KotlinAndroidSourceSetLayoutChecker.Diagnostic): Nothing {
_errors.add(diagnostic)
throw ErrorDiagnosticException(diagnostic)
}
override fun warning(diagnostic: KotlinAndroidSourceSetLayoutChecker.Diagnostic) {
_warnings.add(diagnostic)
}
}
internal fun TestDiagnosticsReporter.assertSingleWarning(): KotlinAndroidSourceSetLayoutChecker.Diagnostic {
if (errors.isNotEmpty()) fail("Expected just a single warning, but found errors: $errors")
if (warnings.isEmpty()) fail("Expected a single warning, but found none!")
if (warnings.size > 1) fail("Expected a single warning, but found multiple: $warnings")
return warnings.first()
}
@@ -0,0 +1,15 @@
[AndroidStyleSourceDirUsageWarning | WARNING] Usage of 'Android Style' source directory src/main/kotlin is deprecated.
Use src/androidMain/kotlin instead.
To suppress this warning: put the following in your gradle.properties:
kotlin.mpp.androidSourceSetLayoutV2AndroidStyleDirs.nowarn=true
Learn more: https://kotlinlang.org/docs/whatsnew18.html#kotlin-multiplatform-a-new-android-source-set-layout
----
[AndroidStyleSourceDirUsageWarning | WARNING] Usage of 'Android Style' source directory src/test/kotlin is deprecated.
Use src/androidUnitTest/kotlin instead.
To suppress this warning: put the following in your gradle.properties:
kotlin.mpp.androidSourceSetLayoutV2AndroidStyleDirs.nowarn=true
Learn more: https://kotlinlang.org/docs/whatsnew18.html#kotlin-multiplatform-a-new-android-source-set-layout
@@ -0,0 +1,7 @@
[AndroidStyleSourceDirUsageWarning | WARNING] Usage of 'Android Style' source directory src/androidTest/kotlin is deprecated.
Use src/androidInstrumentedTest/kotlin instead.
To suppress this warning: put the following in your gradle.properties:
kotlin.mpp.androidSourceSetLayoutV2AndroidStyleDirs.nowarn=true
Learn more: https://kotlinlang.org/docs/whatsnew18.html#kotlin-multiplatform-a-new-android-source-set-layout
@@ -0,0 +1,4 @@
[SourceSetLayoutV1StyleDirUsageWarning | WARNING] Found used source directory src/androidAndroidTest/kotlin
This source directory was supported by: Multiplatform/Android-V1-SourceSetLayout
Current KotlinAndroidSourceSetLayout: Multiplatform/Android-V2-SourceSetLayout
New source directory is: src/androidInstrumentedTest/kotlin