Check the MPP model for unused Kotlin source sets, warn when found
Issue #KT-26963 Fixed
This commit is contained in:
+31
@@ -5,6 +5,7 @@
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.UnusedSourceSetsChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.METADATA_CONFIGURATION_NAME_SUFFIX
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.SourceSetConsistencyChecks
|
||||
import org.jetbrains.kotlin.gradle.util.checkBytecodeContains
|
||||
@@ -1062,4 +1063,34 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
assertFileExists("foo/2.txt")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUnusedSourceSetsReport() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) {
|
||||
setupWorkingDir()
|
||||
|
||||
gradleBuildScript().appendText("\nkotlin { sourceSets { foo { } } }")
|
||||
|
||||
build {
|
||||
assertSuccessful()
|
||||
assertContains(UnusedSourceSetsChecker.WARNING_PREFIX_ONE, UnusedSourceSetsChecker.WARNING_INTRO)
|
||||
}
|
||||
|
||||
gradleBuildScript().appendText("\nkotlin { sourceSets { bar { dependsOn foo } } }")
|
||||
|
||||
build {
|
||||
assertSuccessful()
|
||||
assertContains(UnusedSourceSetsChecker.WARNING_PREFIX_MANY, UnusedSourceSetsChecker.WARNING_INTRO)
|
||||
}
|
||||
|
||||
gradleBuildScript().appendText("\nkotlin { sourceSets { jvm6Main { dependsOn bar } } }")
|
||||
|
||||
build {
|
||||
assertSuccessful()
|
||||
assertNotContains(
|
||||
UnusedSourceSetsChecker.WARNING_PREFIX_ONE,
|
||||
UnusedSourceSetsChecker.WARNING_PREFIX_MANY,
|
||||
UnusedSourceSetsChecker.WARNING_INTRO
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-9
@@ -94,6 +94,8 @@ class KotlinMultiplatformPlugin(
|
||||
|
||||
// propagate compiler plugin options to the source set language settings
|
||||
setupCompilerPluginOptions(project)
|
||||
|
||||
UnusedSourceSetsChecker.checkSourceSets(project)
|
||||
}
|
||||
|
||||
private fun setupCompilerPluginOptions(project: Project) {
|
||||
@@ -104,14 +106,7 @@ class KotlinMultiplatformPlugin(
|
||||
.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||
|
||||
val primaryCompilationsBySourceSet by lazy { // don't evaluate eagerly: Android targets are not created at this point
|
||||
val allCompilationsForSourceSets =
|
||||
project.multiplatformExtension!!.targets
|
||||
.flatMap { target ->
|
||||
target.compilations.flatMap { compilation ->
|
||||
compilation.allKotlinSourceSets.map { it to compilation }
|
||||
}
|
||||
}
|
||||
.groupBy(keySelector = { (sourceSet, _) -> sourceSet }, valueTransform = { (_, compilation) -> compilation })
|
||||
val allCompilationsForSourceSets = compilationsBySourceSet(project)
|
||||
|
||||
allCompilationsForSourceSets.mapValues { (_, compilations) -> // choose one primary compilation
|
||||
when (compilations.size) {
|
||||
@@ -305,4 +300,15 @@ class KotlinMultiplatformPlugin(
|
||||
}
|
||||
}
|
||||
|
||||
internal val KotlinTarget.defaultArtifactId get() = "${project.name}-${name.toLowerCase()}"
|
||||
internal val KotlinTarget.defaultArtifactId get() = "${project.name}-${name.toLowerCase()}"
|
||||
|
||||
internal fun compilationsBySourceSet(project: Project): Map<KotlinSourceSet, Set<KotlinCompilation>> =
|
||||
HashMap<KotlinSourceSet, MutableSet<KotlinCompilation>>().also { result ->
|
||||
for (target in project.multiplatformExtension!!.targets) {
|
||||
for (compilation in target.compilations) {
|
||||
for (sourceSet in compilation.allKotlinSourceSets) {
|
||||
result.getOrPut(sourceSet) { mutableSetOf() }.add(compilation)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.mpp
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
|
||||
object UnusedSourceSetsChecker {
|
||||
const val WARNING_PREFIX_ONE =
|
||||
"The Kotlin source set"
|
||||
|
||||
const val WARNING_PREFIX_MANY =
|
||||
"The following Kotlin source sets were"
|
||||
|
||||
const val WARNING_INTRO = "configured but not added to any Kotlin compilation"
|
||||
|
||||
const val WARNING_BOTTOM_LINE =
|
||||
"You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'.\n" +
|
||||
"See https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#connecting-source-sets"
|
||||
|
||||
private fun reportUnusedSourceSets(project: Project, sourceSets: Set<KotlinSourceSet>) {
|
||||
require(sourceSets.isNotEmpty())
|
||||
val message = when (sourceSets.size) {
|
||||
1 -> "$WARNING_PREFIX_ONE ${sourceSets.single().name} was $WARNING_INTRO. $WARNING_BOTTOM_LINE"
|
||||
else -> {
|
||||
val list = sourceSets.joinToString("\n", "\n", "\n") { " * ${it.name}" }
|
||||
"$WARNING_PREFIX_MANY $WARNING_INTRO:$list$WARNING_BOTTOM_LINE"
|
||||
}
|
||||
}
|
||||
project.logger.warn("\n" + message) // make sure the message stands out
|
||||
}
|
||||
|
||||
fun checkSourceSets(project: Project) {
|
||||
project.afterEvaluate {
|
||||
val compilationsBySourceSet = compilationsBySourceSet(project)
|
||||
val unusedSourceSets = project.kotlinExtension.sourceSets.filter {
|
||||
compilationsBySourceSet[it]?.isEmpty() ?: true
|
||||
}
|
||||
if (unusedSourceSets.isNotEmpty()) {
|
||||
reportUnusedSourceSets(project, unusedSourceSets.toSet())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user