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 dc5b9558885..58f2c5ffc04 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,8 +15,6 @@ import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.HostManager import org.junit.Assert import org.junit.Test -import java.io.File -import java.lang.StringBuilder import java.util.jar.JarFile import java.util.zip.ZipFile import kotlin.test.assertEquals @@ -1618,4 +1616,81 @@ class NewMultiplatformIT : BaseGradleIT() { assertCompiledKotlinSources(project.relativize(libJsPlatformUtilKt, useLibJsPlatformUtilKt)) } } + + @Test + fun testPomRewritingInSinglePlatformProject() = with(Project("kt-27059-pom-rewriting", GradleVersionRequired.AtLeast("4.10.2"))) { + setupWorkingDir() + gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl) + + val groupDir = "build/repo/com/example/" + + build(":mpp-lib:publish") { + assertSuccessful() + assertFileExists(groupDir + "mpp-lib") + assertFileExists(groupDir + "mpp-lib-myjvm") + } + + fun doTestPomRewriting(mppProjectDependency: Boolean, legacyPublishing: Boolean, keepPomIntact: Boolean? = null) { + + val params = mutableListOf("clean", ":jvm-app:publish", ":js-app:publish").apply { + if (mppProjectDependency) + add("-PmppProjectDependency=true") + if (legacyPublishing) + add("-PlegacyPublishing=true") + if (keepPomIntact == true) + add("-Pkotlin.mpp.keepMppDependenciesIntactInPoms=true") + }.toTypedArray() + + build(*params) { + assertSuccessful() + if (legacyPublishing) { + assertTasksExecuted(":jvm-app:uploadArchives") + assertTasksExecuted(":js-app:uploadArchives") + } else { + assertTasksExecuted(":jvm-app:publishMainPublicationToMavenRepository") + assertTasksExecuted(":js-app:publishMainPublicationToMavenRepository") + } + + val jvmModuleDir = groupDir + "jvm-app/1.0/" + val jsModuleDir = groupDir + "js-app/1.0/" + val jvmPom = fileInWorkingDir(jvmModuleDir + "jvm-app-1.0.pom").readText().replace("\\s+".toRegex(), "") + val jsPom = fileInWorkingDir(jsModuleDir + "js-app-1.0.pom").readText().replace("\\s+".toRegex(), "") + + if (keepPomIntact != true) { + assertTrue("The JVM POM should contain the dependency on 'mpp-lib' rewritten as 'mpp-lib-myjvm'") { + jvmPom.contains( + "com.examplempp-lib-myjvm1.0compile" + ) + } + assertTrue("The JS POM should contain the dependency on 'mpp-lib' rewritten as 'mpp-lib-js'") { + jsPom.contains( + "com.examplempp-lib-js1.0compile" + ) + } + } else { + assertTrue("The JVM POM should contain the original dependency on 'mpp-lib'") { + jvmPom.contains( + "com.examplempp-lib1.0compile" + ) + } + assertTrue("The JS POM should contain the original dependency on 'mpp-lib'") { + jsPom.contains( + "com.examplempp-lib1.0compile" + ) + } + } + } + } + + doTestPomRewriting(mppProjectDependency = false, legacyPublishing = false) + doTestPomRewriting(mppProjectDependency = false, legacyPublishing = true) + doTestPomRewriting(mppProjectDependency = true, legacyPublishing = false) + + // This case doesn't work and never did; TODO investigate KT-29975 + // doTestPomRewriting(mppProjectDependency = true, legacyPublishing = true) + + // Also check that the flag for keeping POMs intact works: + doTestPomRewriting(mppProjectDependency = false, legacyPublishing = false, keepPomIntact = true) + doTestPomRewriting(mppProjectDependency = false, legacyPublishing = true, keepPomIntact = true) + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/build.gradle new file mode 100644 index 00000000000..5e0840d7a43 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/build.gradle @@ -0,0 +1,10 @@ +plugins { + id "org.jetbrains.kotlin.multiplatform" version "" apply false +} + +allprojects { + repositories { + mavenLocal() + jcenter() + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/js-app/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/js-app/build.gradle new file mode 100644 index 00000000000..de4922b4254 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/js-app/build.gradle @@ -0,0 +1,62 @@ +plugins { + id "kotlin2js" +} + +group = "com.example" +version = "1.0" + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-js" +} + +if (project.findProperty("mppProjectDependency") == "true") { + + dependencies { + api project(":mpp-lib") + } + +} else { + + repositories { + maven { setUrl "${rootProject.buildDir}/repo" } + } + + dependencies { + api "com.example:mpp-lib:1.0" + } + +} + + +if (project.findProperty("legacyPublishing") == "true") { + + apply plugin: 'maven' + + uploadArchives { + repositories { + mavenDeployer { + repository(url: "file://${rootProject.buildDir}/repo") + } + } + } + + tasks.create("publish") { + dependsOn uploadArchives + } + +} else { + + apply plugin: 'maven-publish' + + publishing { + publications { + main(MavenPublication) { + from components.java + } + } + repositories { + maven { setUrl("${rootProject.buildDir}/repo") } + } + } + +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/js-app/src/main/kotlin/A.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/js-app/src/main/kotlin/A.kt new file mode 100644 index 00000000000..13180bda65b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/js-app/src/main/kotlin/A.kt @@ -0,0 +1,5 @@ +import com.example.mpp.lib.* + +fun main() { + println(hello()) +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/jvm-app/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/jvm-app/build.gradle new file mode 100644 index 00000000000..b088a3f6540 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/jvm-app/build.gradle @@ -0,0 +1,62 @@ +plugins { + id "org.jetbrains.kotlin.jvm" +} + +group = "com.example" +version = "1.0" + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib" +} + +if (project.findProperty("mppProjectDependency") == "true") { + + dependencies { + api project(":mpp-lib") + } + +} else { + + repositories { + maven { setUrl "${rootProject.buildDir}/repo" } + } + + dependencies { + api "com.example:mpp-lib:1.0" + } + +} + + +if (project.findProperty("legacyPublishing") == "true") { + + apply plugin: 'maven' + + uploadArchives { + repositories { + mavenDeployer { + repository(url: "file://${rootProject.buildDir}/repo") + } + } + } + + tasks.create("publish") { + dependsOn uploadArchives + } + +} else { + + apply plugin: 'maven-publish' + + publishing { + publications { + main(MavenPublication) { + from components.java + } + } + repositories { + maven { setUrl("${rootProject.buildDir}/repo") } + } + } + +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/jvm-app/src/main/kotlin/A.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/jvm-app/src/main/kotlin/A.kt new file mode 100644 index 00000000000..13180bda65b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/jvm-app/src/main/kotlin/A.kt @@ -0,0 +1,5 @@ +import com.example.mpp.lib.* + +fun main() { + println(hello()) +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/mpp-lib/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/mpp-lib/build.gradle new file mode 100644 index 00000000000..686876fbf8f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/mpp-lib/build.gradle @@ -0,0 +1,42 @@ +plugins { + id "org.jetbrains.kotlin.multiplatform" + id "maven-publish" +} + +group = "com.example" +version = "1.0" + +kotlin { + jvm() + js() + + sourceSets { + commonMain { + dependencies { + implementation 'org.jetbrains.kotlin:kotlin-stdlib-common' + } + } + jvmMain { + dependencies { + implementation 'org.jetbrains.kotlin:kotlin-stdlib' + } + } + jsMain { + dependencies { + implementation 'org.jetbrains.kotlin:kotlin-stdlib-js' + } + } + } +} + +publishing { + publications { + jvm { + artifactId = "mpp-lib-myjvm" + } + } + + repositories { + maven { setUrl("${rootProject.buildDir}/repo") } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/mpp-lib/src/commonMain/kotlin/Hello.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/mpp-lib/src/commonMain/kotlin/Hello.kt new file mode 100644 index 00000000000..003c59d9d22 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/mpp-lib/src/commonMain/kotlin/Hello.kt @@ -0,0 +1,3 @@ +package com.example.mpp.lib + +fun hello(): String = "hello" \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/settings.gradle new file mode 100644 index 00000000000..03c6fa830f9 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-27059-pom-rewriting/settings.gradle @@ -0,0 +1,18 @@ +pluginManagement { + resolutionStrategy { + eachPlugin { + if (requested.id.id == "kotlin2js") { + useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") + } + } + } + repositories { + mavenLocal() + jcenter() + gradlePluginPortal() + } +} + +enableFeaturePreview('GRADLE_METADATA') + +include(":mpp-lib", ":jvm-app", ":js-app") \ 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 a64ee2c8396..e778c0cf7ae 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 @@ -7,6 +7,7 @@ import groovy.lang.Closure import org.gradle.api.* import org.gradle.api.artifacts.ExternalDependency import org.gradle.api.artifacts.MutableVersionConstraint +import org.gradle.api.artifacts.maven.MavenResolver import org.gradle.api.attributes.Usage import org.gradle.api.file.FileCollection import org.gradle.api.file.SourceDirectorySet @@ -15,9 +16,12 @@ import org.gradle.api.logging.Logging import org.gradle.api.plugins.InvalidPluginException import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.tasks.CompileClasspathNormalizer import org.gradle.api.tasks.Delete import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.Upload import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.JavaCompile @@ -27,7 +31,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl import org.jetbrains.kotlin.gradle.dsl.KotlinSingleJavaTargetExtension import org.jetbrains.kotlin.gradle.dsl.kotlinExtension -import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedClassesDir import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin import org.jetbrains.kotlin.gradle.internal.KaptVariantData import org.jetbrains.kotlin.gradle.internal.checkAndroidAnnotationProcessorDependencyUsage @@ -348,10 +351,41 @@ internal abstract class AbstractKotlinPlugin( { compilation -> buildSourceSetProcessor(project, compilation, kotlinPluginVersion) } ) + rewriteMppDependenciesInPom(target) + configureProjectGlobalSettings(project, kotlinPluginVersion) registry.register(KotlinModelBuilder(kotlinPluginVersion, null)) } + private fun rewriteMppDependenciesInPom(target: KotlinTarget) { + val project = target.project + + fun shouldRewritePoms(): Boolean = + PropertiesProvider(project).keepMppDependenciesIntactInPoms != true + + project.pluginManager.withPlugin("maven-publish") { + project.extensions.configure(PublishingExtension::class.java) { publishing -> + publishing.publications.withType(MavenPublication::class.java).all { publication -> + publication.pom.withXml { xml -> + if (shouldRewritePoms()) + project.rewritePomMppDependenciesToActualTargetModules(xml, target.components.single()) + } + } + } + } + + project.pluginManager.withPlugin("maven") { + project.tasks.withType(Upload::class.java).all { uploadTask -> + uploadTask.repositories.withType(MavenResolver::class.java).all { mavenResolver -> + mavenResolver.pom.withXml { xml -> + if (shouldRewritePoms()) + project.rewritePomMppDependenciesToActualTargetModules(xml, target.components.single()) + } + } + } + } + } + companion object { fun configureProjectGlobalSettings(project: Project, kotlinPluginVersion: String) { configureDefaultVersionsResolutionStrategy(project, kotlinPluginVersion) @@ -527,6 +561,7 @@ internal open class KotlinPlugin( (project.kotlinExtension as KotlinSingleJavaTargetExtension).target = target project.pluginManager.apply(ScriptingGradleSubplugin::class.java) + super.apply(project) } }