From 88bbeea7f6aa60f92ba5bb2ad85e48805886c3a0 Mon Sep 17 00:00:00 2001 From: Bingran Date: Wed, 7 Oct 2020 16:29:00 +0100 Subject: [PATCH] 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 --- .../jetbrains/kotlin/gradle/BaseGradleIT.kt | 5 +- .../IncrementalCompilationMultiProjectIT.kt | 2 +- .../kotlin/gradle/KaptIncrementalIT.kt | 13 ++++- .../KaptIncrementalWithAggregatingApt.kt | 2 +- .../app/build-js.gradle | 4 +- .../incrementalMultiproject/app/build.gradle | 4 +- .../lib/build-js.gradle | 2 +- .../incrementalMultiproject/lib/build.gradle | 2 +- .../build.gradle | 6 +-- .../kapt/Kapt3KotlinGradleSubplugin.kt | 28 ++++++++--- .../kapt/incremental/ClasspathAnalyzer.kt | 31 ++++++++++++ .../gradle/fixtures/FakeGradleProvider.kt | 48 +++++++++++++++++++ .../gradle/fixtures/FakeGradleRegularFile.kt | 13 +++++ .../kapt/incremental/ClasspathAnalyzerTest.kt | 5 +- 14 files changed, 143 insertions(+), 22 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/fixtures/FakeGradleProvider.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/fixtures/FakeGradleRegularFile.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt index a014cf0b93e..50012ecc3f3 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt @@ -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) } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt index 2c5e189f006..bd4b2728148 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt @@ -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() diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalIT.kt index d43ddc360f3..db5ff4ca228 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalIT.kt @@ -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() { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt index 52dfb6a5c9e..ca60e4001ca 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt @@ -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") { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/app/build-js.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/app/build-js.gradle index 90f002e1ce5..62f6c9b017d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/app/build-js.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/app/build-js.gradle @@ -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" } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/app/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/app/build.gradle index b5432a9eb42..14dcf14ce9d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/app/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/app/build.gradle @@ -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') } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/lib/build-js.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/lib/build-js.gradle index 718db2a0c77..aaf051c9255 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/lib/build-js.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/lib/build-js.gradle @@ -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" } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/lib/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/lib/build.gradle index ee7434e1b5d..83e41992508 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/lib/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/incrementalMultiproject/lib/build.gradle @@ -1,5 +1,5 @@ apply plugin: 'kotlin' dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kaptIncrementalCompilationProject/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kaptIncrementalCompilationProject/build.gradle index a44e0f08e55..b347cdb6bbc 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kaptIncrementalCompilationProject/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kaptIncrementalCompilationProject/build.gradle @@ -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' } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt index c87f97ce0dd..e15d3a23cbf 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt @@ -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 diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathAnalyzer.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathAnalyzer.kt index 6366f939195..9eaf03489dd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathAnalyzer.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathAnalyzer.kt @@ -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 { + @get:InputArtifact + abstract val inputArtifact: Provider + + 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 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 { @get:InputArtifact abstract val inputArtifact: File diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/fixtures/FakeGradleProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/fixtures/FakeGradleProvider.kt new file mode 100644 index 00000000000..8c35858daf3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/fixtures/FakeGradleProvider.kt @@ -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(private val v: (()-> T)?): Provider { + + constructor(v: T): this({v}) + + override fun flatMap(transformer: Transformer, in T>): Provider { + @Suppress("UNCHECKED_CAST") + return transformer.transform(v!!.invoke()) as Provider + } + + override fun isPresent() = v != null + + override fun getOrElse(p0: T) = if (isPresent) orNull else p0 + + override fun map(transformer: Transformer): Provider { + return FakeGradleProvider { transformer.transform(get()) } + } + + override fun get() = orNull!! + + override fun getOrNull() = v?.invoke() + + override fun orElse(p0: T): Provider { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun orElse(p0: Provider): Provider { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun forUseAtConfigurationTime(): Provider { + TODO("Not yet implemented") + } + + override fun zip(p0: Provider, p1: BiFunction): Provider { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/fixtures/FakeGradleRegularFile.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/fixtures/FakeGradleRegularFile.kt new file mode 100644 index 00000000000..b4523063d35 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/fixtures/FakeGradleRegularFile.kt @@ -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 +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathAnalyzerTest.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathAnalyzerTest.kt index 140e3377089..1fdf0a2a66a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathAnalyzerTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathAnalyzerTest.kt @@ -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 = FakeGradleProvider(FakeGradleRegularFile(input)) override fun getParameters(): TransformParameters.None? { //no need for StructureTransformAction and so for test