From 7ff53deea56a2f74c02ff2a13b572a4c8fdab23b Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Wed, 29 Aug 2018 20:10:35 +0300 Subject: [PATCH] Generate and publish `*-sources.jar` for each target --- .../kotlin/gradle/NewMultiplatformIT.kt | 36 ++++++++++++++++++- .../plugin/mpp/KotlinMultiplatformPlugin.kt | 32 +++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index 54c5b360c5d..95d2556f19b 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -15,7 +15,9 @@ import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.HostManager import org.junit.Assert import org.junit.Test +import java.util.jar.JarFile import java.util.zip.ZipFile +import kotlin.test.assertEquals import kotlin.test.assertTrue class NewMultiplatformIT : BaseGradleIT() { @@ -412,10 +414,11 @@ class NewMultiplatformIT : BaseGradleIT() { assertFileExists("repo/com/example/sample-lib-$publishedVariant/1.0/sample-lib-$publishedVariant-1.0.klib") assertNoSuchFile("repo/com/example/sample-lib-$nonPublishedVariant") // check that no artifacts are published for that variant - // but check that the module metadata contains both variants: + // but check that the module metadata contains all variants: val gradleModuleMetadata = projectDir.resolve("repo/com/example/sample-lib/1.0/sample-lib-1.0.module").readText() assertTrue(""""name": "linux64-api"""" in gradleModuleMetadata) assertTrue(""""name": "mingw64-api"""" in gradleModuleMetadata) + assertTrue(""""name": "macos64-api"""" in gradleModuleMetadata) } } @@ -512,4 +515,35 @@ class NewMultiplatformIT : BaseGradleIT() { assertTasksExecuted(linkTasks[0]) } } + + @Test + fun testSourceJars() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) { + setupWorkingDir() + + build("publish") { + assertSuccessful() + + val nativeHostTargetName = when { + HostManager.hostIsMingw -> "mingw64" + HostManager.hostIsLinux -> "linux64" + HostManager.hostIsMac -> "macos64" + else -> error("Unknown host") + } + + val groupDir = projectDir.resolve("repo/com/example/") + val targetArtifactIdAppendices = listOf("metadata", "jvm6", "nodejs", "wasm32", nativeHostTargetName) + + val sourceJarSourceRoots = targetArtifactIdAppendices.associate { artifact -> + val sourcesJar = JarFile(groupDir.resolve("sample-lib-$artifact/1.0/sample-lib-$artifact-1.0-sources.jar")) + val sourcesDirs = sourcesJar.entries().asSequence().map { it.name.substringBefore("/") }.toSet() - "META-INF" + artifact to sourcesDirs + } + + assertEquals(setOf("commonMain"), sourceJarSourceRoots["metadata"]) + assertEquals(setOf("commonMain", "jvm6Main"), sourceJarSourceRoots["jvm6"]) + assertEquals(setOf("commonMain", "nodeJsMain"), sourceJarSourceRoots["nodejs"]) + assertEquals(setOf("commonMain", "wasm32Main"), sourceJarSourceRoots["wasm32"]) + assertEquals(setOf("commonMain", "${nativeHostTargetName}Main"), sourceJarSourceRoots[nativeHostTargetName]) + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt index f16f81562ef..a574dc7947c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt @@ -19,6 +19,7 @@ import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal import org.gradle.internal.cleanup.BuildOutputCleanupRegistry import org.gradle.internal.reflect.Instantiator +import org.gradle.jvm.tasks.Jar import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.kotlinExtension @@ -70,6 +71,7 @@ class KotlinMultiplatformPlugin( setUpConfigurationAttributes(project) configurePublishingWithMavenPublish(project) + configureSourceJars(project) // set up metadata publishing targetsFromPreset.fromPreset( @@ -110,9 +112,12 @@ class KotlinMultiplatformPlugin( val name = target.name val variantPublication = publishing.publications.create(name, MavenPublication::class.java).apply { - // do this in afterEvaluate since older Gradle versions seem to check the files in the variant eagerly: - project.afterEvaluate { + // do this in whenEvaluated since older Gradle versions seem to check the files in the variant eagerly: + project.whenEvaluated { from(variant) + (project.tasks.findByName(target.sourcesJarTaskName) as Jar?)?.let { sourcesJar -> + artifact(sourcesJar) + } } (this as MavenPublicationInternal).publishWithOriginalFileName() artifactId = "${project.name}-${variant.target.name.toLowerCase()}" @@ -130,6 +135,29 @@ class KotlinMultiplatformPlugin( } } + private val KotlinTarget.sourcesJarTaskName get() = disambiguateName("sourcesJar") + + private fun configureSourceJars(project: Project) = with(project.kotlinExtension as KotlinMultiplatformExtension) { + targets.all { target -> + val mainCompilation = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) + ?: return@all + + val sourcesJar = project.tasks.create(target.sourcesJarTaskName, Jar::class.java) { sourcesJar -> + sourcesJar.appendix = target.targetName.toLowerCase() + sourcesJar.classifier = "sources" + } + + project.afterEvaluate { _ -> + val compiledSourceSets = mainCompilation.allKotlinSourceSets + compiledSourceSets.forEach { sourceSet -> + sourcesJar.from(sourceSet.kotlin) { copySpec -> + copySpec.into(sourceSet.name) + } + } + } + } + } + private fun configureSourceSets(project: Project) = with (project.kotlinExtension as KotlinMultiplatformExtension) { val production = sourceSets.create(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) val test = sourceSets.create(KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME)