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:
Dmitriy Dolovov
2020-11-02 17:32:23 +03:00
parent 734dff6282
commit fae3ba35e9
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.compilerRunner
import com.intellij.openapi.util.text.StringUtil.escapeStringCharacters
import org.gradle.api.Project
import org.jetbrains.kotlin.konan.target.HostManager
import java.io.File
@@ -67,37 +68,58 @@ internal abstract class KotlinToolRunner(
}
fun run(args: List<String>) {
project.logger.info("Run tool: \"$displayName\" with args: ${args.joinToString(separator = " ")}")
checkClasspath()
if (mustRunViaExec) runViaExec(args) else runInProcess(args)
}
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 ->
spec.main = mainClass
spec.classpath = project.files(classpath)
spec.classpath = classpath
spec.jvmArgs(jvmArgs)
spec.systemProperties(
System.getProperties().asSequence()
.map { (k, v) -> k.toString() to v.toString() }
.filter { (k, _) -> k !in execSystemPropertiesBlacklist }
.escapeQuotesForWindows()
.toMap()
)
spec.systemProperties(execSystemProperties)
spec.systemProperties(systemProperties)
execEnvironmentBlacklist.forEach { spec.environment.remove(it) }
spec.environment(execEnvironment)
spec.args(transformArgs(args))
spec.args(transformedArgs)
}
}
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 {
val mainClass = getIsolatedClassLoader().loadClass(mainClass)
val entryPoint = mainClass.methods.single { it.name == daemonEntryPoint }
entryPoint.invoke(null, transformArgs(args).toTypedArray())
entryPoint.invoke(null, transformedArgs.toTypedArray())
} catch (t: InvocationTargetException) {
throw t.targetException
}
@@ -110,5 +132,24 @@ internal abstract class KotlinToolRunner(
if (HostManager.hostIsMingw) map { (key, value) -> key.escapeQuotes() to value.escapeQuotes() } else this
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 }
}
}