Gradle, Native: More verbose logging in KotlinToolRunner
Especially for tools executed in a separate JVM process: JVM options, Java system properties, custom ENV variables.
This commit is contained in:
+53
-12
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.compilerRunner
|
package org.jetbrains.kotlin.compilerRunner
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.text.StringUtil.escapeStringCharacters
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -67,37 +68,58 @@ internal abstract class KotlinToolRunner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun run(args: List<String>) {
|
fun run(args: List<String>) {
|
||||||
project.logger.info("Run tool: \"$displayName\" with args: ${args.joinToString(separator = " ")}")
|
|
||||||
checkClasspath()
|
checkClasspath()
|
||||||
|
|
||||||
if (mustRunViaExec) runViaExec(args) else runInProcess(args)
|
if (mustRunViaExec) runViaExec(args) else runInProcess(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun runViaExec(args: List<String>) {
|
private fun runViaExec(args: List<String>) {
|
||||||
|
val transformedArgs = transformArgs(args)
|
||||||
|
val classpath = project.files(classpath)
|
||||||
|
val systemProperties = System.getProperties().asSequence()
|
||||||
|
.map { (k, v) -> k.toString() to v.toString() }
|
||||||
|
.filter { (k, _) -> k !in execSystemPropertiesBlacklist }
|
||||||
|
.escapeQuotesForWindows()
|
||||||
|
.toMap() + execSystemProperties
|
||||||
|
|
||||||
|
project.logger.info(
|
||||||
|
"""|Run "$displayName" tool in a separate JVM process
|
||||||
|
|Main class = $mainClass
|
||||||
|
|Arguments = ${transformedArgs.toPrettyString()}
|
||||||
|
|Classpath = ${classpath.files.map { it.absolutePath }.toPrettyString()}
|
||||||
|
|JVM options = ${jvmArgs.toPrettyString()}
|
||||||
|
|Java system properties = ${systemProperties.toPrettyString()}
|
||||||
|
|Suppressed ENV variables = ${execEnvironmentBlacklist.toPrettyString()}
|
||||||
|
|Custom ENV variables = ${execEnvironment.toPrettyString()}
|
||||||
|
""".trimMargin()
|
||||||
|
)
|
||||||
|
|
||||||
project.javaexec { spec ->
|
project.javaexec { spec ->
|
||||||
spec.main = mainClass
|
spec.main = mainClass
|
||||||
spec.classpath = project.files(classpath)
|
spec.classpath = classpath
|
||||||
spec.jvmArgs(jvmArgs)
|
spec.jvmArgs(jvmArgs)
|
||||||
spec.systemProperties(
|
spec.systemProperties(systemProperties)
|
||||||
System.getProperties().asSequence()
|
|
||||||
.map { (k, v) -> k.toString() to v.toString() }
|
|
||||||
.filter { (k, _) -> k !in execSystemPropertiesBlacklist }
|
|
||||||
.escapeQuotesForWindows()
|
|
||||||
.toMap()
|
|
||||||
)
|
|
||||||
spec.systemProperties(execSystemProperties)
|
|
||||||
execEnvironmentBlacklist.forEach { spec.environment.remove(it) }
|
execEnvironmentBlacklist.forEach { spec.environment.remove(it) }
|
||||||
spec.environment(execEnvironment)
|
spec.environment(execEnvironment)
|
||||||
spec.args(transformArgs(args))
|
spec.args(transformedArgs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun runInProcess(args: List<String>) {
|
private fun runInProcess(args: List<String>) {
|
||||||
|
val transformedArgs = transformArgs(args)
|
||||||
|
|
||||||
|
project.logger.info(
|
||||||
|
"""|Run in-process tool "$displayName"
|
||||||
|
|Entry point method = $mainClass.$daemonEntryPoint
|
||||||
|
|Arguments = ${transformedArgs.toPrettyString()}
|
||||||
|
""".trimMargin()
|
||||||
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val mainClass = getIsolatedClassLoader().loadClass(mainClass)
|
val mainClass = getIsolatedClassLoader().loadClass(mainClass)
|
||||||
val entryPoint = mainClass.methods.single { it.name == daemonEntryPoint }
|
val entryPoint = mainClass.methods.single { it.name == daemonEntryPoint }
|
||||||
|
|
||||||
entryPoint.invoke(null, transformArgs(args).toTypedArray())
|
entryPoint.invoke(null, transformedArgs.toTypedArray())
|
||||||
} catch (t: InvocationTargetException) {
|
} catch (t: InvocationTargetException) {
|
||||||
throw t.targetException
|
throw t.targetException
|
||||||
}
|
}
|
||||||
@@ -110,5 +132,24 @@ internal abstract class KotlinToolRunner(
|
|||||||
if (HostManager.hostIsMingw) map { (key, value) -> key.escapeQuotes() to value.escapeQuotes() } else this
|
if (HostManager.hostIsMingw) map { (key, value) -> key.escapeQuotes() to value.escapeQuotes() } else this
|
||||||
|
|
||||||
private val isolatedClassLoadersMap = ConcurrentHashMap<Any, ClassLoader>()
|
private val isolatedClassLoadersMap = ConcurrentHashMap<Any, ClassLoader>()
|
||||||
|
|
||||||
|
private fun Map<String, String>.toPrettyString(): String = buildString {
|
||||||
|
append('{')
|
||||||
|
if (this@toPrettyString.isNotEmpty()) append('\n')
|
||||||
|
this@toPrettyString.entries.forEach { (key, value) ->
|
||||||
|
append('\t').append(key).append(" = ").append(value.toPrettyString()).append('\n')
|
||||||
|
}
|
||||||
|
append('}')
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Collection<String>.toPrettyString(): String = buildString {
|
||||||
|
append('[')
|
||||||
|
if (this@toPrettyString.isNotEmpty()) append('\n')
|
||||||
|
this@toPrettyString.forEach { append('\t').append(it.toPrettyString()).append('\n') }
|
||||||
|
append(']')
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.toPrettyString(): String =
|
||||||
|
if (isEmpty()) "\"\"" else escapeStringCharacters(this).let { if (any(Char::isWhitespace)) "\"$it\"" else it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user