Add workaround for external plugin modifying options on task execution
Currently, known plugins doing that are 'kotlin-dsl' and AGP with compose enabled. They are setting freeCompilerArgs in KotlinCompile .doFirst task action. At this point compilerOptions.freeCompilerArgs are finalized and Gradle doesn't allow further modification. ^KT-27301 In Progress
This commit is contained in:
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
||||
internal class CompilerOptionsIT : KGPBaseTest() {
|
||||
|
||||
// In Gradle 7.3-7.5 'kotlin-dsl' plugin tries to set up freeCompilerArgs in doFirst task action
|
||||
@DisplayName("Allows to set kotlinOptions.freeCompilerArgs on task execution with warning")
|
||||
@JvmGradlePluginTests
|
||||
@GradleTestVersions(
|
||||
minVersion = TestVersions.Gradle.G_7_3,
|
||||
maxVersion = TestVersions.Gradle.G_7_5
|
||||
)
|
||||
@GradleTest
|
||||
internal fun compatibleWithKotlinDsl(gradleVersion: GradleVersion) {
|
||||
project("buildSrcWithKotlinDslAndKgp", gradleVersion) {
|
||||
build("tasks") {
|
||||
assertOutputContains("kotlinOptions.freeCompilerArgs were changed on task execution phase:")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
//buildscript {
|
||||
// dependencies {
|
||||
// classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${property("kotlin_version")}")
|
||||
// classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:${property("kotlin_version")}")
|
||||
// }
|
||||
//}
|
||||
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.jvm")
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${property("kotlin_version")}")
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.
|
||||
*/
|
||||
|
||||
import org.gradle.api.Project
|
||||
|
||||
fun Project.nameLength() = name.length
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
dependencies {
|
||||
"implementation"("org.jetbrains.kotlin:kotlin-symbol-processing-api")
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.
|
||||
*/
|
||||
|
||||
fun main() {
|
||||
println("Hello World!")
|
||||
}
|
||||
+19
-4
@@ -56,6 +56,7 @@ import org.jetbrains.kotlin.gradle.report.BuildMetricsService
|
||||
import org.jetbrains.kotlin.gradle.report.BuildReportMode
|
||||
import org.jetbrains.kotlin.gradle.report.BuildReportsService
|
||||
import org.jetbrains.kotlin.gradle.report.ReportingSettings
|
||||
import org.jetbrains.kotlin.gradle.tasks.internal.KotlinJvmOptionsCompat
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.incremental.*
|
||||
import org.jetbrains.kotlin.incremental.ClasspathChanges.ClasspathSnapshotDisabled
|
||||
@@ -535,10 +536,10 @@ abstract class KotlinCompile @Inject constructor(
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated("Replaced by compilerOptions input", replaceWith = ReplaceWith("compilerOptions"))
|
||||
final override val kotlinOptions: KotlinJvmOptions = object : KotlinJvmOptions {
|
||||
override val options: CompilerJvmOptions
|
||||
get() = compilerOptions
|
||||
}
|
||||
final override val kotlinOptions: KotlinJvmOptions = KotlinJvmOptionsCompat(
|
||||
{ this },
|
||||
compilerOptions
|
||||
)
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated("Configure compilerOptions directly", replaceWith = ReplaceWith("compilerOptions"))
|
||||
@@ -677,6 +678,16 @@ abstract class KotlinCompile @Inject constructor(
|
||||
override fun createCompilerArgs(): K2JVMCompilerArguments =
|
||||
K2JVMCompilerArguments()
|
||||
|
||||
/**
|
||||
* Workaround for those "nasty" plugins that are adding 'freeCompilerArgs' on task execution phase.
|
||||
* With properties api it is not possible to update property value after task configuration is finished.
|
||||
*
|
||||
* Marking it as `@Internal` as anyway on the configuration phase, when Gradle does task inputs snapshot,
|
||||
* this input will always be empty.
|
||||
*/
|
||||
@get:Internal
|
||||
internal var additionalFreeCompilerArgs: List<String> = listOf()
|
||||
|
||||
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
|
||||
compilerArgumentsContributor.contributeArguments(
|
||||
args, compilerArgumentsConfigurationFlags(
|
||||
@@ -690,6 +701,10 @@ abstract class KotlinCompile @Inject constructor(
|
||||
if (reportingSettings().buildReportMode == BuildReportMode.VERBOSE) {
|
||||
args.reportPerf = true
|
||||
}
|
||||
|
||||
if (additionalFreeCompilerArgs.isNotEmpty()) {
|
||||
args.freeArgs = compilerOptions.freeCompilerArgs.get().union(additionalFreeCompilerArgs).toList()
|
||||
}
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.tasks.internal
|
||||
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
/**
|
||||
* Temporary workaround for external plugins that tries to set up freeCompilerArgs
|
||||
* in task execution phase.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
class KotlinJvmOptionsCompat(
|
||||
private val task: () -> KotlinCompile,
|
||||
override val options: CompilerJvmOptions
|
||||
) : KotlinJvmOptions {
|
||||
override var freeCompilerArgs: List<String>
|
||||
get() = if (isTaskExecuting) {
|
||||
options.freeCompilerArgs.get().union(task().additionalFreeCompilerArgs).toList()
|
||||
} else {
|
||||
options.freeCompilerArgs.get()
|
||||
}
|
||||
|
||||
set(value) = if (isTaskExecuting) {
|
||||
task().logger.warn(
|
||||
"kotlinOptions.freeCompilerArgs were changed on task execution phase: ${value.joinToString()}\n" +
|
||||
"This behaviour is deprecated and become an error in future releases!"
|
||||
)
|
||||
task().additionalFreeCompilerArgs = value
|
||||
} else {
|
||||
options.freeCompilerArgs.set(value)
|
||||
}
|
||||
|
||||
private val isTaskExecuting: Boolean
|
||||
get() = task().state.executing
|
||||
}
|
||||
Reference in New Issue
Block a user