diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index a6cc312853c..b7c117d82c0 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -8,7 +8,4 @@ - - - \ No newline at end of file + diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MultiplatformAndroidSourceSetLayoutV2IT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MultiplatformAndroidSourceSetLayoutV2IT.kt index 063a96ff526..5b93e3eb024 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MultiplatformAndroidSourceSetLayoutV2IT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MultiplatformAndroidSourceSetLayoutV2IT.kt @@ -8,14 +8,45 @@ package org.jetbrains.kotlin.gradle import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.testbase.* import org.junit.jupiter.api.DisplayName +import kotlin.test.assertNull @MppGradlePluginTests -@DisplayName("Multiplatform Build Reproducibility") +@DisplayName("Multiplatform Android Source Set Layout 2") class MultiplatformAndroidSourceSetLayoutV2IT : KGPBaseTest() { @GradleAndroidTest + @DisplayName("test Android project with flavors") @AndroidTestVersions(minVersion = "7.0.4") fun testProjectWithFlavors(gradleVersion: GradleVersion, agpVersion: String, jdkVersion: JdkVersions.ProvidedJdk) { - val buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion) + project( + "multiplatformAndroidSourceSetLayout2", + gradleVersion, + defaultBuildOptions.copy(androidVersion = agpVersion), + buildJdk = jdkVersion.location + ) { + build("test") { + assertTasksExecuted(":testUsaPaidReleaseUnitTest") + assertTasksExecuted(":testUsaPaidDebugUnitTest") + assertTasksExecuted(":testUsaFreeReleaseUnitTest") + assertTasksExecuted(":testUsaFreeDebugUnitTest") + + assertTasksExecuted(":testGermanPaidReleaseUnitTest") + assertTasksExecuted(":testGermanPaidDebugUnitTest") + assertTasksExecuted(":testGermanFreeReleaseUnitTest") + assertTasksExecuted(":testGermanFreeDebugUnitTest") + + assertNull(task(":assembleUsaPaidDebugAndroidTest")) + assertNull(task(":assembleUsaFreeDebugAndroidTest")) + assertNull(task(":assembleGermanPaidDebugAndroidTest")) + assertNull(task(":assembleGermanFreeDebugAndroidTest")) + } + + build("assembleAndroidTest") { + assertTasksExecuted(":assembleUsaPaidDebugAndroidTest") + assertTasksExecuted(":assembleUsaFreeDebugAndroidTest") + assertTasksExecuted(":assembleGermanPaidDebugAndroidTest") + assertTasksExecuted(":assembleGermanFreeDebugAndroidTest") + } + } } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/build.gradle.kts new file mode 100644 index 00000000000..d83cc673ab6 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/build.gradle.kts @@ -0,0 +1,63 @@ +@file:OptIn(ExperimentalKotlinGradlePluginApi::class) + +import org.jetbrains.kotlin.gradle.plugin.ExperimentalKotlinGradlePluginApi + +plugins { + id("com.android.library") + kotlin("multiplatform") +} + + +android { + compileSdk = 31 + defaultConfig { + minSdk = 31 + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + 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" +} + +repositories { + mavenLocal() + mavenCentral() + google() +} + +kotlin { + android() + jvm() + + val commonMain by sourceSets.getting + val commonTest by sourceSets.getting + val androidMain by sourceSets.getting + + val androidUnitTest by sourceSets.getting + val androidInstrumentedTest by sourceSets.getting + + commonTest.dependencies { + implementation(kotlin("test-junit")) + } + + androidUnitTest.dependencies { + implementation("org.robolectric:robolectric:4.8") + implementation("androidx.test:core:1.4.0") + implementation("androidx.test:core-ktx:1.4.0") + } + + androidInstrumentedTest.dependencies { + implementation("androidx.test:runner:1.4.0") + implementation("androidx.test:rules:1.4.0") + } + + sourceSets.invokeWhenCreated("androidUnitTestGermanFreeDebug") { + dependencies { + implementation("com.squareup.okio:okio:3.2.0") + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/gradle.properties b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/gradle.properties new file mode 100644 index 00000000000..df5f3ea09bf --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/gradle.properties @@ -0,0 +1,2 @@ +kotlin.mpp.androidSourceSetLayoutVersion=2 +android.useAndroidX=true diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidInstrumentedTest/kotlin/AndroidInstrumentedTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidInstrumentedTest/kotlin/AndroidInstrumentedTest.kt new file mode 100644 index 00000000000..150da558edc --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidInstrumentedTest/kotlin/AndroidInstrumentedTest.kt @@ -0,0 +1,13 @@ +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Test + +class AndroidInstrumentedTest { + + @Test + fun someTest() { + commonMainExpect() + CommonMain.invoke() + AndroidMain.invoke() + AndroidMain.invoke(InstrumentationRegistry.getInstrumentation().targetContext.applicationContext) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/AndroidManifest.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/AndroidManifest.xml new file mode 100644 index 00000000000..90c72fdddb1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/AndroidMain.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/AndroidMain.kt new file mode 100644 index 00000000000..fead70440b1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/AndroidMain.kt @@ -0,0 +1,14 @@ +import android.app.Application +import android.content.Context + +object AndroidMain { + operator fun invoke(context: Context): AndroidMain { + context.applicationContext + return this + } + + operator fun invoke(): AndroidMain { + CommonMain.invoke() + return AndroidMain + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/commonMainExpect.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/commonMainExpect.kt new file mode 100644 index 00000000000..63da8a1c5bb --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/commonMainExpect.kt @@ -0,0 +1,3 @@ +actual fun commonMainExpect(): CommonMain { + return CommonMain.invoke() +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTest/kotlin/AndroidUnitTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTest/kotlin/AndroidUnitTest.kt new file mode 100644 index 00000000000..a0fbc5dedba --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTest/kotlin/AndroidUnitTest.kt @@ -0,0 +1,16 @@ +import androidx.test.core.app.ApplicationProvider +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class AndroidUnitTest { + @Test + fun someTest() { + commonMainExpect() + CommonMain.invoke() + AndroidMain.invoke() + AndroidMain.invoke(ApplicationProvider.getApplicationContext()) + CommonTest().someTest() + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTestGermanFreeDebug/kotlin/AndroidUnitTestGermanFreeDebug.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTestGermanFreeDebug/kotlin/AndroidUnitTestGermanFreeDebug.kt new file mode 100644 index 00000000000..9e43e671cd3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTestGermanFreeDebug/kotlin/AndroidUnitTestGermanFreeDebug.kt @@ -0,0 +1,18 @@ +import androidx.test.core.app.ApplicationProvider +import okio.Path.Companion.toPath +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class AndroidUnitTestGermanFreeDebug { + @Test + fun someTest() { + "".toPath() + commonMainExpect() + CommonMain.invoke() + AndroidMain.invoke() + AndroidMain.invoke(ApplicationProvider.getApplicationContext()) + CommonTest().someTest() + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonMain/kotlin/CommonMain.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonMain/kotlin/CommonMain.kt new file mode 100644 index 00000000000..628e069e151 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonMain/kotlin/CommonMain.kt @@ -0,0 +1,5 @@ +object CommonMain { + operator fun invoke() = CommonMain +} + +expect fun commonMainExpect(): CommonMain diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonTest/kotlin/CommonTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonTest/kotlin/CommonTest.kt new file mode 100644 index 00000000000..140a6e0de82 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonTest/kotlin/CommonTest.kt @@ -0,0 +1,9 @@ +import kotlin.test.Test + +class CommonTest { + @Test + fun someTest() { + commonMainExpect() + CommonMain.invoke() + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmMain/kotlin/commonMainExpect.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmMain/kotlin/commonMainExpect.kt new file mode 100644 index 00000000000..63da8a1c5bb --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmMain/kotlin/commonMainExpect.kt @@ -0,0 +1,3 @@ +actual fun commonMainExpect(): CommonMain { + return CommonMain.invoke() +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmTest/kotlin/JvmTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmTest/kotlin/JvmTest.kt new file mode 100644 index 00000000000..de95f68dae6 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmTest/kotlin/JvmTest.kt @@ -0,0 +1,9 @@ +import org.junit.Test + +class JvmTest { + @Test + fun someTest() { + CommonMain.invoke() + CommonTest().someTest() + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSets.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSets.kt index 9d062609394..4dc50758881 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSets.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSets.kt @@ -34,7 +34,11 @@ internal object KotlinAndroidSourceSets { /* Ensures that each KotlinSourceSet only invokes the 'configurator' once */ val configuredKotlinSourceSets = mutableSetOf() - /* Hook eagerly into AndroidSourceSet creation */ + /* + Hook eagerly into AndroidSourceSet creation + Some 'base' source sets shall be created eagerly, as soon as available, too also + make them available in the buildscript dsl immediately. + */ android.sourceSets.all { androidSourceSet -> val kotlinSourceSetName = naming.kotlinSourceSetName(target.disambiguationClassifier, androidSourceSet.name) ?: return@all val kotlinSourceSet = kotlin.getOrCreateKotlinSourceSet(kotlinSourceSetName, androidSourceSet) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidSourceSetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidSourceSetConfigurator.kt index 42b4ba748eb..5c3643c498b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidSourceSetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidSourceSetConfigurator.kt @@ -35,21 +35,6 @@ internal fun KotlinAndroidSourceSetConfigurator( return CompositeKotlinAndroidSourceSetConfigurator(configurators.filterNotNull()) } -internal operator fun KotlinAndroidSourceSetConfigurator.plus( - other: KotlinAndroidSourceSetConfigurator -): KotlinAndroidSourceSetConfigurator { - val configurators = when { - this is CompositeKotlinAndroidSourceSetConfigurator && other is CompositeKotlinAndroidSourceSetConfigurator -> - this.configurators + other.configurators - - this is CompositeKotlinAndroidSourceSetConfigurator -> this.configurators + other - other is CompositeKotlinAndroidSourceSetConfigurator -> listOf(this) + other.configurators - else -> listOf(this, other) - } - - return CompositeKotlinAndroidSourceSetConfigurator(configurators) -} - private class CompositeKotlinAndroidSourceSetConfigurator( val configurators: List ) : KotlinAndroidSourceSetConfigurator {