[Gradle] Replace project with GradleExecutionContext in KotlinToolRunner

Gradle Project cannot be used during Task Execution Phase with enabled
Configuration Cache. This change allows to avoid using Project.

^KT-43293
This commit is contained in:
Anton Lakotka
2022-05-23 11:56:28 +02:00
committed by Space
parent ce72948a21
commit e8040fcf77
@@ -7,6 +7,12 @@ package org.jetbrains.kotlin.compilerRunner
import com.intellij.openapi.util.text.StringUtil.escapeStringCharacters
import org.gradle.api.Project
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.logging.Logger
import org.gradle.api.model.ObjectFactory
import org.gradle.process.ExecOperations
import org.gradle.process.ExecResult
import org.gradle.process.JavaExecSpec
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.konan.target.HostManager
import java.io.File
@@ -17,8 +23,41 @@ import java.util.concurrent.ConcurrentHashMap
// Note: this class is public because it is used in the K/N build infrastructure.
abstract class KotlinToolRunner(
val project: Project
private val executionContext: GradleExecutionContext
) {
/**
* Context Services that are required for [KotlinToolRunner] during Gradle Task Execution Phase
*/
class GradleExecutionContext(
val filesProvider: (Any) -> ConfigurableFileCollection,
val javaexec: ((JavaExecSpec) -> Unit) -> ExecResult,
val logger: Logger,
) {
companion object {
@Deprecated(
"Building execution context from Project object isn't compatible with Gradle Configuration Cache",
ReplaceWith("fromTaskContext()"),
DeprecationLevel.WARNING
)
fun fromProject(project: Project) = GradleExecutionContext(
filesProvider = project::files,
javaexec = project::javaexec,
logger = project.logger
)
/** Gradle Configuration Cache friendly context, should be used inside Task Execution Phase */
fun fromTaskContext(
objectFactory: ObjectFactory,
execOperations: ExecOperations,
logger: Logger
) = GradleExecutionContext(
filesProvider = objectFactory.fileCollection()::from,
javaexec = execOperations::javaexec,
logger = logger
)
}
}
// name that will be used in logs
abstract val displayName: String
@@ -84,7 +123,7 @@ abstract class KotlinToolRunner(
private fun runViaExec(args: List<String>) {
val transformedArgs = transformArgs(args)
val classpath = project.files(classpath)
val classpath = executionContext.filesProvider(classpath)
val systemProperties = System.getProperties()
/* Capture 'System.getProperties()' as List to avoid potential 'ConcurrentModificationException' */
.toListSynchronized()
@@ -94,7 +133,7 @@ abstract class KotlinToolRunner(
.escapeQuotesForWindows()
.toMap() + execSystemProperties
project.logger.info(
executionContext.logger.info(
"""|Run "$displayName" tool in a separate JVM process
|Main class = $mainClass
|Arguments = ${args.toPrettyString()}
@@ -107,7 +146,7 @@ abstract class KotlinToolRunner(
""".trimMargin()
)
project.javaexec { spec ->
executionContext.javaexec { spec ->
@Suppress("DEPRECATION")
if (GradleVersion.current() >= GradleVersion.version("7.0")) spec.mainClass.set(mainClass)
else spec.main = mainClass
@@ -124,7 +163,7 @@ abstract class KotlinToolRunner(
val transformedArgs = transformArgs(args)
val isolatedClassLoader = getIsolatedClassLoader()
project.logger.info(
executionContext.logger.info(
"""|Run in-process tool "$displayName"
|Entry point method = $mainClass.$daemonEntryPoint
|Classpath = ${isolatedClassLoader.urLs.map { it.file }.toPrettyString()}