[Gradle] Minor: Improve readability of GranularMetadataTransformation.kt

^KT-46198
This commit is contained in:
sebastian.sellmair
2021-10-08 14:14:21 +02:00
committed by Space
parent df7ab52505
commit 5902e3d0fd
6 changed files with 61 additions and 60 deletions
@@ -14,7 +14,6 @@ import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.Attribute
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
import org.jetbrains.kotlin.gradle.dsl.topLevelExtension import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
@@ -71,11 +70,11 @@ internal sealed class MetadataDependencyResolution(
) : MetadataDependencyResolution(dependency, projectDependency) { ) : MetadataDependencyResolution(dependency, projectDependency) {
/** Returns the mapping of source set names to files which should be used as the [dependency] parts representing the source sets. /** Returns the mapping of source set names to files which should be used as the [dependency] parts representing the source sets.
* If any temporary files need to be created, their paths are built from the [baseDir]. * If any temporary files need to be created, their paths are built from the [baseDir].
* If [doProcessFiles] is true, these temporary files are actually re-created during the call, * If [createFiles] is true, these temporary files are actually re-created during the call,
* otherwise only their paths are returned, while the files might be missing. * otherwise only their paths are returned, while the files might be missing.
*/ */
fun getMetadataFilesBySourceSet(baseDir: File, doProcessFiles: Boolean): Map<String, FileCollection> = fun getMetadataFilesBySourceSet(baseDir: File, createFiles: Boolean): Map<String, FileCollection> =
getExtractableMetadataFiles(baseDir).getMetadataFilesPerSourceSet(doProcessFiles) getExtractableMetadataFiles(baseDir).getMetadataFilesPerSourceSet(createFiles)
abstract fun getExtractableMetadataFiles(baseDir: File): ExtractableMetadataFiles abstract fun getExtractableMetadataFiles(baseDir: File): ExtractableMetadataFiles
@@ -373,9 +372,8 @@ private class ProjectMppDependencyMetadataExtractor(
val dependencyProject: Project val dependencyProject: Project
) : MppDependencyMetadataExtractor(project, dependency) { ) : MppDependencyMetadataExtractor(project, dependency) {
override fun getProjectStructureMetadata(): KotlinProjectStructureMetadata? { override fun getProjectStructureMetadata(): KotlinProjectStructureMetadata? {
val topLevelExtension = dependencyProject.topLevelExtension return when (val topLevelExtension = dependencyProject.topLevelExtension) {
return when { is KotlinPm20ProjectExtension -> buildProjectStructureMetadata(
topLevelExtension is KotlinPm20ProjectExtension -> buildProjectStructureMetadata(
topLevelExtension.modules.single { it.moduleIdentifier == moduleIdentifier } topLevelExtension.modules.single { it.moduleIdentifier == moduleIdentifier }
) )
else -> buildKotlinProjectStructureMetadata(dependencyProject) else -> buildKotlinProjectStructureMetadata(dependencyProject)
@@ -401,7 +399,7 @@ private class ProjectMppDependencyMetadataExtractor(
} }
return object : ExtractableMetadataFiles() { return object : ExtractableMetadataFiles() {
override fun getMetadataFilesPerSourceSet(doProcessFiles: Boolean): Map<String, FileCollection> = result override fun getMetadataFilesPerSourceSet(createFiles: Boolean): Map<String, FileCollection> = result
} }
} }
} }
@@ -459,11 +457,13 @@ internal open class JarArtifactMppDependencyMetadataExtractor(
val moduleId = ModuleIds.fromComponent(project, component) val moduleId = ModuleIds.fromComponent(project, component)
return JarExtractableMetadataFiles( return JarExtractableMetadataFiles(
moduleId, module = moduleId,
project, project = project,
baseDir, baseDir = baseDir,
visibleSourceSetNames.associate { it to (metadataArtifactBySourceSet[it] ?: primaryArtifact) }, artifactBySourceSet = visibleSourceSetNames.associateWith { (metadataArtifactBySourceSet[it] ?: primaryArtifact) },
checkNotNull(getProjectStructureMetadata()) { "project structure metadata is needed to extract files" } projectStructureMetadata = checkNotNull(getProjectStructureMetadata()) {
"project structure metadata is needed to extract files"
}
) )
} }
@@ -475,60 +475,63 @@ internal open class JarArtifactMppDependencyMetadataExtractor(
private val projectStructureMetadata: KotlinProjectStructureMetadata private val projectStructureMetadata: KotlinProjectStructureMetadata
) : ExtractableMetadataFiles() { ) : ExtractableMetadataFiles() {
override fun getMetadataFilesPerSourceSet(doProcessFiles: Boolean): Map<String, FileCollection> { override fun getMetadataFilesPerSourceSet(createFiles: Boolean): Map<String, FileCollection> {
return artifactBySourceSet.mapValues { (sourceSetName, artifact) ->
project.files(
getCompiledSourceSetMetadata(sourceSetName, artifact, createFiles)
)
}
}
private fun getCompiledSourceSetMetadata(sourceSetName: String, artifact: File, createFiles: Boolean): File {
val moduleString = "${module.groupId}-${module.moduleId}" val moduleString = "${module.groupId}-${module.moduleId}"
val transformedModuleRoot = run { baseDir.resolve(moduleString).also { it.mkdirs() } } val transformedModuleRoot = run { baseDir.resolve(moduleString).also { it.mkdirs() } }
val resultFiles = mutableMapOf<String, FileCollection>() val extension = projectStructureMetadata.sourceSetBinaryLayout[sourceSetName]?.archiveExtension
val projectStructureMetadata = projectStructureMetadata ?: SourceSetMetadataLayout.METADATA.archiveExtension
artifactBySourceSet.forEach { (sourceSetName, artifact) -> val metadataOutputFile = transformedModuleRoot.resolve("$moduleString-$sourceSetName.$extension")
val extension = projectStructureMetadata.sourceSetBinaryLayout[sourceSetName]?.archiveExtension
?: SourceSetMetadataLayout.METADATA.archiveExtension
val extractToJarFile = transformedModuleRoot.resolve("$moduleString-$sourceSetName.$extension")
/** NB: the result may contain files that do not exist and won't be created if the actual metadata artifact doesn't contain /** In composite builds, we don't really need tro process the file in IDE import, so ignore it if it's missing */
* entries for the corresponding source set. It's the consumer's responsibility to filter the result if they need only // refactor: allow only included builds to provide no artifacts, and allow this only in IDE import
* existing files! */ if (!artifact.isFile) {
resultFiles[sourceSetName] = project.files(extractToJarFile) return metadataOutputFile
}
if (doProcessFiles) { if (!createFiles) {
if (extractToJarFile.exists()) { return metadataOutputFile
extractToJarFile.delete() }
}
/** In composite builds, we don't really need tro process the file in IDE import, so ignore it if it's missing */ if (metadataOutputFile.exists()) {
// refactor: allow only included builds to provide no artifacts, and allow this only in IDE import metadataOutputFile.delete()
if (!artifact.isFile) return@forEach }
ZipFile(artifact).use { zip -> ZipFile(artifact).use { zip ->
val entries = zip.entries().asSequence().filter { it.name.startsWith("$sourceSetName/") }.toList() val entries = zip.entries().asSequence().filter { it.name.startsWith("$sourceSetName/") }.toList()
// TODO: once IJ supports non-JAR metadata dependencies, extract to a directory, not a JAR // TODO: once IJ supports non-JAR metadata dependencies, extract to a directory, not a JAR
// Also, if both IJ and the CLI compiler can read metadata from a path inside a JAR, then no operations will be needed // Also, if both IJ and the CLI compiler can read metadata from a path inside a JAR, then no operations will be needed
if (entries.any()) { if (entries.any()) {
ZipOutputStream(extractToJarFile.outputStream()).use { resultZipOutput -> ZipOutputStream(metadataOutputFile.outputStream()).use { resultZipOutput ->
for (entry in entries) { for (entry in entries) {
if (entry.isDirectory) if (entry.isDirectory)
continue continue
// Drop the source set name from the entry path // Drop the source set name from the entry path
val resultEntry = ZipEntry(entry.name.substringAfter("/")) val resultEntry = ZipEntry(entry.name.substringAfter("/"))
zip.getInputStream(entry).use { inputStream -> zip.getInputStream(entry).use { inputStream ->
resultZipOutput.putNextEntry(resultEntry) resultZipOutput.putNextEntry(resultEntry)
inputStream.copyTo(resultZipOutput) inputStream.copyTo(resultZipOutput)
resultZipOutput.closeEntry() resultZipOutput.closeEntry()
}
}
} }
} }
} }
} }
} }
return resultFiles return metadataOutputFile
} }
} }
} }
@@ -540,7 +543,8 @@ internal fun getMetadataExtractor(
resolveViaAvailableAt: Boolean resolveViaAvailableAt: Boolean
): MppDependencyMetadataExtractor? { ): MppDependencyMetadataExtractor? {
val resolvedMppVariantsProvider = ResolvedMppVariantsProvider.get(project) val resolvedMppVariantsProvider = ResolvedMppVariantsProvider.get(project)
val moduleIdentifier = resolvedComponentResult.toSingleModuleIdentifier() // FIXME this loses information about auxiliary module deps val moduleIdentifier =
resolvedComponentResult.toSingleModuleIdentifier() // FIXME this loses information about auxiliary module deps
// TODO check how this code works with multi-capability resolutions // TODO check how this code works with multi-capability resolutions
return mppDependencyMetadataExtractor( return mppDependencyMetadataExtractor(
@@ -627,6 +631,6 @@ internal fun getProjectStructureMetadata(
// This class is needed to encapsulate how we extract the files and point to them in a way that doesn't capture the Gradle project state // This class is needed to encapsulate how we extract the files and point to them in a way that doesn't capture the Gradle project state
internal abstract class ExtractableMetadataFiles { internal abstract class ExtractableMetadataFiles {
abstract fun getMetadataFilesPerSourceSet(doProcessFiles: Boolean): Map<String, FileCollection> abstract fun getMetadataFilesPerSourceSet(createFiles: Boolean): Map<String, FileCollection>
} }
@@ -11,7 +11,6 @@ import org.gradle.api.tasks.*
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.TransformKotlinGranularMetadataForFragment
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope.* import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope.*
import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets
import org.jetbrains.kotlin.gradle.targets.metadata.ALL_COMPILE_METADATA_CONFIGURATION_NAME import org.jetbrains.kotlin.gradle.targets.metadata.ALL_COMPILE_METADATA_CONFIGURATION_NAME
@@ -117,7 +116,7 @@ open class TransformKotlinGranularMetadata
} }
outputsDir.mkdirs() outputsDir.mkdirs()
extractableFiles.forEach { it.getMetadataFilesPerSourceSet(doProcessFiles = true) } extractableFiles.forEach { it.getMetadataFilesPerSourceSet(createFiles = true) }
} }
} }
@@ -202,4 +202,4 @@ internal class MetadataCompilationRegistry {
withAllCommonCallbacks += action withAllCommonCallbacks += action
withAllNativeCallbacks += action withAllNativeCallbacks += action
} }
} }
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.jetbrains.kotlin.gradle.plugin.mpp.ExtractableMetadataFiles import org.jetbrains.kotlin.gradle.plugin.mpp.ExtractableMetadataFiles
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
@@ -85,7 +84,7 @@ internal open class TransformKotlinGranularMetadataForFragment
} }
outputsDir.mkdirs() outputsDir.mkdirs()
extractableFiles.forEach { it.getMetadataFilesPerSourceSet(doProcessFiles = true) } extractableFiles.forEach { it.getMetadataFilesPerSourceSet(createFiles = true) }
} }
} }
@@ -95,4 +94,4 @@ internal class FragmentResolvedMetadataProvider(
override val buildDependencies: Iterable<TaskProvider<*>> = listOf(taskProvider) override val buildDependencies: Iterable<TaskProvider<*>> = listOf(taskProvider)
override val metadataResolutions: Iterable<MetadataDependencyResolution> by taskProvider.map { it.metadataDependencyResolutions } override val metadataResolutions: Iterable<MetadataDependencyResolution> by taskProvider.map { it.metadataDependencyResolutions }
override val metadataFilesByResolution: Map<MetadataDependencyResolution, FileCollection> by taskProvider.map { it.filesByResolution } override val metadataFilesByResolution: Map<MetadataDependencyResolution, FileCollection> by taskProvider.map { it.filesByResolution }
} }
@@ -186,7 +186,7 @@ class DefaultKotlinSourceSet(
is MetadataDependencyResolution.ChooseVisibleSourceSets -> { is MetadataDependencyResolution.ChooseVisibleSourceSets -> {
val filesBySourceSet = resolution.getMetadataFilesBySourceSet( val filesBySourceSet = resolution.getMetadataFilesBySourceSet(
baseDir, baseDir,
doProcessFiles = true createFiles = true
).filter { it.value.any { it.exists() } } ).filter { it.value.any { it.exists() } }
MetadataDependencyTransformation( MetadataDependencyTransformation(
@@ -528,8 +528,7 @@ internal fun createTransformedMetadataClasspath(
if (resolutions == null) { if (resolutions == null) {
add(artifact.file) add(artifact.file)
} else { } else {
val chooseVisibleSourceSets = val chooseVisibleSourceSets = resolutions.filterIsInstance<MetadataDependencyResolution.ChooseVisibleSourceSets>()
resolutions.filterIsInstance<MetadataDependencyResolution.ChooseVisibleSourceSets>()
if (chooseVisibleSourceSets.isNotEmpty()) { if (chooseVisibleSourceSets.isNotEmpty()) {
// Wrap the list into a FileCollection, as some older Gradle version failed to resolve the classpath // Wrap the list into a FileCollection, as some older Gradle version failed to resolve the classpath