KT-37720 Replace ArtifactTransform with TransformAction
This commit is contained in:
+10
-10
@@ -26,12 +26,12 @@ import org.gradle.tooling.provider.model.ToolingModelBuilder
|
||||
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.CLASS_STRUCTURE_ARTIFACT_TYPE
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureArtifactTransform
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformAction
|
||||
import org.jetbrains.kotlin.gradle.model.builder.KaptModelBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
import java.io.ByteArrayOutputStream
|
||||
@@ -507,15 +507,14 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
|
||||
private fun maybeRegisterTransform(project: Project) {
|
||||
if (!project.extensions.extraProperties.has("KaptStructureTransformAdded")) {
|
||||
project.dependencies.registerTransform { variantTransform ->
|
||||
variantTransform.artifactTransform(StructureArtifactTransform::class.java)
|
||||
variantTransform.from.attribute(artifactType, "jar")
|
||||
variantTransform.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
|
||||
project.dependencies.registerTransform(StructureTransformAction::class.java) { transformSpec ->
|
||||
transformSpec.from.attribute(artifactType, "jar")
|
||||
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
|
||||
}
|
||||
project.dependencies.registerTransform { variantTransform ->
|
||||
variantTransform.artifactTransform(StructureArtifactTransform::class.java)
|
||||
variantTransform.from.attribute(artifactType, "directory")
|
||||
variantTransform.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
|
||||
|
||||
project.dependencies.registerTransform(StructureTransformAction::class.java) { transformSpec ->
|
||||
transformSpec.from.attribute(artifactType, "directory")
|
||||
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
|
||||
}
|
||||
|
||||
project.extensions.extraProperties["KaptStructureTransformAdded"] = true
|
||||
@@ -590,6 +589,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
override fun getPluginArtifact(): SubpluginArtifact =
|
||||
JetBrainsSubpluginArtifact(artifactId = KAPT_ARTIFACT_NAME)
|
||||
}
|
||||
|
||||
private val artifactType = Attribute.of("artifactType", String::class.java)
|
||||
|
||||
// Don't reference the BaseVariant type in the Kapt plugin signatures, as those type references will fail to link when there's no Android
|
||||
|
||||
+14
-5
@@ -5,7 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.internal.kapt.incremental
|
||||
|
||||
import org.gradle.api.artifacts.transform.ArtifactTransform
|
||||
import org.gradle.api.artifacts.transform.InputArtifact
|
||||
import org.gradle.api.artifacts.transform.TransformAction
|
||||
import org.gradle.api.artifacts.transform.TransformOutputs
|
||||
import org.gradle.api.artifacts.transform.TransformParameters
|
||||
import org.gradle.api.file.FileSystemLocation
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.ClassWriter
|
||||
import java.io.*
|
||||
@@ -15,19 +20,23 @@ import java.util.zip.ZipFile
|
||||
const val CLASS_STRUCTURE_ARTIFACT_TYPE = "class-structure"
|
||||
private const val MODULE_INFO = "module-info.class"
|
||||
|
||||
class StructureArtifactTransform : ArtifactTransform() {
|
||||
override fun transform(input: File): MutableList<File> {
|
||||
abstract class StructureTransformAction : TransformAction<TransformParameters.None> {
|
||||
@get:InputArtifact
|
||||
abstract val inputArtifact: File
|
||||
|
||||
override fun transform(outputs: TransformOutputs) {
|
||||
try {
|
||||
val input = inputArtifact
|
||||
|
||||
val data = if (input.isDirectory) {
|
||||
visitDirectory(input)
|
||||
} else {
|
||||
visitJar(input)
|
||||
}
|
||||
|
||||
val dataFile = outputDirectory.resolve("output.bin")
|
||||
val dataFile = outputs.file("output.bin")
|
||||
data.saveTo(dataFile)
|
||||
|
||||
return mutableListOf(dataFile)
|
||||
} catch (e: Throwable) {
|
||||
throw e
|
||||
}
|
||||
|
||||
+26
-25
@@ -10,8 +10,12 @@ package org.jetbrains.kotlin.gradle.scripting.internal
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.transform.ArtifactTransform
|
||||
import org.gradle.api.artifacts.transform.InputArtifact
|
||||
import org.gradle.api.artifacts.transform.TransformAction
|
||||
import org.gradle.api.artifacts.transform.TransformOutputs
|
||||
import org.gradle.api.artifacts.transform.TransformParameters
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.file.FileSystemLocation
|
||||
import org.gradle.api.plugins.JavaPluginConvention
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.compile.AbstractCompile
|
||||
@@ -25,7 +29,6 @@ import org.jetbrains.kotlin.gradle.scripting.ScriptingExtension
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.reporter
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionsFromClasspathDiscoverySource
|
||||
import java.io.File
|
||||
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
||||
|
||||
private const val SCRIPTING_LOG_PREFIX = "kotlin scripting plugin:"
|
||||
@@ -149,46 +152,45 @@ private fun configureDiscoveryTransformation(
|
||||
}
|
||||
}
|
||||
|
||||
internal class DiscoverScriptExtensionsTransform : ArtifactTransform() {
|
||||
internal abstract class DiscoverScriptExtensionsTransformAction : TransformAction<TransformParameters.None> {
|
||||
@InputArtifact
|
||||
abstract fun getInputArtifact(): Provider<FileSystemLocation>
|
||||
|
||||
override fun transform(outputs: TransformOutputs) {
|
||||
val input = getInputArtifact().get().asFile
|
||||
|
||||
override fun transform(input: File): List<File> {
|
||||
val definitions =
|
||||
ScriptDefinitionsFromClasspathDiscoverySource(
|
||||
listOf(input),
|
||||
defaultJvmScriptingHostConfiguration,
|
||||
PrintingMessageCollector(System.out, MessageRenderer.WITHOUT_PATHS, false).reporter
|
||||
).definitions
|
||||
|
||||
val extensions = definitions.mapTo(arrayListOf()) { it.fileExtension }
|
||||
return if (extensions.isNotEmpty()) {
|
||||
val outputFile = outputDirectory.resolve("${input.nameWithoutExtension}.discoveredScriptsExtensions.txt")
|
||||
|
||||
if (extensions.isNotEmpty()) {
|
||||
val outputFile = outputs.file("${input.nameWithoutExtension}.discoveredScriptsExtensions.txt")
|
||||
outputFile.writeText(extensions.joinToString("\n"))
|
||||
listOf(outputFile)
|
||||
} else emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private
|
||||
fun Project.registerDiscoverScriptExtensionsTransform() {
|
||||
private fun Project.registerDiscoverScriptExtensionsTransform() {
|
||||
dependencies.apply {
|
||||
registerTransform {
|
||||
with(it) {
|
||||
from.attribute(artifactType, "jar")
|
||||
to.attribute(artifactType, scriptFilesExtensions)
|
||||
artifactTransform(DiscoverScriptExtensionsTransform::class.java)
|
||||
}
|
||||
registerTransform(DiscoverScriptExtensionsTransformAction::class.java) { transformSpec ->
|
||||
transformSpec.from.attribute(artifactType, "jar")
|
||||
transformSpec.to.attribute(artifactType, scriptFilesExtensions)
|
||||
|
||||
}
|
||||
registerTransform {
|
||||
with(it) {
|
||||
from.attribute(artifactType, "classes")
|
||||
to.attribute(artifactType, scriptFilesExtensions)
|
||||
artifactTransform(DiscoverScriptExtensionsTransform::class.java)
|
||||
}
|
||||
registerTransform(DiscoverScriptExtensionsTransformAction::class.java) { transformSpec ->
|
||||
transformSpec.from.attribute(artifactType, "classes")
|
||||
transformSpec.to.attribute(artifactType, scriptFilesExtensions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private
|
||||
fun <T> Project.withRegisteredDiscoverScriptExtensionsTransform(block: () -> T): T {
|
||||
private fun <T> Project.withRegisteredDiscoverScriptExtensionsTransform(block: () -> T): T {
|
||||
if (!project.extensions.extraProperties.has("DiscoverScriptExtensionsTransform")) {
|
||||
registerDiscoverScriptExtensionsTransform()
|
||||
project.extensions.extraProperties["DiscoverScriptExtensionsTransform"] = true
|
||||
@@ -200,8 +202,7 @@ private val artifactType = Attribute.of("artifactType", String::class.java)
|
||||
|
||||
private val scriptFilesExtensions = "script-files-extensions"
|
||||
|
||||
private
|
||||
fun Configuration.discoverScriptExtensionsFiles() =
|
||||
private fun Configuration.discoverScriptExtensionsFiles() =
|
||||
incoming.artifactView {
|
||||
attributes {
|
||||
it.attribute(artifactType, scriptFilesExtensions)
|
||||
|
||||
+50
-13
@@ -5,12 +5,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.internal.kapt.incremental
|
||||
|
||||
import org.gradle.api.artifacts.transform.TransformOutputs
|
||||
import org.gradle.api.artifacts.transform.TransformParameters
|
||||
import org.gradle.api.file.FileSystemLocation
|
||||
import org.gradle.api.internal.file.DefaultFileSystemLocation
|
||||
import org.gradle.api.internal.provider.DefaultProvider
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.org.objectweb.asm.ClassWriter
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import java.io.File
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
@@ -32,10 +40,10 @@ class ClasspathAnalyzerTest {
|
||||
it.writeBytes(emptyClass("A"))
|
||||
}
|
||||
}
|
||||
val transform = StructureArtifactTransform().also { it.outputDirectory = tmp.newFolder() }
|
||||
val outputs = transform.transform(classesDir)
|
||||
val outputs = TransformOutputsMock(tmp.newFolder())
|
||||
StructureTransformTestAction(classesDir).transform(outputs)
|
||||
|
||||
val data = ClasspathEntryData.ClasspathEntrySerializer.loadFrom(outputs.single())
|
||||
val data = ClasspathEntryData.ClasspathEntrySerializer.loadFrom(outputs.createdOutputs.single())
|
||||
assertEquals(setOf("test/A", "test/B"), data.classAbiHash.keys)
|
||||
assertEquals(setOf("test/A", "test/B"), data.classDependencies.keys)
|
||||
assertEquals(emptySet<String>(), data.classDependencies["test/A"]!!.abiTypes)
|
||||
@@ -68,10 +76,10 @@ class ClasspathAnalyzerTest {
|
||||
it.closeEntry()
|
||||
}
|
||||
}
|
||||
val transform = StructureArtifactTransform().also { it.outputDirectory = tmp.newFolder() }
|
||||
val outputs = transform.transform(inputJar)
|
||||
val outputs = TransformOutputsMock(tmp.newFolder())
|
||||
StructureTransformTestAction(inputJar).transform(outputs)
|
||||
|
||||
val data = ClasspathEntryData.ClasspathEntrySerializer.loadFrom(outputs.single())
|
||||
val data = ClasspathEntryData.ClasspathEntrySerializer.loadFrom(outputs.createdOutputs.single())
|
||||
assertEquals(setOf("test/A", "test/B"), data.classAbiHash.keys)
|
||||
assertEquals(setOf("test/A", "test/B"), data.classDependencies.keys)
|
||||
assertEquals(emptySet<String>(), data.classDependencies["test/A"]!!.abiTypes)
|
||||
@@ -94,7 +102,8 @@ class ClasspathAnalyzerTest {
|
||||
it.closeEntry()
|
||||
}
|
||||
}
|
||||
val outputA = StructureArtifactTransform().also { it.outputDirectory = tmp.newFolder() }.transform(jarA).single()
|
||||
val outputsA = TransformOutputsMock(tmp.newFolder())
|
||||
StructureTransformTestAction(jarA).transform(outputsA)
|
||||
|
||||
val jarB = tmp.newFile("inputB.jar").also { jar ->
|
||||
ZipOutputStream(jar.outputStream()).use {
|
||||
@@ -107,18 +116,20 @@ class ClasspathAnalyzerTest {
|
||||
it.closeEntry()
|
||||
}
|
||||
}
|
||||
val outputB = StructureArtifactTransform().also { it.outputDirectory = tmp.newFolder() }.transform(jarB).single()
|
||||
val outputsB = TransformOutputsMock(tmp.newFolder())
|
||||
StructureTransformTestAction(jarB).transform(outputsB)
|
||||
|
||||
assertArrayEquals(outputA.readBytes(), outputB.readBytes())
|
||||
assertArrayEquals(outputsA.createdOutputs.single().readBytes(), outputsB.createdOutputs.single().readBytes())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun emptyInput() {
|
||||
val inputDir = tmp.newFolder("input")
|
||||
val transform = StructureArtifactTransform().also { it.outputDirectory = tmp.newFolder() }
|
||||
val outputs = transform.transform(inputDir)
|
||||
val transformAction = StructureTransformTestAction(tmp.newFolder("input"))
|
||||
val outputs = TransformOutputsMock(tmp.newFolder())
|
||||
|
||||
val data = ClasspathEntryData.ClasspathEntrySerializer.loadFrom(outputs.single())
|
||||
transformAction.transform(outputs)
|
||||
|
||||
val data = ClasspathEntryData.ClasspathEntrySerializer.loadFrom(outputs.createdOutputs.single())
|
||||
assertTrue(data.classAbiHash.isEmpty())
|
||||
assertTrue(data.classDependencies.isEmpty())
|
||||
}
|
||||
@@ -128,4 +139,30 @@ class ClasspathAnalyzerTest {
|
||||
writer.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, internalName, null, "java/lang/Object", emptyArray())
|
||||
return writer.toByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
class StructureTransformTestAction(val input: File) : StructureTransformAction() {
|
||||
override val inputArtifact: File = input
|
||||
|
||||
override fun getParameters(): TransformParameters.None? {
|
||||
//no need for StructureTransformAction and so for test
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class TransformOutputsMock(val outputDir: File) : TransformOutputs {
|
||||
val createdOutputs = mutableListOf<File>()
|
||||
|
||||
override fun file(name: Any): File {
|
||||
val newFile = outputDir.resolve(name as String)
|
||||
createdOutputs.add(newFile)
|
||||
return newFile
|
||||
}
|
||||
|
||||
override fun dir(name: Any): File {
|
||||
val newDir = outputDir.resolve(name as String)
|
||||
createdOutputs.add(newDir)
|
||||
return newDir
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user