use gradle execOperation and set args in file
This commit is contained in:
+13
-3
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.report.BuildReportMode
|
||||
import org.jetbrains.kotlin.gradle.report.TaskExecutionResult
|
||||
import org.jetbrains.kotlin.gradle.tasks.clearLocalState
|
||||
import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError
|
||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
||||
import org.jetbrains.kotlin.gradle.utils.stackTraceAsString
|
||||
import org.jetbrains.kotlin.incremental.ChangedFiles
|
||||
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
|
||||
@@ -32,12 +33,14 @@ import javax.inject.Inject
|
||||
internal class ProjectFilesForCompilation(
|
||||
val projectRootFile: File,
|
||||
val clientIsAliveFlagFile: File,
|
||||
val sessionFlagFile: File
|
||||
val sessionFlagFile: File,
|
||||
val project: Project
|
||||
) : Serializable {
|
||||
constructor(project: Project) : this(
|
||||
projectRootFile = project.rootProject.projectDir,
|
||||
clientIsAliveFlagFile = GradleCompilerRunner.getOrCreateClientFlagFile(project),
|
||||
sessionFlagFile = GradleCompilerRunner.getOrCreateSessionFlagFile(project)
|
||||
sessionFlagFile = GradleCompilerRunner.getOrCreateSessionFlagFile(project),
|
||||
project = project
|
||||
)
|
||||
|
||||
companion object {
|
||||
@@ -97,6 +100,7 @@ internal class GradleKotlinCompilerWork @Inject constructor(
|
||||
private val buildReportMode = config.buildReportMode
|
||||
private val kotlinScriptExtensions = config.kotlinScriptExtensions
|
||||
private val allWarningsAsErrors = config.allWarningsAsErrors
|
||||
private val project = config.projectFiles.project
|
||||
|
||||
private val log: KotlinLogger =
|
||||
TaskLoggers.get(taskPath)?.let { GradleKotlinLogger(it).apply { debug("Using '$taskPath' logger") } }
|
||||
@@ -297,7 +301,13 @@ internal class GradleKotlinCompilerWork @Inject constructor(
|
||||
clearLocalState(outputFiles, log, reason = "out-of-process execution strategy is non-incremental")
|
||||
|
||||
return try {
|
||||
runToolInSeparateProcess(compilerArgs, compilerClassName, compilerFullClasspath, log)
|
||||
if (isGradleVersionAtLeast(6, 0)) {
|
||||
val execResult =
|
||||
runToolInSeparateProcessForGradle6AndMore(compilerArgs, compilerClassName, compilerFullClasspath, project)
|
||||
exitCodeFromProcessExitCode(log, execResult.exitValue)
|
||||
} else {
|
||||
runToolInSeparateProcess(compilerArgs, compilerClassName, compilerFullClasspath, log, project.buildDir)
|
||||
}
|
||||
} finally {
|
||||
reportExecutionResultIfNeeded {
|
||||
TaskExecutionResult(
|
||||
|
||||
+45
-10
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.compilerRunner
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.process.ExecResult
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
@@ -25,11 +27,14 @@ import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
||||
import org.jetbrains.kotlin.daemon.client.DaemonReportingTargets
|
||||
import org.jetbrains.kotlin.daemon.client.launchProcessWithFallback
|
||||
import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger
|
||||
import org.jetbrains.kotlin.gradle.tasks.internal.GradleExecOperationsHolder
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import java.io.File
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.zip.ZipFile
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
@@ -37,14 +42,17 @@ internal fun loadCompilerVersion(compilerClasspath: List<File>): String {
|
||||
var result: String? = null
|
||||
|
||||
fun checkVersion(bytes: ByteArray) {
|
||||
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
|
||||
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor {
|
||||
if (name == KotlinCompilerVersion::VERSION.name && value is String) {
|
||||
result = value
|
||||
ClassReader(bytes).accept(
|
||||
object : ClassVisitor(Opcodes.API_VERSION) {
|
||||
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor {
|
||||
if (name == KotlinCompilerVersion::VERSION.name && value is String) {
|
||||
result = value
|
||||
}
|
||||
return super.visitField(access, name, desc, signature, value)
|
||||
}
|
||||
return super.visitField(access, name, desc, signature, value)
|
||||
}
|
||||
}, ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES or ClassReader.SKIP_DEBUG)
|
||||
},
|
||||
ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES or ClassReader.SKIP_DEBUG
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -78,15 +86,34 @@ internal fun loadCompilerVersion(compilerClasspath: List<File>): String {
|
||||
return result ?: "<unknown>"
|
||||
}
|
||||
|
||||
internal fun runToolInSeparateProcessForGradle6AndMore(
|
||||
argsArray: Array<String>,
|
||||
compilerClassName: String,
|
||||
classpath: List<File>,
|
||||
project: Project
|
||||
): ExecResult {
|
||||
val gradleExecutionOperation = project.objects.newInstance(GradleExecOperationsHolder::class.java)
|
||||
val compilationArguments = writeArgumentsToFile(project.buildDir, argsArray)
|
||||
return gradleExecutionOperation.execOperation.javaexec {
|
||||
it.classpath = project.files(classpath)
|
||||
it.args = listOf("@${compilationArguments.absolutePath}")
|
||||
it.main = compilerClassName
|
||||
}
|
||||
}
|
||||
|
||||
internal fun runToolInSeparateProcess(
|
||||
argsArray: Array<String>,
|
||||
compilerClassName: String,
|
||||
classpath: List<File>,
|
||||
logger: KotlinLogger
|
||||
logger: KotlinLogger,
|
||||
buildDir: File
|
||||
): ExitCode {
|
||||
val javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"
|
||||
val classpathString = classpath.map { it.absolutePath }.joinToString(separator = File.pathSeparator)
|
||||
val builder = ProcessBuilder(javaBin, "-cp", classpathString, compilerClassName, *argsArray)
|
||||
|
||||
val compilerOptions = writeArgumentsToFile(buildDir, argsArray)
|
||||
|
||||
val builder = ProcessBuilder(javaBin, "-cp", classpathString, compilerClassName, "@${compilerOptions.absolutePath}")
|
||||
val messageCollector = createLoggingMessageCollector(logger)
|
||||
val process = launchProcessWithFallback(builder, DaemonReportingTargets(messageCollector = messageCollector))
|
||||
|
||||
@@ -114,6 +141,13 @@ internal fun runToolInSeparateProcess(
|
||||
return exitCodeFromProcessExitCode(logger, exitCode)
|
||||
}
|
||||
|
||||
private fun writeArgumentsToFile(directory: File, argsArray: Array<String>): File {
|
||||
val compilerOptions = File.createTempFile(LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE) + "_", ".compiler.options", directory)
|
||||
compilerOptions.deleteOnExit()
|
||||
compilerOptions.writeText(argsArray.joinToString(" "))
|
||||
return compilerOptions
|
||||
}
|
||||
|
||||
private fun createLoggingMessageCollector(log: KotlinLogger): MessageCollector = object : MessageCollector {
|
||||
private var hasErrors = false
|
||||
private val messageRenderer = MessageRenderer.PLAIN_FULL_PATHS
|
||||
@@ -131,7 +165,8 @@ private fun createLoggingMessageCollector(log: KotlinLogger): MessageCollector =
|
||||
CompilerMessageSeverity.ERROR,
|
||||
CompilerMessageSeverity.STRONG_WARNING,
|
||||
CompilerMessageSeverity.WARNING,
|
||||
CompilerMessageSeverity.INFO -> log.info(locMessage)
|
||||
CompilerMessageSeverity.INFO
|
||||
-> log.info(locMessage)
|
||||
CompilerMessageSeverity.LOGGING -> log.debug(locMessage)
|
||||
CompilerMessageSeverity.OUTPUT -> {
|
||||
}
|
||||
|
||||
+20
-5
@@ -26,11 +26,13 @@ import org.gradle.api.tasks.TaskAction
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSDceArguments
|
||||
import org.jetbrains.kotlin.cli.js.dce.K2JSDce
|
||||
import org.jetbrains.kotlin.compilerRunner.runToolInSeparateProcess
|
||||
import org.jetbrains.kotlin.compilerRunner.runToolInSeparateProcessForGradle6AndMore
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJsDce
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJsDceOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJsDceOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger
|
||||
import org.jetbrains.kotlin.gradle.utils.canonicalPathWithoutExtension
|
||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
||||
import java.io.File
|
||||
|
||||
@CacheableTask
|
||||
@@ -82,11 +84,24 @@ open class KotlinJsDce : AbstractKotlinCompileTool<K2JSDceArguments>(), KotlinJs
|
||||
|
||||
val log = GradleKotlinLogger(logger)
|
||||
val allArgs = argsArray + outputDirArgs + inputFiles
|
||||
val exitCode = runToolInSeparateProcess(
|
||||
allArgs, K2JSDce::class.java.name, computedCompilerClasspath,
|
||||
log
|
||||
)
|
||||
throwGradleExceptionIfError(exitCode)
|
||||
|
||||
if (isGradleVersionAtLeast(6,0)) {
|
||||
runToolInSeparateProcessForGradle6AndMore(
|
||||
allArgs,
|
||||
K2JSDce::class.java.name,
|
||||
computedCompilerClasspath,
|
||||
project
|
||||
).rethrowFailure()
|
||||
} else {
|
||||
val exitCode = runToolInSeparateProcess(
|
||||
allArgs,
|
||||
K2JSDce::class.java.name,
|
||||
computedCompilerClasspath,
|
||||
log,
|
||||
project.buildDir
|
||||
)
|
||||
throwGradleExceptionIfError(exitCode)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isDceCandidate(file: File): Boolean {
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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.tasks.internal
|
||||
|
||||
import javax.inject.Inject
|
||||
import org.gradle.process.ExecOperations
|
||||
|
||||
/**
|
||||
* Available since Gradle 6.0
|
||||
*/
|
||||
open class GradleExecOperationsHolder @Inject constructor(val execOperation: ExecOperations) {
|
||||
}
|
||||
Reference in New Issue
Block a user