From 269410d7aa5377144d8903774b25329eb0155216 Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Wed, 12 Sep 2018 19:08:41 +0300 Subject: [PATCH] Build source sets hierarchy in Android projects Instead of simply adding all Kotlin source sets participating in an Android compilation, as was appropriate until we introduced the dependsOn relation, we should now build a proper source sets hierarchy. --- .../AbstractKotlinAndroidGradleTests.kt | 31 ++++++++++++++++ .../new-mpp-android/lib/build.gradle | 8 +++++ .../kotlin/gradle/plugin/KotlinPlugin.kt | 36 +++++++++++++------ 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt index 6758e816484..a7051297764 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt @@ -8,6 +8,7 @@ import org.jetbrains.kotlin.gradle.util.modify import org.jetbrains.kotlin.test.KotlinTestUtils import org.junit.Test import java.io.File +import kotlin.test.assertEquals class KotlinAndroidGradleIT : AbstractKotlinAndroidGradleTests(androidGradlePluginVersion = "2.3.0") { @@ -22,6 +23,36 @@ class KotlinAndroid32GradleIT : KotlinAndroid3GradleIT(androidGradlePluginVersio @Test fun testAndroidWithNewMppApp() = with(Project("new-mpp-android")) { + build("printSourceSetDependsOnRelations") { + val dependsOnReportRegex = "(\\w+?) dependsOn \\[(.*?)]".toRegex() + val dependsOnRelations = dependsOnReportRegex + .findAll(output) + .associate { it.groupValues[1] to it.groupValues[2].split(", ").toSet() } + + val expectedDependsOnRelations = listOf( + "androidLibMain" to setOf("commonMain"), + "androidLibDebug" to setOf("commonMain", "androidLibMain"), // compilation + "androidLibRelease" to setOf("commonMain", "androidLibMain"), // compilation + + "androidLibTest" to setOf("commonTest"), + "androidLibTestDebug" to setOf("commonTest"), + "androidLibTestRelease" to setOf("commonTest"), + "androidLibAndroidTestDebug" to setOf("commonTest"), + "androidLibAndroidTest" to setOf("commonTest"), + "androidLibDebugAndroidTest" to setOf("commonTest", "androidLibAndroidTest", "androidLibAndroidTestDebug"), // compilation + "androidLibDebugUnitTest" to setOf("commonTest", "androidLibTest", "androidLibTestDebug"), // compilation + "androidLibReleaseUnitTest" to setOf("commonTest", "androidLibTest", "androidLibTestRelease") // compilation + ) + + for ((sourceSetName, expectedDependsOn) in expectedDependsOnRelations) { + assertEquals( + expectedDependsOn, + dependsOnRelations[sourceSetName], + "source set $sourceSetName should depend on $expectedDependsOn" + ) + } + } + build("assemble", "compileDebugUnitTestJavaWithJavac") { assertSuccessful() diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-android/lib/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-android/lib/build.gradle index 8ee1a222fcb..feba04070a4 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-android/lib/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/new-mpp-android/lib/build.gradle @@ -51,4 +51,12 @@ kotlin { fromPreset(presets.jvm, 'jvmLib') fromPreset(presets.js, 'jsLib') } +} + +task printSourceSetDependsOnRelations { + doFirst { + kotlin.sourceSets.each { sourceSet -> + println sourceSet.name + " dependsOn " + sourceSet.dependsOn.collect { it.name } + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index 1b869979675..501fbdb9030 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -718,17 +718,9 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT kotlinTask.destinationDir = File(project.buildDir, "tmp/kotlin-classes/$variantDataName") kotlinTask.description = "Compiles the $variantDataName kotlin." - // Register the source only after the task is created, because tne task is required for that: - compilation.source(defaultSourceSet) configureSources(kotlinTask, variantData, compilation) - - // In MPPs, add the common main Kotlin sources to non-test variants, the common test sources to test variants - val commonSourceSetName = if (getTestedVariantData(variantData) == null) - KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME else - KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME - project.kotlinExtension.sourceSets.findByName(commonSourceSetName)?.let { - compilation.source(it) - } + // Register the source only after the task is created and source set relations are built: + compilation.source(defaultSourceSet) wireKotlinTasks(project, compilation, androidPlugin, androidExt, variantData, javaTask, kotlinTask) } @@ -752,10 +744,32 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT private fun configureSources(compileTask: AbstractCompile, variantData: V, compilation: KotlinCompilation?) { val logger = compileTask.project.logger + val commonSourceSet = compilation?.run { + target.project.kotlinExtension.sourceSets.run { + // In MPPs, add the common main Kotlin sources to dependsOn of non-test variants, the common test sources to test variants + val commonSourceSetName = if (getTestedVariantData(variantData) == null) + KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME else + KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME + + findByName(commonSourceSetName)?.also { common -> + getByName(compilation.defaultSourceSetName).dependsOn(common) + } + } + } + + val defaultSourceSet = compilation?.run { + target.project.kotlinExtension.sourceSets.getByName(defaultSourceSetName) + } + for (provider in getSourceProviders(variantData)) { val kotlinSourceSet = provider.getConvention(KOTLIN_DSL_NAME) as? KotlinSourceSet ?: continue if (compilation != null) { - compilation.source(kotlinSourceSet) + if (commonSourceSet != null) { + kotlinSourceSet.dependsOn(commonSourceSet) + } + if (kotlinSourceSet != defaultSourceSet) { + defaultSourceSet!!.dependsOn(kotlinSourceSet) + } } else { compileTask.source(kotlinSourceSet.kotlin) }