diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PublishingIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PublishingIT.kt index ea7f3ea3b7a..520e05b9c63 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PublishingIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PublishingIT.kt @@ -5,9 +5,12 @@ package org.jetbrains.kotlin.gradle +import org.gradle.api.logging.configuration.WarningMode import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.testbase.* import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.io.TempDir +import java.nio.file.Path import kotlin.io.path.appendText import kotlin.io.path.readLines import kotlin.io.path.readText @@ -107,4 +110,43 @@ class PublishingIT : KGPBaseTest() { } } } + + @DisplayName("Publication with old 'maven' plugin is working") + @GradleTest + @GradleTestVersions(maxVersion = TestVersions.Gradle.G_6_9) + fun testOldMavenPublishing( + gradleVersion: GradleVersion, + @TempDir localRepoDir: Path + ) { + project( + projectName = "old-maven-publish", + gradleVersion = gradleVersion, + localRepoDir = localRepoDir, + buildOptions = defaultBuildOptions.copy( + warningMode = WarningMode.Summary // 'maven' is deprecated + ) + ) { + build("uploadArchives") { + val publishingDir = localRepoDir.resolve("org.jetbrains.kotlin.example").resolve("1.0.0") + assertDirectoryExists(publishingDir) + assertFileExists(publishingDir.resolve("org.jetbrains.kotlin.example-1.0.0.jar")) + val pomFile = publishingDir.resolve("org.jetbrains.kotlin.example-1.0.0.pom") + assertFileExists(pomFile) + assertFileContains( + pomFile, + """ + | + | + | org.jetbrains.kotlin + | kotlin-stdlib + | ${buildOptions.kotlinVersion} + | compile + | + | + """.trimMargin() + ) + } + } + } + } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/old-maven-publish/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/old-maven-publish/build.gradle new file mode 100644 index 00000000000..3b87adc40b8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/old-maven-publish/build.gradle @@ -0,0 +1,23 @@ +plugins { + id "org.jetbrains.kotlin.jvm" + id "maven" +} + +repositories { + mavenLocal() + mavenCentral() +} + +dependencies { + api "org.jetbrains.kotlin:kotlin-stdlib" +} + +uploadArchives { + repositories { + mavenDeployer { + repository(url: "file://localhost") + pom.artifactId = "org.jetbrains.kotlin.example" + pom.version = "1.0.0" + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/old-maven-publish/src/main/kotlin/ExampleClass.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/old-maven-publish/src/main/kotlin/ExampleClass.kt new file mode 100644 index 00000000000..0b038b5a5f8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/old-maven-publish/src/main/kotlin/ExampleClass.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package testProject.publishing +class ExampleClass { + fun one() = 1 + + fun two() = 2 +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt index c32094c8275..73164095ac9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.KAPT_ import org.jetbrains.kotlin.gradle.internal.kapt.classloaders.ClassLoadersCache import org.jetbrains.kotlin.gradle.internal.kapt.classloaders.rootOrSelf import org.jetbrains.kotlin.gradle.internal.kapt.incremental.KaptIncrementalChanges -import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPluginWrapper +import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinAndroidPluginWrapper import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast @@ -46,7 +46,7 @@ abstract class KaptWithoutKotlincTask @Inject constructor( override fun configure(task: KaptWithoutKotlincTask) { super.configure(task) task.addJdkClassesToClasspath.value( - task.project.providers.provider { task.project.plugins.none { it is KotlinAndroidPluginWrapper } } + task.project.providers.provider { task.project.plugins.none { it is AbstractKotlinAndroidPluginWrapper } } ).disallowChanges() task.kaptJars.from(task.project.configurations.getByName(KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME)).disallowChanges() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformPlugin.kt index fff6e551681..c23f1c0d446 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformPlugin.kt @@ -40,13 +40,6 @@ abstract class KotlinPlatformPluginBase(protected val platformName: String) : Pl } } -open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") { - override fun apply(project: Project) { - warnAboutKotlin12xMppDeprecation(project) - project.applyPlugin() - } -} - const val EXPECTED_BY_CONFIG_NAME = "expectedBy" const val IMPLEMENT_CONFIG_NAME = "implement" @@ -252,39 +245,6 @@ internal fun Project.whenEvaluated(fn: Project.() -> T) { } } -open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase("android") { - override fun apply(project: Project) { - project.applyPlugin() - super.apply(project) - } - - override fun namedSourceSetsContainer(project: Project): NamedDomainObjectContainer<*> = - (project.extensions.getByName("android") as BaseExtension).sourceSets - - override fun addCommonSourceSetToPlatformSourceSet(commonSourceSet: Named, platformProject: Project) { - val androidExtension = platformProject.extensions.getByName("android") as BaseExtension - val androidSourceSet = androidExtension.sourceSets.findByName(commonSourceSet.name) ?: return - val kotlinSourceSet = androidSourceSet.getConvention(KOTLIN_DSL_NAME) as? KotlinSourceSet - ?: return - kotlinSourceSet.kotlin.source(getKotlinSourceDirectorySetSafe(commonSourceSet)!!) - } -} - -open class KotlinPlatformJvmPlugin : KotlinPlatformImplementationPluginBase("jvm") { - override fun apply(project: Project) { - project.applyPlugin() - super.apply(project) - } -} - -open class KotlinPlatformJsPlugin : KotlinPlatformImplementationPluginBase("js") { - override fun apply(project: Project) { - @Suppress("DEPRECATION_ERROR") - project.applyPlugin() - super.apply(project) - } -} - internal val KOTLIN_12X_MPP_DEPRECATION_WARNING = "\n" + """ The 'org.jetbrains.kotlin.platform.*' plugins are deprecated and will no longer be available in Kotlin 1.4. Please migrate the project to the 'org.jetbrains.kotlin.multiplatform' plugin. @@ -293,7 +253,7 @@ internal val KOTLIN_12X_MPP_DEPRECATION_WARNING = "\n" + """ private const val KOTLIN_12X_MPP_DEPRECATION_SUPPRESS_FLAG = "kotlin.internal.mpp12x.deprecation.suppress" -private fun warnAboutKotlin12xMppDeprecation(project: Project) { +internal fun warnAboutKotlin12xMppDeprecation(project: Project) { if (project.findProperty(KOTLIN_12X_MPP_DEPRECATION_SUPPRESS_FLAG) != "true") { SingleWarningPerBuild.show(project, KOTLIN_12X_MPP_DEPRECATION_WARNING) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index 80d5859d07c..24613a54a16 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -9,7 +9,6 @@ import com.android.build.gradle.* import com.android.build.gradle.BasePlugin import com.android.build.gradle.api.* import org.gradle.api.* -import org.gradle.api.artifacts.repositories.ArtifactRepository import org.gradle.api.attributes.Category import org.gradle.api.attributes.Usage import org.gradle.api.file.ConfigurableFileTree @@ -26,13 +25,13 @@ import org.gradle.api.tasks.* import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.jvm.tasks.Jar import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry -import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin import org.jetbrains.kotlin.gradle.internal.checkAndroidAnnotationProcessorDependencyUsage import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.model.builder.KotlinModelBuilder +import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfigurator import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData @@ -45,14 +44,10 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry import org.jetbrains.kotlin.gradle.tooling.includeKotlinToolingMetadataInApk import org.jetbrains.kotlin.gradle.utils.* -import org.jetbrains.kotlin.utils.addToStdlib.cast import java.io.File import java.net.URL import java.util.concurrent.Callable import java.util.jar.Manifest -import kotlin.reflect.full.functions -import kotlin.reflect.full.staticProperties -import kotlin.reflect.jvm.isAccessible const val PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinCompilerPluginClasspath" const val NATIVE_COMPILER_PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinNativeCompilerPluginClasspath" @@ -438,64 +433,10 @@ internal abstract class AbstractKotlinPlugin( } } - if (GradleVersion.version(project.gradle.gradleVersion) < GradleVersion.version("7.0")) { - project.pluginManager.withPlugin("maven") { - project.tasks.withType(Upload::class.java).configureEach { uploadTask -> - uploadTask - .repositories - .withType( - Class.forName("org.gradle.api.artifacts.maven.MavenResolver") - .cast>() - ) - .configureEach { mavenResolver -> - val pomRewriter = PomDependenciesRewriter(project, target.kotlinComponents.single()) - val mavenPom = mavenResolver::class - .functions - .first { it.name == "getPom" } - .also { it.isAccessible = true } - .call(mavenResolver)!! - mavenPom::class - .functions - .first { func -> - // On older Gradle versions there were two 'withXml' method - one with 'Closure' and one with 'Action' - func.name == "withXml" && - func.parameters.any { - it.type.toString() == "org.gradle.api.Action!" - } - } - .call(mavenPom, Action { xml -> - if (shouldRewritePoms.get()) { - pomRewriter.rewritePomMppDependenciesToActualTargetModules(xml) - } - }) - } - } - - // Setup conf2ScopeMappings so that the API dependencies are written - // with compile scope in the POMs in case of 'java' plugin - val mavenPluginConvention = project - .convention - .getPlugin(Class.forName("org.gradle.api.plugins.MavenPluginConvention")) - - val conf2ScopeMappingContainer = mavenPluginConvention::class - .functions - .first { it.name == "getConf2ScopeMappings" } - .call(mavenPluginConvention)!! - - conf2ScopeMappingContainer::class - .functions - .first { it.name == "addMapping" } - .call( - conf2ScopeMappingContainer, - 0, - project.configurations.getByName("api"), - conf2ScopeMappingContainer::class - .staticProperties - .first { it.name == "COMPILE" } - .get() - ) - } - } + VariantImplementationFactories + .get(project.gradle)[MavenPluginConfigurator.MavenPluginConfiguratorVariantFactory::class] + .getInstance() + .applyConfiguration(project, target, shouldRewritePoms) } companion object { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index a5455708d47..b6bd9c4d8e3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.internal.KOTLIN_COMPILER_EMBEDDABLE import org.jetbrains.kotlin.gradle.internal.KOTLIN_MODULE_GROUP import org.jetbrains.kotlin.gradle.logging.kotlinDebug +import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfigurator import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20GradlePlugin @@ -50,7 +51,6 @@ import org.jetbrains.kotlin.gradle.utils.loadPropertyFromResources import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheck import org.jetbrains.kotlin.statistics.metrics.StringMetrics import org.jetbrains.kotlin.tooling.core.KotlinToolingVersion -import javax.inject.Inject import kotlin.reflect.KClass abstract class KotlinBasePluginWrapper : Plugin { @@ -90,6 +90,8 @@ abstract class KotlinBasePluginWrapper : Plugin { } project.registerCommonizerClasspathConfigurationIfNecessary() + project.registerDefaultVariantImplementations() + KotlinGradleBuildServices.registerIfAbsent(project, kotlinPluginVersion).get() KotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion) @@ -132,6 +134,14 @@ abstract class KotlinBasePluginWrapper : Plugin { project.registerBuildKotlinToolingMetadataTask() } + private fun Project.registerDefaultVariantImplementations() { + val factories = VariantImplementationFactories.get(project.gradle) + factories.putIfAbsent( + MavenPluginConfigurator.MavenPluginConfiguratorVariantFactory::class, + MavenPluginConfigurator.DefaultMavenPluginConfiguratorVariantFactory() + ) + } + private fun addKotlinCompilerConfiguration(project: Project) { project .configurations @@ -169,7 +179,7 @@ abstract class KotlinBasePluginWrapper : Plugin { ): Plugin } -open class KotlinPluginWrapper @Inject constructor( +abstract class AbstractKotlinPluginWrapper( protected val registry: ToolingModelBuilderRegistry ) : KotlinBasePluginWrapper() { override fun getPlugin(project: Project): Plugin = @@ -179,7 +189,7 @@ open class KotlinPluginWrapper @Inject constructor( get() = KotlinJvmProjectExtension::class } -open class KotlinCommonPluginWrapper @Inject constructor( +abstract class AbstractKotlinCommonPluginWrapper( protected val registry: ToolingModelBuilderRegistry ) : KotlinBasePluginWrapper() { override fun getPlugin(project: Project): Plugin = @@ -189,7 +199,7 @@ open class KotlinCommonPluginWrapper @Inject constructor( get() = KotlinCommonProjectExtension::class } -open class KotlinAndroidPluginWrapper @Inject constructor( +abstract class AbstractKotlinAndroidPluginWrapper( protected val registry: ToolingModelBuilderRegistry ) : KotlinBasePluginWrapper() { override fun getPlugin(project: Project): Plugin = @@ -203,7 +213,7 @@ open class KotlinAndroidPluginWrapper @Inject constructor( message = "Should be removed with JS platform plugin", level = DeprecationLevel.ERROR ) -open class Kotlin2JsPluginWrapper @Inject constructor( +abstract class AbstractKotlin2JsPluginWrapper( protected val registry: ToolingModelBuilderRegistry ) : KotlinBasePluginWrapper() { @@ -215,7 +225,7 @@ open class Kotlin2JsPluginWrapper @Inject constructor( get() = Kotlin2JsProjectExtension::class } -open class KotlinJsPluginWrapper : KotlinBasePluginWrapper() { +abstract class AbstractKotlinJsPluginWrapper : KotlinBasePluginWrapper() { override fun getPlugin(project: Project): Plugin = KotlinJsPlugin(project.getKotlinPluginVersion()) @@ -246,7 +256,7 @@ open class KotlinJsPluginWrapper : KotlinBasePluginWrapper() { override fun createTestRegistry(project: Project) = KotlinTestsRegistry(project, "test") } -open class KotlinMultiplatformPluginWrapper : KotlinBasePluginWrapper() { +abstract class AbstractKotlinMultiplatformPluginWrapper : KotlinBasePluginWrapper() { override fun getPlugin(project: Project): Plugin = KotlinMultiplatformPlugin() @@ -260,7 +270,7 @@ open class KotlinMultiplatformPluginWrapper : KotlinBasePluginWrapper() { } } -open class KotlinPm20PluginWrapper @Inject constructor( +abstract class AbstractKotlinPm20PluginWrapper( private val objectFactory: ObjectFactory ) : KotlinBasePluginWrapper() { override fun getPlugin(project: Project): Plugin = diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/VariantImplementationFactories.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/VariantImplementationFactories.kt new file mode 100644 index 00000000000..e97d652b3e4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/VariantImplementationFactories.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin + +import org.gradle.api.invocation.Gradle +import org.gradle.api.provider.Provider +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters +import java.util.concurrent.ConcurrentHashMap +import kotlin.reflect.KClass + +/** + * Provides a way for Gradle plugin variants to register specific implementation factories, + * that could be used inside common code. + */ +abstract class VariantImplementationFactories : BuildService { + private val factories: MutableMap, VariantImplementationFactory> = ConcurrentHashMap() + operator fun set( + type: KClass, + factory: T + ) { + factories[type] = factory + } + + fun putIfAbsent( + type: KClass, + factory: T + ) { + factories.putIfAbsent(type, factory) + } + + @Suppress("UNCHECKED_CAST") + operator fun get(type: KClass): T { + return factories[type] as? T ?: throw IllegalArgumentException("${type.simpleName} type is not known for plugin variants") + } + + /** + * Marker interface for actual implementation factories. + */ + interface VariantImplementationFactory + + companion object { + fun getProvider( + gradle: Gradle + ): Provider { + // Use class loader hashcode in case there are multiple class loaders in the same build + return gradle.sharedServices + .registerIfAbsent( + "variant_impl_factories_${VariantImplementationFactories::class.java.classLoader.hashCode()}", + VariantImplementationFactories::class.java + ) {} + } + + fun get(gradle: Gradle): VariantImplementationFactories = getProvider(gradle).get() + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/MavenPluginConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/MavenPluginConfigurator.kt new file mode 100644 index 00000000000..82452026507 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/MavenPluginConfigurator.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin.internal + +import org.gradle.api.Project +import org.gradle.api.provider.Provider +import org.jetbrains.kotlin.gradle.plugin.VariantImplementationFactories +import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinTarget + +/** + * Additional configuration for 'maven' Gradle plugin. + * Documentation: https://docs.gradle.org/6.0/userguide/maven_plugin.html + */ +interface MavenPluginConfigurator { + fun applyConfiguration( + project: Project, + target: AbstractKotlinTarget, + shouldRewritePoms: Provider + ) + + interface MavenPluginConfiguratorVariantFactory : VariantImplementationFactories.VariantImplementationFactory { + fun getInstance(): MavenPluginConfigurator + } + + class DefaultMavenPluginConfiguratorVariantFactory : MavenPluginConfiguratorVariantFactory { + override fun getInstance(): MavenPluginConfigurator = object : MavenPluginConfigurator { + override fun applyConfiguration( + project: Project, + target: AbstractKotlinTarget, + shouldRewritePoms: Provider + ) = Unit + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt index 94564efaebd..b0b8cd7e18c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt @@ -8,12 +8,8 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project import org.gradle.api.attributes.* import org.gradle.api.attributes.Usage.* -import org.gradle.kotlin.dsl.findByType -import org.gradle.kotlin.dsl.hasPlugin -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.kotlinExtension -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformCommonPlugin import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.* import org.jetbrains.kotlin.gradle.plugin.KotlinTarget diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index f144e80cc54..a65e2a667b7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -275,7 +275,11 @@ abstract class AbstractKotlinCompile @Inject constr task.sourceSetName.set(project.provider { compilation.compilationPurpose }) task.multiPlatformEnabled.value( project.provider { - project.plugins.any { it is KotlinPlatformPluginBase || it is KotlinMultiplatformPluginWrapper || it is KotlinPm20PluginWrapper } + project.plugins.any { + it is KotlinPlatformPluginBase || + it is AbstractKotlinMultiplatformPluginWrapper || + it is AbstractKotlinPm20PluginWrapper + } } ).disallowChanges() task.taskBuildCacheableOutputDirectory.value(getKotlinBuildDir(task).map { it.dir("cacheable") }).disallowChanges() diff --git a/libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt b/libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt new file mode 100644 index 00000000000..163df392297 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin + +import com.android.build.gradle.BaseExtension +import org.gradle.api.Named +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project +import org.gradle.api.model.ObjectFactory +import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry +import javax.inject.Inject + +open class KotlinPluginWrapper @Inject constructor( + registry: ToolingModelBuilderRegistry +) : AbstractKotlinPluginWrapper(registry) + +open class KotlinCommonPluginWrapper @Inject constructor( + registry: ToolingModelBuilderRegistry +) : AbstractKotlinCommonPluginWrapper(registry) + +open class KotlinAndroidPluginWrapper @Inject constructor( + registry: ToolingModelBuilderRegistry +) : AbstractKotlinAndroidPluginWrapper(registry) + +@Suppress("DEPRECATION_ERROR") +open class Kotlin2JsPluginWrapper @Inject constructor( + registry: ToolingModelBuilderRegistry +) : AbstractKotlin2JsPluginWrapper(registry) + +open class KotlinMultiplatformPluginWrapper : AbstractKotlinMultiplatformPluginWrapper() + +open class KotlinJsPluginWrapper : AbstractKotlinJsPluginWrapper() + +open class KotlinPm20PluginWrapper @Inject constructor( + objectFactory: ObjectFactory +) : AbstractKotlinPm20PluginWrapper(objectFactory) + +open class KotlinPlatformJvmPlugin : KotlinPlatformImplementationPluginBase("jvm") { + override fun apply(project: Project) { + project.applyPlugin() + super.apply(project) + } +} + +open class KotlinPlatformJsPlugin : KotlinPlatformImplementationPluginBase("js") { + override fun apply(project: Project) { + @Suppress("DEPRECATION_ERROR") + project.applyPlugin() + super.apply(project) + } +} + +open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase("android") { + override fun apply(project: Project) { + project.applyPlugin() + super.apply(project) + } + + override fun namedSourceSetsContainer(project: Project): NamedDomainObjectContainer<*> = + (project.extensions.getByName("android") as BaseExtension).sourceSets + + override fun addCommonSourceSetToPlatformSourceSet(commonSourceSet: Named, platformProject: Project) { + val androidExtension = platformProject.extensions.getByName("android") as BaseExtension + val androidSourceSet = androidExtension.sourceSets.findByName(commonSourceSet.name) ?: return + val kotlinSourceSet = androidSourceSet.getConvention(KOTLIN_DSL_NAME) as? KotlinSourceSet + ?: return + kotlinSourceSet.kotlin.source(getKotlinSourceDirectorySetSafe(commonSourceSet)!!) + } +} + +open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") { + override fun apply(project: Project) { + warnAboutKotlin12xMppDeprecation(project) + project.applyPlugin() + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt new file mode 100644 index 00000000000..6783bc2ffc8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt @@ -0,0 +1,122 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin + +import com.android.build.gradle.BaseExtension +import org.gradle.api.Named +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project +import org.gradle.api.model.ObjectFactory +import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry +import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfigurator +import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfiguratorG6 +import javax.inject.Inject + +open class KotlinPluginWrapper @Inject constructor( + registry: ToolingModelBuilderRegistry +) : AbstractKotlinPluginWrapper(registry) { + override fun apply(project: Project) { + project.registerVariantImplementations() + super.apply(project) + } +} + +open class KotlinCommonPluginWrapper @Inject constructor( + registry: ToolingModelBuilderRegistry +) : AbstractKotlinCommonPluginWrapper(registry) { + override fun apply(project: Project) { + project.registerVariantImplementations() + super.apply(project) + } +} + +open class KotlinAndroidPluginWrapper @Inject constructor( + registry: ToolingModelBuilderRegistry +) : AbstractKotlinAndroidPluginWrapper(registry) { + override fun apply(project: Project) { + project.registerVariantImplementations() + super.apply(project) + } +} + +@Suppress("DEPRECATION_ERROR") +open class Kotlin2JsPluginWrapper @Inject constructor( + registry: ToolingModelBuilderRegistry +) : AbstractKotlin2JsPluginWrapper(registry) { + override fun apply(project: Project) { + project.registerVariantImplementations() + super.apply(project) + } +} + +open class KotlinMultiplatformPluginWrapper : AbstractKotlinMultiplatformPluginWrapper() { + override fun apply(project: Project) { + project.registerVariantImplementations() + super.apply(project) + } +} + +open class KotlinJsPluginWrapper : AbstractKotlinJsPluginWrapper() { + override fun apply(project: Project) { + project.registerVariantImplementations() + super.apply(project) + } +} + +open class KotlinPm20PluginWrapper @Inject constructor( + objectFactory: ObjectFactory +) : AbstractKotlinPm20PluginWrapper(objectFactory) { + override fun apply(project: Project) { + project.registerVariantImplementations() + super.apply(project) + } +} + +open class KotlinPlatformJvmPlugin : KotlinPlatformImplementationPluginBase("jvm") { + override fun apply(project: Project) { + project.applyPlugin() + super.apply(project) + } +} + +open class KotlinPlatformJsPlugin : KotlinPlatformImplementationPluginBase("js") { + override fun apply(project: Project) { + @Suppress("DEPRECATION_ERROR") + project.applyPlugin() + super.apply(project) + } +} + +open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase("android") { + override fun apply(project: Project) { + project.applyPlugin() + super.apply(project) + } + + override fun namedSourceSetsContainer(project: Project): NamedDomainObjectContainer<*> = + (project.extensions.getByName("android") as BaseExtension).sourceSets + + override fun addCommonSourceSetToPlatformSourceSet(commonSourceSet: Named, platformProject: Project) { + val androidExtension = platformProject.extensions.getByName("android") as BaseExtension + val androidSourceSet = androidExtension.sourceSets.findByName(commonSourceSet.name) ?: return + val kotlinSourceSet = androidSourceSet.getConvention(KOTLIN_DSL_NAME) as? KotlinSourceSet + ?: return + kotlinSourceSet.kotlin.source(getKotlinSourceDirectorySetSafe(commonSourceSet)!!) + } +} + +open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") { + override fun apply(project: Project) { + warnAboutKotlin12xMppDeprecation(project) + project.applyPlugin() + } +} + +private fun Project.registerVariantImplementations() { + val factories = VariantImplementationFactories.get(gradle) + factories[MavenPluginConfigurator.MavenPluginConfiguratorVariantFactory::class] = + MavenPluginConfiguratorG6.Gradle6MavenPluginConfiguratorVariantFactory() +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/MavenPluginConfiguratorG6.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/MavenPluginConfiguratorG6.kt new file mode 100644 index 00000000000..624fd4f256d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/MavenPluginConfiguratorG6.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin.internal + +import org.gradle.api.Project +import org.gradle.api.artifacts.maven.Conf2ScopeMappingContainer +import org.gradle.api.artifacts.maven.MavenPom +import org.gradle.api.artifacts.maven.MavenResolver +import org.gradle.api.plugins.MavenPluginConvention +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Upload +import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.PomDependenciesRewriter + +@Suppress("DEPRECATION") +class MavenPluginConfiguratorG6 : MavenPluginConfigurator { + override fun applyConfiguration( + project: Project, + target: AbstractKotlinTarget, + shouldRewritePoms: Provider + ) { + project.pluginManager.withPlugin("maven") { + project.tasks.withType(Upload::class.java).all { uploadTask -> + uploadTask.repositories.withType(MavenResolver::class.java).all { mavenResolver -> + val pomRewriter = PomDependenciesRewriter(project, target.kotlinComponents.single()) + rewritePom(mavenResolver.pom, pomRewriter, shouldRewritePoms) + } + } + + // Setup conf2ScopeMappings so that the API dependencies are written with the compile scope in the POMs in case of 'java' plugin + project.convention.getPlugin(MavenPluginConvention::class.java) + .conf2ScopeMappings.addMapping(0, project.configurations.getByName("api"), Conf2ScopeMappingContainer.COMPILE) + } + } + + private fun rewritePom( + pom: MavenPom, + rewriter: PomDependenciesRewriter, + shouldRewritePom: Provider + ) { + pom.withXml { xml -> + if (shouldRewritePom.get()) + rewriter.rewritePomMppDependenciesToActualTargetModules(xml) + } + } + + class Gradle6MavenPluginConfiguratorVariantFactory : MavenPluginConfigurator.MavenPluginConfiguratorVariantFactory { + override fun getInstance(): MavenPluginConfigurator = MavenPluginConfiguratorG6() + } +} \ No newline at end of file