diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/HierarchicalMppIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/HierarchicalMppIT.kt index f0016de78cf..d96814b678d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/HierarchicalMppIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/HierarchicalMppIT.kt @@ -24,12 +24,11 @@ import org.junit.jupiter.api.io.TempDir import java.io.File import java.nio.file.Path import java.util.zip.ZipFile -import kotlin.io.path.absolutePathString -import kotlin.io.path.appendText -import kotlin.io.path.writeText +import kotlin.io.path.* import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.test.assertTrue +import kotlin.test.fail @MppGradlePluginTests @DisplayName("Hierarchical multiplatform") @@ -921,6 +920,54 @@ class HierarchicalMppIT : KGPBaseTest() { } } + @GradleTest + @OsCondition(enabledOnCI = [OS.LINUX, OS.MAC, OS.WINDOWS]) + @DisplayName("Sources publication can be disabled per target") + fun testDisableSourcesPublication(gradleVersion: GradleVersion, @TempDir tempDir: Path) { + project( + "mpp-sources-publication/producer", + gradleVersion = gradleVersion, + localRepoDir = tempDir + ) { + // Disable sources publication for all targets except JVM + buildGradleKts.appendText( + """ + kotlin { + withSourcesJar(publish = false) + } + + kotlin.targets.getByName("jvm").withSourcesJar() + """.trimIndent() + ) + + build("publish") + + val gradleModuleFileContent = tempDir.resolve("test/lib/1.0/lib-1.0.module").readText() + fun assertNoSourcesPublished(expectedJarLocation: String, variantName: String) { + val jarFile = tempDir.resolve(expectedJarLocation).toFile() + if (jarFile.exists()) fail("Sources jar '$expectedJarLocation' shouldn't be published") + if (gradleModuleFileContent.contains(variantName)) fail("Variant '$variantName' shouldn't be published") + } + + assertNoSourcesPublished("test/lib/1.0/lib-1.0-sources.jar", "metadataSourcesElements") + assertNoSourcesPublished("test/lib-linuxx64/1.0/lib-linuxx64-1.0-sources.jar", "linuxX64SourcesElements-published") + assertNoSourcesPublished("test/lib-linuxarm64/1.0/lib-linuxarm64-1.0-sources.jar", "linuxArm64SourcesElements-published") + if (OS.MAC.isCurrentOs) { + assertNoSourcesPublished("test/lib-iosx64/1.0/lib-iosx64-1.0-sources.jar", "iosX64SourcesElements-published") + assertNoSourcesPublished("test/lib-iosarm64/1.0/lib-iosarm64-1.0-sources.jar", "iosArm64SourcesElements-published") + } + + // Check that JVM sources were published + val jvmSourcesJar = tempDir.resolve("test/lib-jvm/1.0/lib-jvm-1.0-sources.jar") + if (!jvmSourcesJar.exists()) { + fail("JVM Sources should be published") + } + if (!gradleModuleFileContent.contains("jvmSourcesElements-published")) { + fail("'jvmSourcesElements-published' variant should be published") + } + } + } + @GradleTest @DisplayName("KT-44845: all external dependencies is unresolved in IDE with kotlin.mpp.enableGranularSourceSetsMetadata=true") fun testMixedScopesFilesExistKt44845(gradleVersion: GradleVersion, @TempDir tempDir: Path) { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/KotlinAndroidMppIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/KotlinAndroidMppIT.kt index e13b40866cb..8e72c40ab36 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/KotlinAndroidMppIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/KotlinAndroidMppIT.kt @@ -418,6 +418,42 @@ class KotlinAndroidMppIT : KGPBaseTest() { } } } + @DisplayName("Sources publication can be disabled") + @GradleAndroidTest + fun testDisableSourcesPublication( + gradleVersion: GradleVersion, + agpVersion: String, + jdkVersion: JdkVersions.ProvidedJdk + ) { + project( + "new-mpp-android", + gradleVersion, + buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion), + buildJdk = jdkVersion.location + ) { + subProject("lib").buildGradle.appendText( + //language=Gradle + """ + + kotlin.android('androidLib') { + withSourcesJar(false) + publishLibraryVariants = ['release'] + } + """.trimIndent() + ) + + val groupDir = subProject("lib").projectPath.resolve("build/repo/com/example") + build("publish") { + val sourcesJarFile = groupDir.resolve("lib-androidlib/1.0/lib-androidlib-1.0-sources.jar").toFile() + if (sourcesJarFile.exists()) fail("Release sources jar should not be published") + + val gradleMetadataFileContent = groupDir.resolve("lib-androidlib/1.0/lib-androidlib-1.0.module").readText() + if (gradleMetadataFileContent.contains("releaseSourcesElements-published")) { + fail("'releaseSourcesElements-published' variant should not be published") + } + } + } + } @DisplayName("android mpp lib dependencies are properly rewritten") @GradleAndroidTest diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/MppPublicationTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/MppPublicationTest.kt index 68cb8ccab10..7aba86ed77f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/MppPublicationTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/MppPublicationTest.kt @@ -18,6 +18,7 @@ import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication import org.gradle.testfixtures.ProjectBuilder import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.mpp.internal import org.jetbrains.kotlin.gradle.util.addBuildEventsListenerRegistryMock import org.jetbrains.kotlin.gradle.util.disableLegacyWarning import kotlin.test.* @@ -145,6 +146,50 @@ class MppPublicationTest { } } + @Test + fun `test withSourcesJar DSL on extension level`() { + kotlin.linuxX64() + + kotlin.withSourcesJar(publish = false) + + for (target in kotlin.targets) { + assertFalse(target.internal.publishableSources) + } + } + + @Test + fun `test withSourcesJar DSL on target level`() { + kotlin.linuxX64("linux") { + withSourcesJar(publish = false) + } + + for (target in kotlin.targets) { + if (target.name == "linux") { + assertFalse(target.internal.publishableSources) + } else { + assertTrue(target.internal.publishableSources) + } + } + } + + @Test + fun `test that sourcesJar tasks still exist even if sources should not be published`() { + kotlin.linuxX64("linux") + kotlin.withSourcesJar(publish = false) + + val sourcesJars = listOf( + "sourcesJar", // sources of common source sets i.e. root module + "jvmSourcesJar", + "jsSourcesJar", + "linuxSourcesJar" + ) + + for (sourcesJarTaskName in sourcesJars) { + val sourcesJar = project.tasks.findByName(sourcesJarTaskName) + assertNotNull(sourcesJar, "Task '$sourcesJarTaskName' should exist during project configuration time") + } + } + private fun SoftwareComponent.attributesOfUsageContext(usageContextName: String): AttributeContainer { this as SoftwareComponentInternal return usages.first { it.name == usageContextName }.attributes