[Gradle] Share Cinterop and regular [MDT]Tasks inputs

These tasks are essentially operating on the same inputs but produces
different ouputs. Therefore, it makes sense to extract their Task Inputs
into a separate container and let these tasks share it.

KT-58471 Verification Pending
This commit is contained in:
Anton Lakotka
2023-05-22 14:09:27 +02:00
committed by Space Team
parent 7abc6af124
commit 72c7d15be8
3 changed files with 97 additions and 86 deletions
@@ -16,11 +16,7 @@ import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFileProperty import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.work.NormalizeLineEndings
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope.*
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.targets.metadata.dependsOnClosureWithInterCompilationDependencies import org.jetbrains.kotlin.gradle.targets.metadata.dependsOnClosureWithInterCompilationDependencies
import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.dependsOn
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
@@ -64,35 +60,13 @@ open class MetadataDependencyTransformationTask
//region Task Configuration State & Inputs //region Task Configuration State & Inputs
private val transformationParameters = GranularMetadataTransformation.Params(project, kotlinSourceSet) private val transformationParameters = GranularMetadataTransformation.Params(project, kotlinSourceSet)
@Suppress("unused") // task inputs for up-to-date checks
@get:Nested
internal val taskInputs = MetadataDependencyTransformationTaskInputs(project, kotlinSourceSet)
@get:OutputDirectory @get:OutputDirectory
internal val outputsDir: File get() = projectLayout.kotlinTransformedMetadataLibraryDirectoryForBuild(transformationParameters.sourceSetName) internal val outputsDir: File get() = projectLayout.kotlinTransformedMetadataLibraryDirectoryForBuild(transformationParameters.sourceSetName)
@Suppress("unused") // Gradle input
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:IgnoreEmptyDirectories
@get:NormalizeLineEndings
internal val configurationToResolve: FileCollection = kotlinSourceSet.internal.resolvableMetadataConfiguration
@Suppress("unused") // Gradle input
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:IgnoreEmptyDirectories
@get:NormalizeLineEndings
protected val hostSpecificMetadataConfigurationsToResolve: FileCollection = project.filesProvider {
kotlinSourceSet.internal.compilations
.filter { compilation -> if (compilation is KotlinNativeCompilation) compilation.konanTarget.enabledOnCurrentHost else true }
.mapNotNull { compilation -> compilation.internal.configurations.hostSpecificMetadataConfiguration }
}
@Transient // Only needed for configuring task inputs
private val participatingSourceSetsLazy: Lazy<Set<KotlinSourceSet>>? = lazy {
kotlinSourceSet.internal.withDependsOnClosure.toMutableSet().apply {
if (any { it.name == KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME })
add(project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME))
}
}
@Transient // Only needed for configuring task inputs @Transient // Only needed for configuring task inputs
private val parentTransformationTasksLazy: Lazy<List<TaskProvider<MetadataDependencyTransformationTask>>>? = lazy { private val parentTransformationTasksLazy: Lazy<List<TaskProvider<MetadataDependencyTransformationTask>>>? = lazy {
dependsOnClosureWithInterCompilationDependencies(kotlinSourceSet).mapNotNull { dependsOnClosureWithInterCompilationDependencies(kotlinSourceSet).mapNotNull {
@@ -102,13 +76,6 @@ open class MetadataDependencyTransformationTask
} }
} }
private val participatingSourceSets: Set<KotlinSourceSet>
get() = participatingSourceSetsLazy?.value
?: error(
"`participatingSourceSets` is null. " +
"Probably it is accessed it during Task Execution with state loaded from Configuration Cache"
)
private val parentTransformationTasks: List<TaskProvider<MetadataDependencyTransformationTask>> private val parentTransformationTasks: List<TaskProvider<MetadataDependencyTransformationTask>>
get() = parentTransformationTasksLazy?.value get() = parentTransformationTasksLazy?.value
?: error( ?: error(
@@ -116,23 +83,6 @@ open class MetadataDependencyTransformationTask
"Probably it is accessed it during Task Execution with state loaded from Configuration Cache" "Probably it is accessed it during Task Execution with state loaded from Configuration Cache"
) )
@Suppress("unused") // Gradle input
@get:Input
protected val inputSourceSetsAndCompilations: Map<String, Iterable<String>> by lazy {
participatingSourceSets.associate { sourceSet ->
sourceSet.name to sourceSet.internal.compilations.map { it.name }.sorted()
}
}
@Suppress("unused") // Gradle input
@get:Input
protected val inputCompilationDependencies: Map<String, Set<List<String?>>> by lazy {
participatingSourceSets.flatMap { it.internal.compilations }.associate {
it.name to project.configurations.getByName(it.compileDependencyConfigurationName)
.allDependencies.map { listOf(it.group, it.name, it.version) }.toSet()
}
}
@get:OutputFile @get:OutputFile
protected val transformedLibrariesIndexFile: RegularFileProperty = objectFactory protected val transformedLibrariesIndexFile: RegularFileProperty = objectFactory
.fileProperty() .fileProperty()
@@ -0,0 +1,88 @@
package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.*
import org.gradle.work.NormalizeLineEndings
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.utils.filesProvider
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
internal class MetadataDependencyTransformationTaskInputs(
project: Project,
kotlinSourceSet: KotlinSourceSet,
private val skipProjectDependencies: Boolean = false,
) {
@Suppress("unused") // Gradle input
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:IgnoreEmptyDirectories
@get:NormalizeLineEndings
val configurationToResolve: FileCollection = kotlinSourceSet
.internal
.resolvableMetadataConfiguration
.applyIf(skipProjectDependencies) { withoutProjectDependencies() }
@Suppress("unused") // Gradle input
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:IgnoreEmptyDirectories
@get:NormalizeLineEndings
val hostSpecificMetadataConfigurationsToResolve: FileCollection = project.filesProvider {
kotlinSourceSet.internal.compilations
.filter { compilation -> if (compilation is KotlinNativeCompilation) compilation.konanTarget.enabledOnCurrentHost else true }
.mapNotNull { compilation -> compilation
.internal
.configurations
.hostSpecificMetadataConfiguration
?.applyIf(skipProjectDependencies) { withoutProjectDependencies() }
}
}
@Transient // Only needed for configuring task inputs
private val participatingSourceSetsLazy: Lazy<Set<KotlinSourceSet>>? = lazy {
kotlinSourceSet.internal.withDependsOnClosure.toMutableSet().apply {
if (any { it.name == KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME })
add(project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME))
}
}
private val participatingSourceSets: Set<KotlinSourceSet>
get() = participatingSourceSetsLazy?.value
?: error(
"`participatingSourceSets` is null. " +
"Probably it is accessed it during Task Execution with state loaded from Configuration Cache"
)
@Suppress("unused") // Gradle input
@get:Input
val inputSourceSetsAndCompilations: Map<String, Iterable<String>> by lazy {
participatingSourceSets.associate { sourceSet ->
sourceSet.name to sourceSet.internal.compilations.map { it.name }.sorted()
}
}
@Suppress("unused") // Gradle input
@get:Input
val inputCompilationDependencies: Map<String, Set<List<String?>>> by lazy {
participatingSourceSets.flatMap { it.internal.compilations }.associate {
it.name to project.configurations.getByName(it.compileDependencyConfigurationName)
.allDependencies
.applyIf(skipProjectDependencies) { filterNot { it is ProjectDependency } }
.map { listOf(it.group, it.name, it.version) }.toSet()
}
}
}
private fun Configuration.withoutProjectDependencies(): FileCollection {
return incoming.artifactView { view ->
view.componentFilter { componentIdentifier ->
componentIdentifier !is ProjectComponentIdentifier
}
}.files
}
@@ -113,7 +113,10 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru
@Transient @get:Internal val sourceSet: DefaultKotlinSourceSet, @Transient @get:Internal val sourceSet: DefaultKotlinSourceSet,
@get:OutputDirectory val outputDirectory: File, @get:OutputDirectory val outputDirectory: File,
@get:Internal val cleaning: Cleaning, @get:Internal val cleaning: Cleaning,
objectFactory: ObjectFactory /** when set, project-to-project dependencies will not be included to [outputLibraryFiles],
* assuming they are added during gradle configuration, see [createCInteropMetadataDependencyClasspath] for details */
private val skipProjectDependencies: Boolean,
objectFactory: ObjectFactory,
) : DefaultTask() { ) : DefaultTask() {
private val parameters = GranularMetadataTransformation.Params(project, sourceSet) private val parameters = GranularMetadataTransformation.Params(project, sourceSet)
@@ -133,38 +136,8 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru
} }
} }
@Suppress("unused")
class ChooseVisibleSourceSetProjection(
@Input val dependencyModuleIdentifiers: List<KpmModuleIdentifier>,
@Nested val projectStructureMetadata: KotlinProjectStructureMetadata,
@Optional @Input val visibleSourceSetProvidingCInterops: String?
) {
constructor(chooseVisibleSourceSets: ChooseVisibleSourceSets) : this(
dependencyModuleIdentifiers = chooseVisibleSourceSets.dependency.toKpmModuleIdentifiers(),
projectStructureMetadata = chooseVisibleSourceSets.projectStructureMetadata,
visibleSourceSetProvidingCInterops = chooseVisibleSourceSets.visibleSourceSetProvidingCInterops
)
}
@Suppress("unused")
@get:Classpath
protected val inputArtifactFiles: FileCollection = sourceSet
.internal
.resolvableMetadataConfiguration
.withoutProjectDependencies()
@get:Internal
protected val chooseVisibleSourceSets
get() = sourceSet
.metadataTransformation
.metadataDependencyResolutionsOrEmpty
.resolutionsToTransform()
@Suppress("unused")
@get:Nested @get:Nested
protected val chooseVisibleSourceSetsProjection by lazy { internal val inputs = MetadataDependencyTransformationTaskInputs(project, sourceSet, skipProjectDependencies)
chooseVisibleSourceSets.map(::ChooseVisibleSourceSetProjection).toSet()
}
@get:OutputFile @get:OutputFile
protected val outputLibrariesFileIndex: RegularFileProperty = objectFactory protected val outputLibrariesFileIndex: RegularFileProperty = objectFactory