[Gradle, JS] LogType on Enum

#KT-38109 fixed
#KT-38286 fixed
This commit is contained in:
Ilya Goncharov
2020-04-15 11:19:13 +03:00
parent fa4003bac5
commit 5969f1dd4d
6 changed files with 55 additions and 41 deletions
@@ -15,6 +15,7 @@ import org.gradle.api.tasks.testing.TestResult.ResultType.*
import org.gradle.internal.operations.OperationIdentifier import org.gradle.internal.operations.OperationIdentifier
import org.gradle.process.internal.ExecHandle import org.gradle.process.internal.ExecHandle
import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.targets.js.LogType
import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure import org.jetbrains.kotlin.gradle.testing.KotlinTestFailure
import org.slf4j.Logger import org.slf4j.Logger
import java.text.ParseException import java.text.ParseException
@@ -85,7 +86,7 @@ internal open class TCServiceMessagesClient(
} }
} }
is TestSuiteFinished -> close(message.ts, getSuiteName(message)) is TestSuiteFinished -> close(message.ts, getSuiteName(message))
is Message -> printNonTestOutput(message.text, message.attributes["type"]) is Message -> printNonTestOutput(message.text, LogType.byValueOrNull(message.attributes["type"]))
else -> Unit else -> Unit
} }
@@ -115,7 +116,7 @@ internal open class TCServiceMessagesClient(
afterMessage = false afterMessage = false
} }
protected open fun printNonTestOutput(text: String, type: String? = null) { protected open fun printNonTestOutput(text: String, type: LogType? = null) {
print(text) print(text)
} }
@@ -28,7 +28,7 @@ class TeamCityMessageCommonClient(
override fun serviceMessage(message: ServiceMessage) { override fun serviceMessage(message: ServiceMessage) {
when (message) { when (message) {
is Message -> printMessage(message.text, message.attributes["type"]) is Message -> printMessage(message.text, LogType.byValueOrNull(message.attributes["type"]))
} }
} }
@@ -37,23 +37,22 @@ class TeamCityMessageCommonClient(
.joinToString("\n") .joinToString("\n")
} }
private fun printMessage(text: String, type: String?) { private fun printMessage(text: String, type: LogType?) {
val value = text.trimEnd() val value = text.trimEnd()
progressLogger.progress(value) progressLogger.progress(value)
var actualType = type val inStackTrace = stackTraceProcessor.process(text) { line, logType ->
stackTraceProcessor.process(text) { line -> log.processLogMessage(line, logType)
actualType = ERROR errors.add(line.clearAnsiColor())
if (line != null) {
printMessage(line, actualType)
}
} }
when (actualType) { if (inStackTrace) return
ERROR, WARN -> errors.add(value.clearAnsiColor())
when (type) {
LogType.ERROR, LogType.WARN -> errors.add(value.clearAnsiColor())
} }
actualType?.let { log.processLogMessage(value, it) } type?.let { log.processLogMessage(value, it) }
} }
override fun regularText(text: String) { override fun regularText(text: String) {
@@ -8,14 +8,17 @@ package org.jetbrains.kotlin.gradle.targets.js
internal class TeamCityMessageStackTraceProcessor { internal class TeamCityMessageStackTraceProcessor {
private var firstLine: String? = null private var firstLine: String? = null
fun process(text: String, firstLineAction: (String?) -> Unit) { fun process(text: String, action: (String, LogType) -> Unit): Boolean {
firstLine = if (text.trim().startsWith("at ")) { return if (text.trim().startsWith("at ")) {
// firstLineAction can have side effects firstLine?.let {
// that's why important to call it even with null line action(it, LogType.ERROR)
firstLineAction(firstLine) }
null firstLine = null
action(text, LogType.ERROR)
true
} else { } else {
text firstLine = text
false
} }
} }
} }
@@ -11,7 +11,7 @@ import org.slf4j.Logger as SlfLogger
internal fun SlfLogger.processLogMessage( internal fun SlfLogger.processLogMessage(
message: String, message: String,
type: String type: LogType
) { ) {
processLogMessageInternal( processLogMessageInternal(
message = message, message = message,
@@ -26,7 +26,7 @@ internal fun SlfLogger.processLogMessage(
internal fun GradleLogger.processLogMessage( internal fun GradleLogger.processLogMessage(
message: String, message: String,
type: String type: LogType
) { ) {
processLogMessageInternal( processLogMessageInternal(
message = message, message = message,
@@ -40,27 +40,36 @@ internal fun GradleLogger.processLogMessage(
private fun processLogMessageInternal( private fun processLogMessageInternal(
message: String, message: String,
type: String, type: LogType,
error: (text: String) -> Unit, error: (text: String) -> Unit,
warn: (text: String) -> Unit, warn: (text: String) -> Unit,
info: (text: String) -> Unit, info: (text: String) -> Unit,
debug: (text: String) -> Unit debug: (text: String) -> Unit
) { ) {
val nonColoredMessage = message.clearAnsiColor() val nonColoredMessage = message.clearAnsiColor()
when (type.toLowerCase()) { when (type) {
WARN -> { LogType.WARN -> {
warn(nonColoredMessage) warn(nonColoredMessage)
} }
ERROR -> { LogType.ERROR -> {
error(nonColoredMessage) error(nonColoredMessage)
} }
INFO, LOG -> info(nonColoredMessage) LogType.INFO, LogType.LOG -> info(nonColoredMessage)
DEBUG -> debug(nonColoredMessage) LogType.DEBUG -> debug(nonColoredMessage)
} }
} }
internal const val ERROR = "error" enum class LogType(val value: String) {
internal const val WARN = "warn" ERROR("error"),
internal const val INFO = "info" WARN("warn"),
internal const val DEBUG = "debug" INFO("info"),
internal const val LOG = "log" DEBUG("debug"),
LOG("log");
companion object {
fun byValueOrNull(value: String?): LogType? {
if (value == null) return null
return values().singleOrNull { it.value == value }
}
}
}
@@ -10,6 +10,7 @@ import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClient import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClient
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.targets.js.LogType
import org.slf4j.Logger import org.slf4j.Logger
internal open class JSServiceMessagesTestExecutionSpec( internal open class JSServiceMessagesTestExecutionSpec(
@@ -37,7 +38,7 @@ internal open class JSServiceMessagesClient(
settings: TCServiceMessagesClientSettings, settings: TCServiceMessagesClientSettings,
log: Logger log: Logger
) : TCServiceMessagesClient(results, settings, log) { ) : TCServiceMessagesClient(results, settings, log) {
override fun printNonTestOutput(text: String, type: String?) { override fun printNonTestOutput(text: String, type: LogType?) {
if (log.isDebugEnabled) { if (log.isDebugEnabled) {
log.debug(text) log.debug(text)
} }
@@ -430,28 +430,29 @@ class KotlinKarma(override val compilation: KotlinJsCompilation) :
private var stackTraceProcessor = TeamCityMessageStackTraceProcessor() private var stackTraceProcessor = TeamCityMessageStackTraceProcessor()
override fun printNonTestOutput(text: String, type: String?) { override fun printNonTestOutput(text: String, type: LogType?) {
val value = text.trimEnd() val value = text.trimEnd()
progressLogger.progress(value) progressLogger.progress(value)
parseConsole(value, type) parseConsole(value, type)
} }
private fun parseConsole(text: String, type: String?) { private fun parseConsole(text: String, type: LogType?) {
var actualType = type var actualType = type
stackTraceProcessor.process(text) { line -> val inStackTrace = stackTraceProcessor.process(text) { line, logType ->
actualType = ERROR log.processLogMessage(line, logType)
line?.let { parseConsole(it, actualType) }
} }
if (inStackTrace) return
val launcherMessage = KARMA_MESSAGE.matchEntire(text) val launcherMessage = KARMA_MESSAGE.matchEntire(text)
val actualText = if (launcherMessage != null) { val actualText = if (launcherMessage != null) {
val (logLevel, message) = launcherMessage.destructured val (logLevel, message) = launcherMessage.destructured
actualType = logLevel.toLowerCase() actualType = LogType.byValueOrNull(logLevel.toLowerCase())
when (actualType) { when (actualType) {
WARN, ERROR -> { LogType.WARN, LogType.ERROR -> {
processFailedBrowsers(text) processFailedBrowsers(text)
} }
} }