Fix deprecated gradle api usage in artifact transform

Previously, when adding --warning-mode=fail to KaptIncrementalIT,
it would fail when testing with advance gradle version because
deprecated configurations in build files of test projects and
gradle api usage in artifact transform.

With this PR, we have two "StructureTransformAction'. The one with
latest gradle api is for use at most cases, the legacy one is for use
when gradle version is less or equal than 5.3 because the new gradle api
is introduced in 5.4.

This change also adds some test fixtures and updates deprecated
configurations to support testing artifact transform.

Test: KaptIncrementalIT
This commit is contained in:
Bingran
2020-10-07 16:29:00 +01:00
committed by nataliya.valtman
parent 94145f880c
commit 88bbeea7f6
14 changed files with 143 additions and 22 deletions
@@ -2,6 +2,7 @@ package org.jetbrains.kotlin.gradle
import com.intellij.testFramework.TestDataFile
import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.configuration.WarningMode
import org.gradle.tooling.GradleConnector
import org.gradle.util.GradleVersion
import org.intellij.lang.annotations.Language
@@ -213,7 +214,8 @@ abstract class BaseGradleIT {
val parallelTasksInProject: Boolean? = null,
val jsCompilerType: KotlinJsCompilerType? = null,
val configurationCache: Boolean = false,
val configurationCacheProblems: ConfigurationCacheProblems = ConfigurationCacheProblems.FAIL
val configurationCacheProblems: ConfigurationCacheProblems = ConfigurationCacheProblems.FAIL,
val warningMode: WarningMode = WarningMode.Summary
)
enum class ConfigurationCacheProblems {
@@ -828,6 +830,7 @@ Finished executing task ':$taskName'|
// Workaround: override a console type set in the user machine gradle.properties (since Gradle 4.3):
add("--console=plain")
add("--warning-mode=${options.warningMode.name.toLowerCase()}")
addAll(options.freeCommandLineArgs)
}
@@ -293,7 +293,7 @@ open class A {
val appBuildGradle = project.projectDir.resolve("app/build.gradle")
val appBuildGradleContent = appBuildGradle.readText()
appBuildGradle.modify { it.checkedReplace("compile project(':lib')", "") }
appBuildGradle.modify { it.checkedReplace("implementation project(':lib')", "") }
val aaKt = project.projectDir.getFileByName("AA.kt")
aaKt.addNewLine()
@@ -1,5 +1,7 @@
package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.configuration.WarningMode
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.util.*
import org.junit.Test
import kotlin.test.assertEquals
@@ -18,8 +20,15 @@ open class KaptIncrementalIT : BaseGradleIT() {
private val annotatedElements =
arrayOf("A", "funA", "valA", "funUtil", "valUtil", "B", "funB", "valB", "useB")
override fun defaultBuildOptions(): BuildOptions =
super.defaultBuildOptions().copy(incremental = true)
override fun defaultBuildOptions(): BuildOptions {
val gradleVersion = GradleVersion.version(this.getProject().chooseWrapperVersionOrFinishTest())
//The feature of failing the build on deprecation warnings is introduced in gradle 5.6
return if (gradleVersion >= GradleVersion.version("5.6")) {
super.defaultBuildOptions().copy(incremental = true, warningMode = WarningMode.Fail)
} else {
super.defaultBuildOptions().copy(incremental = true)
}
}
@Test
fun testAddNewLine() {
@@ -190,7 +190,7 @@ class KaptIncrementalWithAggregatingApt : KaptIncrementalIT() {
project.gradleBuildScript().appendText("""
dependencies {
compile 'com.google.guava:guava:12.0'
implementation 'com.google.guava:guava:12.0'
}
""".trimIndent())
project.build("build") {
@@ -1,7 +1,7 @@
apply plugin: 'kotlin2js'
dependencies {
compile project(':lib')
implementation project(':lib')
// do not remove until KT-25488 is fixed
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
}
@@ -1,6 +1,6 @@
apply plugin: 'kotlin'
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile project(':lib')
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation project(':lib')
}
@@ -2,5 +2,5 @@ apply plugin: 'kotlin2js'
dependencies {
// do not remove until KT-25488 is fixed
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
}
@@ -1,5 +1,5 @@
apply plugin: 'kotlin'
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
@@ -18,8 +18,8 @@ repositories {
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
kapt "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
testCompile 'junit:junit:4.12'
testImplementation 'junit:junit:4.12'
}
@@ -24,9 +24,11 @@ import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.process.CommandLineArgumentProvider
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.gradle.util.GradleVersion
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.StructureTransformAction
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformLegacyAction
import org.jetbrains.kotlin.gradle.model.builder.KaptModelBuilder
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
@@ -516,14 +518,26 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
private fun maybeRegisterTransform(project: Project) {
if (!project.extensions.extraProperties.has("KaptStructureTransformAdded")) {
project.dependencies.registerTransform(StructureTransformAction::class.java) { transformSpec ->
transformSpec.from.attribute(artifactType, "jar")
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
}
if (GradleVersion.current() >= GradleVersion.version("5.4")) {
project.dependencies.registerTransform(StructureTransformAction::class.java) { transformSpec ->
transformSpec.from.attribute(artifactType, "jar")
transformSpec.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.dependencies.registerTransform(StructureTransformAction::class.java) { transformSpec ->
transformSpec.from.attribute(artifactType, "directory")
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
}
} else {
project.dependencies.registerTransform(StructureTransformLegacyAction::class.java) { transformSpec ->
transformSpec.from.attribute(artifactType, "jar")
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
}
project.dependencies.registerTransform(StructureTransformLegacyAction::class.java) { transformSpec ->
transformSpec.from.attribute(artifactType, "directory")
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
}
}
project.extensions.extraProperties["KaptStructureTransformAdded"] = true
@@ -9,6 +9,8 @@ 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.*
@@ -19,6 +21,35 @@ const val CLASS_STRUCTURE_ARTIFACT_TYPE = "class-structure"
private const val MODULE_INFO = "module-info.class"
abstract class StructureTransformAction : TransformAction<TransformParameters.None> {
@get:InputArtifact
abstract val inputArtifact: Provider<FileSystemLocation>
override fun transform(outputs: TransformOutputs) {
try {
val input = inputArtifact.get().asFile
val data = if (input.isDirectory) {
visitDirectory(input)
} else {
visitJar(input)
}
val dataFile = outputs.file("output.bin")
data.saveTo(dataFile)
} catch (e: Throwable) {
throw e
}
}
}
/**
* [StructureTransformLegacyAction] is a legacy version of [StructureTransformAction] and should only be used when gradle version is 5.3
* or less. The reason of having this legacy artifact transform is that declaring inputArtifact as type Provider<FileSystemLocation> is not
* supported until gradle version 5.4. Once our minimal supported gradle version is 5.4 or above, this legacy artifact transform can be
* removed.
*/
abstract class StructureTransformLegacyAction : TransformAction<TransformParameters.None> {
@get:InputArtifact
abstract val inputArtifact: File
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2020 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.fixtures
import org.gradle.api.Transformer
import org.gradle.api.provider.Provider
import java.util.function.BiFunction
class FakeGradleProvider<T>(private val v: (()-> T)?): Provider<T> {
constructor(v: T): this({v})
override fun <S : Any?> flatMap(transformer: Transformer<out Provider<out S>, in T>): Provider<S> {
@Suppress("UNCHECKED_CAST")
return transformer.transform(v!!.invoke()) as Provider<S>
}
override fun isPresent() = v != null
override fun getOrElse(p0: T) = if (isPresent) orNull else p0
override fun <S : Any> map(transformer: Transformer<out S, in T>): Provider<S> {
return FakeGradleProvider { transformer.transform(get()) }
}
override fun get() = orNull!!
override fun getOrNull() = v?.invoke()
override fun orElse(p0: T): Provider<T> {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun orElse(p0: Provider<out T>): Provider<T> {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun forUseAtConfigurationTime(): Provider<T> {
TODO("Not yet implemented")
}
override fun <B : Any?, R : Any?> zip(p0: Provider<B>, p1: BiFunction<T, B, R>): Provider<R> {
TODO("Not yet implemented")
}
}
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2020 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.fixtures
import org.gradle.api.file.RegularFile
import java.io.File
class FakeGradleRegularFile(private val file: File) : RegularFile {
override fun getAsFile(): File = file
}
@@ -11,6 +11,9 @@ 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.gradle.api.provider.ProviderFactory
import org.jetbrains.kotlin.gradle.fixtures.FakeGradleProvider
import org.jetbrains.kotlin.gradle.fixtures.FakeGradleRegularFile
import org.jetbrains.org.objectweb.asm.ClassWriter
import org.jetbrains.org.objectweb.asm.Opcodes
import org.junit.Assert.*
@@ -169,7 +172,7 @@ class ClasspathAnalyzerTest {
}
class StructureTransformTestAction(val input: File) : StructureTransformAction() {
override val inputArtifact: File = input
override val inputArtifact: Provider<FileSystemLocation> = FakeGradleProvider(FakeGradleRegularFile(input))
override fun getParameters(): TransformParameters.None? {
//no need for StructureTransformAction and so for test