Drop convention usage on accessing Java SourceSet

This is only valid for Gradle 7.1+, so new plugin variant was added -
"gradle71". For Gradle <=7.0 old convention approach is still used.

^KT-47047 In Progress
This commit is contained in:
Yahor Berdnikau
2022-05-31 22:30:41 +02:00
committed by Space
parent f192c2a541
commit c495c07b1a
20 changed files with 421 additions and 84 deletions
+1 -1
View File
@@ -44,7 +44,7 @@ enum class GradlePluginVariant(
) { ) {
GRADLE_MIN("main", "6.7", "6.9"), GRADLE_MIN("main", "6.7", "6.9"),
GRADLE_70("gradle70", "7.0", "7.0"), GRADLE_70("gradle70", "7.0", "7.0"),
//GRADLE_71("gradle71", "7.1", "7.1"), GRADLE_71("gradle71", "7.1", "7.1"),
} }
/** /**
@@ -55,10 +55,17 @@ tasks.named("jar") {
} }
if (!kotlinBuildProperties.isInJpsBuildIdeaSync) { if (!kotlinBuildProperties.isInJpsBuildIdeaSync) {
// Used for Gradle 7.0+ versions // Used for Gradle 7.0 version
val gradle70SourceSet = createGradlePluginVariant( val gradle70SourceSet = createGradlePluginVariant(
GradlePluginVariant.GRADLE_70, GradlePluginVariant.GRADLE_70,
commonSourceSet = commonSourceSet commonSourceSet = commonSourceSet
) )
publishShadowedJar(gradle70SourceSet, commonSourceSet) publishShadowedJar(gradle70SourceSet, commonSourceSet)
// Used for Gradle 7.1+ versions
val gradle71SourceSet = createGradlePluginVariant(
GradlePluginVariant.GRADLE_71,
commonSourceSet = commonSourceSet
)
publishShadowedJar(gradle71SourceSet, commonSourceSet)
} }
@@ -19,13 +19,20 @@ extensions.extraProperties["kotlin.stdlib.default.dependency"] = "false"
val commonSourceSet = createGradleCommonSourceSet() val commonSourceSet = createGradleCommonSourceSet()
reconfigureMainSourcesSetForGradlePlugin(commonSourceSet) reconfigureMainSourcesSetForGradlePlugin(commonSourceSet)
// Used for Gradle 7.0+ versions // Used for Gradle 7.0 version
createGradlePluginVariant( createGradlePluginVariant(
GradlePluginVariant.GRADLE_70, GradlePluginVariant.GRADLE_70,
commonSourceSet = commonSourceSet, commonSourceSet = commonSourceSet,
isGradlePlugin = false isGradlePlugin = false
) )
// Used for Gradle 7.1+ versions
createGradlePluginVariant(
GradlePluginVariant.GRADLE_71,
commonSourceSet = commonSourceSet,
isGradlePlugin = false
)
publishing { publishing {
publications { publications {
register<MavenPublication>(DEFAULT_MAIN_PUBLICATION_NAME) { register<MavenPublication>(DEFAULT_MAIN_PUBLICATION_NAME) {
@@ -442,7 +442,11 @@ class KotlinGradleIT : KGPBaseTest() {
buildGradle.appendText( buildGradle.appendText(
""" """
archivesBaseName = 'a/really\\tricky\n\rmodule\tname' archivesBaseName = 'a/really\\trick\n\rmodule\tname'
tasks.withType(Jar.class).configureEach {
archiveBaseName.set('typeAlias')
}
""".trimIndent() """.trimIndent()
) )
@@ -211,15 +211,18 @@ class SimpleKotlinGradleIT : KGPBaseTest() {
} }
@DisplayName("Proper Gradle plugin variant is used") @DisplayName("Proper Gradle plugin variant is used")
@GradleTestVersions(additionalVersions = [TestVersions.Gradle.G_7_0]) @GradleTestVersions(
additionalVersions = [TestVersions.Gradle.G_7_0],
maxVersion = TestVersions.Gradle.G_7_1
)
@GradleTest @GradleTest
internal fun pluginVariantIsUsed(gradleVersion: GradleVersion) { internal fun pluginVariantIsUsed(gradleVersion: GradleVersion) {
project("kotlinProject", gradleVersion) { project("kotlinProject", gradleVersion) {
build("tasks") { build("tasks") {
val expectedVariant = if (gradleVersion < GradleVersion.version("7.0")) { val expectedVariant = when (gradleVersion) {
"main" GradleVersion.version(TestVersions.Gradle.G_7_1) -> "gradle71"
} else { GradleVersion.version(TestVersions.Gradle.G_7_0) -> "gradle70"
"gradle70" else -> "main"
} }
assertOutputContains("Using Kotlin Gradle Plugin $expectedVariant variant") assertOutputContains("Using Kotlin Gradle Plugin $expectedVariant variant")
@@ -9,7 +9,6 @@ import org.gradle.api.GradleException
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.invocation.Gradle import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.jvm.tasks.Jar import org.gradle.jvm.tasks.Jar
import org.gradle.workers.WorkQueue import org.gradle.workers.WorkQueue
@@ -27,9 +26,11 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.logging.kotlinInfo import org.jetbrains.kotlin.gradle.logging.kotlinInfo
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactory
import org.jetbrains.kotlin.gradle.tasks.* import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.gradle.utils.IsolatedKotlinClasspathClassCastException import org.jetbrains.kotlin.gradle.utils.IsolatedKotlinClasspathClassCastException
import org.jetbrains.kotlin.gradle.utils.archivePathCompatible import org.jetbrains.kotlin.gradle.utils.archivePathCompatible
@@ -310,7 +311,7 @@ internal open class GradleCompilerRunner(
} }
} }
} else if (task is InspectClassesForMultiModuleIC) { } else if (task is InspectClassesForMultiModuleIC) {
jarToClassListFile[File(task.archivePath.get())] = task.classesListFile jarToClassListFile[File(task.archivePath.get())] = task.classesListFile.get().asFile
} }
} }
@@ -360,10 +361,15 @@ internal open class GradleCompilerRunner(
} }
} }
private fun jarForSourceSet(project: Project, sourceSetName: String): File? { private fun jarForSourceSet(
val javaConvention = project.convention.findPlugin(JavaPluginConvention::class.java) project: Project,
?: return null sourceSetName: String
val sourceSet = javaConvention.sourceSets.findByName(sourceSetName) ?: return null ): File? {
val sourceSets = project.gradle.variantImplementationFactory<JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory>()
.getInstance(project)
.sourceSetsIfAvailable ?: return null
val sourceSet = sourceSets.findByName(sourceSetName) ?: return null
val jarTask = project.tasks.findByName(sourceSet.jarTaskName) as? Jar val jarTask = project.tasks.findByName(sourceSet.jarTaskName) as? Jar
return jarTask?.archiveFile?.get()?.asFile return jarTask?.archiveFile?.get()?.asFile
} }
@@ -16,15 +16,14 @@
package org.jetbrains.kotlin.gradle.plugin package org.jetbrains.kotlin.gradle.plugin
import com.android.build.gradle.BaseExtension
import org.gradle.api.* import org.gradle.api.*
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ProjectDependency import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.file.SourceDirectorySet import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.SourceSet
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.logging.kotlinWarn import org.jetbrains.kotlin.gradle.logging.kotlinWarn
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
import org.jetbrains.kotlin.gradle.utils.androidPluginIds import org.jetbrains.kotlin.gradle.utils.androidPluginIds
@@ -118,8 +117,9 @@ open class KotlinPlatformImplementationPluginBase(platformName: String) : Kotlin
addCommonSourceSetToPlatformSourceSet(commonSourceSet, platformProject) addCommonSourceSetToPlatformSourceSet(commonSourceSet, platformProject)
// Workaround for older versions of Kotlin/Native overriding the old signature // Workaround for older versions of Kotlin/Native overriding the old signature
commonProject.convention.findPlugin(JavaPluginConvention::class.java) commonProject.gradle.variantImplementationFactory<JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory>()
?.sourceSets .getInstance(commonProject)
.sourceSetsIfAvailable
?.findByName(commonSourceSet.name) ?.findByName(commonSourceSet.name)
?.let { javaSourceSet -> ?.let { javaSourceSet ->
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
@@ -20,14 +20,12 @@ import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.logging.Logging import org.gradle.api.logging.Logging
import org.gradle.api.plugins.InvalidPluginException import org.gradle.api.plugins.InvalidPluginException
import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPom import org.gradle.api.publish.maven.MavenPom
import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.Upload
import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.jvm.tasks.Jar import org.gradle.jvm.tasks.Jar
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
@@ -37,6 +35,7 @@ import org.jetbrains.kotlin.gradle.internal.checkAndroidAnnotationProcessorDepen
import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.model.builder.KotlinModelBuilder import org.jetbrains.kotlin.gradle.model.builder.KotlinModelBuilder
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor
import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfigurator import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfigurator
import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
@@ -103,7 +102,10 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
return (compilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet return (compilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet
?: kotlinCompilation.owner.let { ?: kotlinCompilation.owner.let {
if (it is KotlinJvmTarget && it.withJavaEnabled && compilation is KotlinJvmCompilation) if (it is KotlinJvmTarget && it.withJavaEnabled && compilation is KotlinJvmCompilation)
project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.maybeCreate(compilation.name) project.gradle.variantImplementationFactory<JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory>()
.getInstance(project)
.sourceSets
.maybeCreate(compilation.name)
else null else null
} }
} }
@@ -447,14 +449,35 @@ internal abstract class AbstractKotlinPlugin(
) )
return return
} }
val inspectTask = val inspectTask = project.registerTask<InspectClassesForMultiModuleIC>("inspectClassesForKotlinIC") { inspectTask ->
project.registerTask<InspectClassesForMultiModuleIC>("inspectClassesForKotlinIC") { inspectTask.archivePath.set(jarTask.map { it.archivePathCompatible.canonicalPath })
it.sourceSetName = SourceSet.MAIN_SOURCE_SET_NAME inspectTask.archivePath.disallowChanges()
it.archivePath.set(project.provider { jarTask.get().archivePathCompatible.canonicalPath })
it.archiveName.set(project.provider { jarTask.get().archiveFileName.get() }) inspectTask.sourceSetName.set(SourceSet.MAIN_SOURCE_SET_NAME)
it.dependsOn(classesTask) inspectTask.sourceSetName.disallowChanges()
}
jarTask.dependsOn(inspectTask) inspectTask.classesListFile.set(
project.layout.file(
(project.kotlinExtension as KotlinSingleJavaTargetExtension)
.target
.defaultArtifactClassesListFile
)
)
inspectTask.classesListFile.disallowChanges()
val sourceSetClassesDir = project.gradle
.variantImplementationFactory<JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory>()
.getInstance(project)
.sourceSetsIfAvailable
?.findByName(SourceSet.MAIN_SOURCE_SET_NAME)
?.output
?.classesDirs
?: project.objects.fileCollection()
inspectTask.sourceSetOutputClassesDir.from(sourceSetClassesDir).disallowChanges()
inspectTask.dependsOn(classesTask)
}
classesTask.configure { it.finalizedBy(inspectTask) }
} }
internal fun setUpJavaSourceSets( internal fun setUpJavaSourceSets(
@@ -462,7 +485,11 @@ internal abstract class AbstractKotlinPlugin(
duplicateJavaSourceSetsAsKotlinSourceSets: Boolean = true duplicateJavaSourceSetsAsKotlinSourceSets: Boolean = true
) { ) {
val project = kotlinTarget.project val project = kotlinTarget.project
val javaSourceSets = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets val javaSourceSets = project
.gradle
.variantImplementationFactory<JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory>()
.getInstance(project)
.sourceSets
val kotlinSourceSetDslName = when (kotlinTarget.platformType) { val kotlinSourceSetDslName = when (kotlinTarget.platformType) {
KotlinPlatformType.js -> KOTLIN_JS_DSL_NAME KotlinPlatformType.js -> KOTLIN_JS_DSL_NAME
@@ -29,6 +29,8 @@ import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.internal.KOTLIN_COMPILER_EMBEDDABLE import org.jetbrains.kotlin.gradle.internal.KOTLIN_COMPILER_EMBEDDABLE
import org.jetbrains.kotlin.gradle.internal.KOTLIN_MODULE_GROUP import org.jetbrains.kotlin.gradle.internal.KOTLIN_MODULE_GROUP
import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.plugin.internal.DefaultJavaSourceSetsAccessorVariantFactory
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor
import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfigurator import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfigurator
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
@@ -189,6 +191,11 @@ abstract class KotlinBasePluginWrapper : DefaultKotlinBasePlugin() {
MavenPluginConfigurator.MavenPluginConfiguratorVariantFactory::class, MavenPluginConfigurator.MavenPluginConfiguratorVariantFactory::class,
MavenPluginConfigurator.DefaultMavenPluginConfiguratorVariantFactory() MavenPluginConfigurator.DefaultMavenPluginConfiguratorVariantFactory()
) )
factories.putIfAbsent(
JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory::class,
DefaultJavaSourceSetsAccessorVariantFactory()
)
} }
internal open fun createTestRegistry(project: Project) = KotlinTestsRegistry(project) internal open fun createTestRegistry(project: Project) = KotlinTestsRegistry(project)
@@ -0,0 +1,38 @@
/*
* 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.plugins.ExtensionContainer
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.SourceSetContainer
import org.jetbrains.kotlin.gradle.plugin.VariantImplementationFactories
import org.jetbrains.kotlin.gradle.utils.findByType
import org.jetbrains.kotlin.gradle.utils.getByType
interface JavaSourceSetsAccessor {
val sourceSets: SourceSetContainer
val sourceSetsIfAvailable: SourceSetContainer?
interface JavaSourceSetsAccessorVariantFactory : VariantImplementationFactories.VariantImplementationFactory {
fun getInstance(project: Project): JavaSourceSetsAccessor
}
}
internal class DefaultJavaSourceSetsAccessorVariantFactory : JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory {
override fun getInstance(project: Project): JavaSourceSetsAccessor = DefaultJavaSourceSetsAccessor(project.extensions)
}
internal class DefaultJavaSourceSetsAccessor(
private val projectExtensions: ExtensionContainer
) : JavaSourceSetsAccessor {
override val sourceSets: SourceSetContainer
get() = projectExtensions.getByType<JavaPluginExtension>().sourceSets
override val sourceSetsIfAvailable: SourceSetContainer?
get() = projectExtensions.findByType<JavaPluginExtension>()?.sourceSets
}
@@ -17,13 +17,13 @@ import org.gradle.api.artifacts.transform.TransformOutputs
import org.gradle.api.artifacts.transform.TransformParameters import org.gradle.api.artifacts.transform.TransformParameters
import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.Attribute
import org.gradle.api.file.FileSystemLocation import org.gradle.api.file.FileSystemLocation
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask
import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeCompilation
import org.jetbrains.kotlin.gradle.scripting.ScriptingExtension import org.jetbrains.kotlin.gradle.scripting.ScriptingExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
@@ -53,8 +53,12 @@ class ScriptingGradleSubplugin : Plugin<Project> {
project.plugins.apply(ScriptingKotlinGradleSubplugin::class.java) project.plugins.apply(ScriptingKotlinGradleSubplugin::class.java)
project.afterEvaluate { project.afterEvaluate {
val javaPluginConvention = project.convention.findPlugin(JavaPluginConvention::class.java) val javaSourceSets = project
if (javaPluginConvention?.sourceSets?.isEmpty() == false) { .gradle
.variantImplementationFactory<JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory>()
.getInstance(project)
.sourceSetsIfAvailable
if (javaSourceSets?.isEmpty() == false) {
val configureAction: (KotlinCompile) -> (Unit) = ca@{ task -> val configureAction: (KotlinCompile) -> (Unit) = ca@{ task ->
@@ -6,11 +6,12 @@
@file:Suppress("PackageDirectoryMismatch") // Old package for compatibility @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility
package org.jetbrains.kotlin.gradle.plugin.mpp package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor
import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactory
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
open class KotlinJvmCompilation( open class KotlinJvmCompilation(
@@ -31,7 +32,9 @@ open class KotlinJvmCompilation(
val compileJavaTaskProvider: TaskProvider<out JavaCompile>? val compileJavaTaskProvider: TaskProvider<out JavaCompile>?
get() = if (target.withJavaEnabled) { get() = if (target.withJavaEnabled) {
val project = target.project val project = target.project
val javaSourceSets = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets val javaSourceSets = project.gradle.variantImplementationFactory<JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory>()
.getInstance(project)
.sourceSets
val javaSourceSet = javaSourceSets.getByName(compilationPurpose) val javaSourceSet = javaSourceSets.getByName(compilationPurpose)
project.tasks.withType(JavaCompile::class.java).named(javaSourceSet.compileJavaTaskName) project.tasks.withType(JavaCompile::class.java).named(javaSourceSet.compileJavaTaskName)
} else null } else null
@@ -11,8 +11,8 @@ import org.gradle.api.Project
import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.testing.Test import org.gradle.api.tasks.testing.Test
import org.gradle.jvm.tasks.Jar import org.gradle.jvm.tasks.Jar
@@ -20,6 +20,7 @@ import org.gradle.language.jvm.tasks.ProcessResources
import org.gradle.util.GradleVersion import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
import org.jetbrains.kotlin.gradle.tasks.withType import org.jetbrains.kotlin.gradle.tasks.withType
@@ -55,7 +56,9 @@ open class KotlinJvmTarget @Inject constructor(
withJavaEnabled = true withJavaEnabled = true
project.plugins.apply(JavaPlugin::class.java) project.plugins.apply(JavaPlugin::class.java)
val javaPluginConvention = project.convention.getPlugin(JavaPluginConvention::class.java) val javaSourceSets = project.gradle.variantImplementationFactory<JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory>()
.getInstance(project)
.sourceSets
AbstractKotlinPlugin.setUpJavaSourceSets(this, duplicateJavaSourceSetsAsKotlinSourceSets = false) AbstractKotlinPlugin.setUpJavaSourceSets(this, duplicateJavaSourceSetsAsKotlinSourceSets = false)
// Below, some effort is made to ensure that a user or 3rd-party plugin that inspects or interacts // Below, some effort is made to ensure that a user or 3rd-party plugin that inspects or interacts
@@ -64,7 +67,7 @@ open class KotlinJvmTarget @Inject constructor(
// * the relevant dependencies for Java and Kotlin are in sync, // * the relevant dependencies for Java and Kotlin are in sync,
// * the Java outputs contain the outputs produced by Kotlin as well // * the Java outputs contain the outputs produced by Kotlin as well
javaPluginConvention.sourceSets.all { javaSourceSet -> javaSourceSets.all { javaSourceSet ->
val compilation = compilations.getByName(javaSourceSet.name) val compilation = compilations.getByName(javaSourceSet.name)
val compileJavaTask = project.tasks.withType<AbstractCompile>().named(javaSourceSet.compileJavaTaskName) val compileJavaTask = project.tasks.withType<AbstractCompile>().named(javaSourceSet.compileJavaTaskName)
@@ -90,7 +93,7 @@ open class KotlinJvmTarget @Inject constructor(
project.configurations.findByName(outputConfigurationName)?.isCanBeConsumed = false project.configurations.findByName(outputConfigurationName)?.isCanBeConsumed = false
} }
disableJavaPluginTasks(javaPluginConvention) disableJavaPluginTasks(javaSourceSets)
} }
private fun setupJavaSourceSetSourcesAndResources( private fun setupJavaSourceSetSourcesAndResources(
@@ -122,12 +125,12 @@ open class KotlinJvmTarget @Inject constructor(
} }
} }
private fun disableJavaPluginTasks(javaPluginConvention: JavaPluginConvention) { private fun disableJavaPluginTasks(javaSourceSet: SourceSetContainer) {
// A 'normal' build should not do redundant job like running the tests twice or building two JARs, // A 'normal' build should not do redundant job like running the tests twice or building two JARs,
// so disable some tasks and just make them depend on the others: // so disable some tasks and just make them depend on the others:
val targetJar = project.tasks.withType(Jar::class.java).named(artifactsTaskName) val targetJar = project.tasks.withType(Jar::class.java).named(artifactsTaskName)
project.tasks.withType(Jar::class.java).named(javaPluginConvention.sourceSets.getByName("main").jarTaskName) { javaJar -> project.tasks.withType(Jar::class.java).named(javaSourceSet.getByName("main").jarTaskName) { javaJar ->
(javaJar.source as? ConfigurableFileCollection)?.setFrom(targetJar.map { it.source }) (javaJar.source as? ConfigurableFileCollection)?.setFrom(targetJar.map { it.source })
javaJar.archiveFileName.set(targetJar.flatMap { it.archiveFileName }) javaJar.archiveFileName.set(targetJar.flatMap { it.archiveFileName })
javaJar.dependsOn(targetJar) javaJar.dependsOn(targetJar)
@@ -6,66 +6,45 @@
package org.jetbrains.kotlin.gradle.tasks package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.jetbrains.kotlin.gradle.dsl.KotlinSingleJavaTargetExtension
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
import org.jetbrains.kotlin.gradle.utils.newProperty
import java.io.File import java.io.File
import javax.inject.Inject
internal open class InspectClassesForMultiModuleIC : DefaultTask() { internal abstract class InspectClassesForMultiModuleIC @Inject constructor(
objects: ObjectFactory
) : DefaultTask() {
@get:Input @get:Input
internal val archivePath = project.newProperty<String>() internal abstract val archivePath: Property<String>
@get:Input @get:Input
internal val archiveName = project.newProperty<String>() internal abstract val sourceSetName: Property<String>
@get:Input
lateinit var sourceSetName: String
@Suppress("MemberVisibilityCanBePrivate")
@get:OutputFile @get:OutputFile
internal val classesListFile: File by lazy { internal abstract val classesListFile: RegularFileProperty
(project.kotlinExtension as KotlinSingleJavaTargetExtension).target.defaultArtifactClassesListFile.get()
}
@get:IgnoreEmptyDirectories @get:IgnoreEmptyDirectories
@get:PathSensitive(PathSensitivity.ABSOLUTE) @get:PathSensitive(PathSensitivity.ABSOLUTE)
@get:InputFiles @get:InputFiles
internal val sourceSetOutputClassesDir by lazy { internal abstract val sourceSetOutputClassesDir: ConfigurableFileCollection
project.convention.findPlugin(JavaPluginConvention::class.java)?.sourceSets?.findByName(sourceSetName)?.output?.classesDirs
}
@get:Internal
internal val fileTrees
get() = sourceSetOutputClassesDir?.map {
objects.fileTree().from(it).include("**/*.class")
}
@get:Internal
internal val objects = project.objects
@Suppress("MemberVisibilityCanBePrivate")
@get:PathSensitive(PathSensitivity.ABSOLUTE) @get:PathSensitive(PathSensitivity.ABSOLUTE)
@get:IgnoreEmptyDirectories @get:IgnoreEmptyDirectories
@get:InputFiles @get:InputFiles
internal val classFiles: FileCollection internal val classFiles: FileCollection = objects.fileCollection()
get() { .from({ sourceSetOutputClassesDir.asFileTree.matching { it.include("**/*.class") } })
if (sourceSetOutputClassesDir != null) {
return objects.fileCollection().from(fileTrees)
}
return objects.fileCollection()
}
@TaskAction @TaskAction
fun run() { fun run() {
classesListFile.parentFile.mkdirs() with(classesListFile.get().asFile) {
val text = classFiles.map { it.absolutePath }.sorted().joinToString(File.pathSeparator) parentFile.mkdirs()
classesListFile.writeText(text) writeText(
classFiles.map { it.absolutePath }.sorted().joinToString(File.pathSeparator)
)
}
} }
private fun sanitizeFileName(candidate: String): String =
candidate.filter { it.isLetterOrDigit() }
} }
@@ -0,0 +1,12 @@
/*
* 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.utils
import org.gradle.api.plugins.ExtensionContainer
internal inline fun <reified T> ExtensionContainer.findByType(): T? = findByType(T::class.java)
internal inline fun <reified T> ExtensionContainer.getByType(): T = getByType(T::class.java)
@@ -11,6 +11,8 @@ import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessorG70
import javax.inject.Inject import javax.inject.Inject
private const val PLUGIN_VARIANT_NAME = "gradle70" private const val PLUGIN_VARIANT_NAME = "gradle70"
@@ -19,18 +21,33 @@ open class KotlinPluginWrapper @Inject constructor(
registry: ToolingModelBuilderRegistry registry: ToolingModelBuilderRegistry
) : AbstractKotlinPluginWrapper(registry) { ) : AbstractKotlinPluginWrapper(registry) {
override val pluginVariant: String = PLUGIN_VARIANT_NAME override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
} }
open class KotlinCommonPluginWrapper @Inject constructor( open class KotlinCommonPluginWrapper @Inject constructor(
registry: ToolingModelBuilderRegistry registry: ToolingModelBuilderRegistry
) : AbstractKotlinCommonPluginWrapper(registry) { ) : AbstractKotlinCommonPluginWrapper(registry) {
override val pluginVariant: String = PLUGIN_VARIANT_NAME override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
} }
open class KotlinAndroidPluginWrapper @Inject constructor( open class KotlinAndroidPluginWrapper @Inject constructor(
registry: ToolingModelBuilderRegistry registry: ToolingModelBuilderRegistry
) : AbstractKotlinAndroidPluginWrapper(registry) { ) : AbstractKotlinAndroidPluginWrapper(registry) {
override val pluginVariant: String = PLUGIN_VARIANT_NAME override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
} }
@Suppress("DEPRECATION_ERROR") @Suppress("DEPRECATION_ERROR")
@@ -38,15 +55,30 @@ open class Kotlin2JsPluginWrapper @Inject constructor(
registry: ToolingModelBuilderRegistry registry: ToolingModelBuilderRegistry
) : AbstractKotlin2JsPluginWrapper(registry) { ) : AbstractKotlin2JsPluginWrapper(registry) {
override val pluginVariant: String = PLUGIN_VARIANT_NAME override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
} }
open class KotlinMultiplatformPluginWrapper : AbstractKotlinMultiplatformPluginWrapper() { open class KotlinMultiplatformPluginWrapper : AbstractKotlinMultiplatformPluginWrapper() {
override val pluginVariant: String = PLUGIN_VARIANT_NAME override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
} }
@Suppress("unused") @Suppress("unused")
open class KotlinJsPluginWrapper : AbstractKotlinJsPluginWrapper() { open class KotlinJsPluginWrapper : AbstractKotlinJsPluginWrapper() {
override val pluginVariant: String = PLUGIN_VARIANT_NAME override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
} }
@Suppress("unused") @Suppress("unused")
@@ -54,6 +86,11 @@ open class KotlinPm20PluginWrapper @Inject constructor(
objectFactory: ObjectFactory objectFactory: ObjectFactory
) : AbstractKotlinPm20PluginWrapper(objectFactory) { ) : AbstractKotlinPm20PluginWrapper(objectFactory) {
override val pluginVariant: String = PLUGIN_VARIANT_NAME override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
} }
open class KotlinPlatformJvmPlugin : KotlinPlatformImplementationPluginBase("jvm") { open class KotlinPlatformJvmPlugin : KotlinPlatformImplementationPluginBase("jvm") {
@@ -95,3 +132,9 @@ open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
project.applyPlugin<KotlinCommonPluginWrapper>() project.applyPlugin<KotlinCommonPluginWrapper>()
} }
} }
private fun Project.registerVariantImplementations() {
val factories = VariantImplementationFactories.get(gradle)
factories[JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory::class] =
JavaSourceSetsAccessorG70.JavaSourceSetAccessorVariantFactoryG70()
}
@@ -0,0 +1,25 @@
/*
* 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.plugins.Convention
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.SourceSetContainer
internal class JavaSourceSetsAccessorG70(
private val convention: Convention
) : JavaSourceSetsAccessor {
override val sourceSets: SourceSetContainer
get() = convention.getPlugin(JavaPluginConvention::class.java).sourceSets
override val sourceSetsIfAvailable: SourceSetContainer?
get() = convention.findPlugin(JavaPluginConvention::class.java)?.sourceSets
internal class JavaSourceSetAccessorVariantFactoryG70 : JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory {
override fun getInstance(project: Project): JavaSourceSetsAccessor = JavaSourceSetsAccessorG70(project.convention)
}
}
@@ -0,0 +1,140 @@
/*
* 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
private const val PLUGIN_VARIANT_NAME = "gradle71"
open class KotlinPluginWrapper @Inject constructor(
registry: ToolingModelBuilderRegistry
) : AbstractKotlinPluginWrapper(registry) {
override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
}
open class KotlinCommonPluginWrapper @Inject constructor(
registry: ToolingModelBuilderRegistry
) : AbstractKotlinCommonPluginWrapper(registry) {
override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
}
open class KotlinAndroidPluginWrapper @Inject constructor(
registry: ToolingModelBuilderRegistry
) : AbstractKotlinAndroidPluginWrapper(registry) {
override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
}
@Suppress("DEPRECATION_ERROR")
open class Kotlin2JsPluginWrapper @Inject constructor(
registry: ToolingModelBuilderRegistry
) : AbstractKotlin2JsPluginWrapper(registry) {
override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
}
open class KotlinMultiplatformPluginWrapper : AbstractKotlinMultiplatformPluginWrapper() {
override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
}
open class KotlinJsPluginWrapper : AbstractKotlinJsPluginWrapper() {
override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
}
open class KotlinPm20PluginWrapper @Inject constructor(
objectFactory: ObjectFactory
) : AbstractKotlinPm20PluginWrapper(objectFactory) {
override val pluginVariant: String = PLUGIN_VARIANT_NAME
override fun apply(project: Project) {
project.registerVariantImplementations()
super.apply(project)
}
}
open class KotlinPlatformJvmPlugin : KotlinPlatformImplementationPluginBase("jvm") {
override fun apply(project: Project) {
project.applyPlugin<KotlinPluginWrapper>()
super.apply(project)
}
}
open class KotlinPlatformJsPlugin : KotlinPlatformImplementationPluginBase("js") {
override fun apply(project: Project) {
@Suppress("DEPRECATION_ERROR")
project.applyPlugin<Kotlin2JsPluginWrapper>()
super.apply(project)
}
}
open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase("android") {
override fun apply(project: Project) {
project.applyPlugin<KotlinAndroidPluginWrapper>()
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<KotlinCommonPluginWrapper>()
}
}
@Suppress("unused")
private fun Project.registerVariantImplementations() {}
@@ -11,6 +11,8 @@ import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessorG6
import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfigurator import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfigurator
import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfiguratorG6 import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfiguratorG6
import javax.inject.Inject import javax.inject.Inject
@@ -142,4 +144,6 @@ private fun Project.registerVariantImplementations() {
val factories = VariantImplementationFactories.get(gradle) val factories = VariantImplementationFactories.get(gradle)
factories[MavenPluginConfigurator.MavenPluginConfiguratorVariantFactory::class] = factories[MavenPluginConfigurator.MavenPluginConfiguratorVariantFactory::class] =
MavenPluginConfiguratorG6.Gradle6MavenPluginConfiguratorVariantFactory() MavenPluginConfiguratorG6.Gradle6MavenPluginConfiguratorVariantFactory()
factories[JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory::class] =
JavaSourceSetsAccessorG6.JavaSourceSetAccessorVariantFactoryG70()
} }
@@ -0,0 +1,25 @@
/*
* 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.plugins.Convention
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.SourceSetContainer
internal class JavaSourceSetsAccessorG6(
private val convention: Convention
) : JavaSourceSetsAccessor {
override val sourceSets: SourceSetContainer
get() = convention.getPlugin(JavaPluginConvention::class.java).sourceSets
override val sourceSetsIfAvailable: SourceSetContainer?
get() = convention.findPlugin(JavaPluginConvention::class.java)?.sourceSets
internal class JavaSourceSetAccessorVariantFactoryG70 : JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory {
override fun getInstance(project: Project): JavaSourceSetsAccessor = JavaSourceSetsAccessorG6(project.convention)
}
}