diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/exec.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/exec.kt index 9b6e690ac57..46582ad3571 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/exec.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/exec.kt @@ -1,6 +1,6 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the license/LICENSE.txt file. + * 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.internal @@ -10,6 +10,8 @@ import org.gradle.api.internal.project.ProjectInternal import org.gradle.process.ExecResult import org.gradle.process.internal.ExecAction import org.gradle.process.internal.ExecActionFactory +import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessageOutputStreamHandler +import org.jetbrains.kotlin.gradle.targets.js.TeamCityMessageCommonClient import java.io.ByteArrayOutputStream import java.io.PipedInputStream import java.io.PipedOutputStream @@ -64,4 +66,34 @@ internal fun Project.execWithProgress(description: String, readStdErr: Boolean = } result } +} + +internal fun Project.execWithErrorLogger(description: String, body: (ExecAction) -> Unit): ExecResult { + this as ProjectInternal + + val exec = services.get(ExecActionFactory::class.java).newExecAction() + body(exec) + return project!!.operation(description) { + progress(description) + exec.standardOutput = TCServiceMessageOutputStreamHandler( + client = TeamCityMessageCommonClient(logger, this), + onException = { }, + logger = logger + ) + exec.errorOutput = TCServiceMessageOutputStreamHandler( + client = TeamCityMessageCommonClient(logger, this), + onException = { }, + logger = logger + ) + exec.isIgnoreExitValue = true + val result = exec.execute() + if (result.exitValue != 0) { + error( + """ + Process '$description' returns ${result.exitValue} + """.trimIndent() + ) + } + result + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/TeamCityMessageCommonClient.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/TeamCityMessageCommonClient.kt new file mode 100644 index 00000000000..211801f30d4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/TeamCityMessageCommonClient.kt @@ -0,0 +1,39 @@ +/* + * 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.targets.js + +import jetbrains.buildServer.messages.serviceMessages.Message +import jetbrains.buildServer.messages.serviceMessages.ServiceMessage +import jetbrains.buildServer.messages.serviceMessages.ServiceMessageParserCallback +import org.gradle.api.logging.Logger +import org.gradle.internal.logging.progress.ProgressLogger +import java.text.ParseException + +class TeamCityMessageCommonClient( + private val log: Logger, + private val progressLogger: ProgressLogger +) : ServiceMessageParserCallback { + override fun parseException(e: ParseException, text: String) { + log.error("Failed to parse test process messages: \"$text\"", e) + } + + override fun serviceMessage(message: ServiceMessage) { + when (message) { + is Message -> printMessage(message.text, message.attributes["type"]) + } + } + + private fun printMessage(text: String, type: String?) { + val value = text.trimEnd() + progressLogger.progress(value) + + type?.let { log.processLogMessage(value, it) } + } + + override fun regularText(text: String) { + printMessage(text, null) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackConfig.kt index 366946cf322..db0d5740b7a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackConfig.kt @@ -1,6 +1,6 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the license/LICENSE.txt file. + * 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. */ @file:Suppress("NodeJsCodingAssistanceForCoreModules", "JSUnresolvedFunction") @@ -41,6 +41,7 @@ data class KotlinWebpackConfig( ) { fun getRequiredDependencies(versions: NpmVersions) = mutableListOf().also { + it.add(versions.kotlinJsTestRunner) it.add(versions.webpack) it.add(versions.webpackCli) @@ -131,6 +132,7 @@ data class KotlinWebpackConfig( appendReport() appendProgressReporter() appendCssSettings() + appendErrorPlugin() appendFromConfigDir() appendEvaluatedFileReport() @@ -357,6 +359,19 @@ data class KotlinWebpackConfig( ) } + private fun Appendable.appendErrorPlugin() { + //language=ES6 + appendln( + """ + // noinspection JSUnnecessarySemicolon + ;(function(config) { + const tcErrorPlugin = require('kotlin-test-js-runner/tc-log-error-webpack'); + config.plugins.push(new tcErrorPlugin(tcErrorPlugin)) + })(config); + """.trimIndent() + ) + } + private fun Appendable.appendResolveModules() { if (!resolveFromModulesFirst || entry == null || entry.parent == null) return diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackRunner.kt index a9970459e56..42e396a8a59 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackRunner.kt @@ -1,6 +1,6 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the license/LICENSE.txt file. + * 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.targets.js.webpack @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.gradle.targets.js.webpack import org.gradle.process.ExecSpec import org.gradle.process.internal.ExecHandle import org.gradle.process.internal.ExecHandleFactory -import org.jetbrains.kotlin.gradle.internal.execWithProgress +import org.jetbrains.kotlin.gradle.internal.execWithErrorLogger import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject import java.io.File @@ -19,7 +19,7 @@ internal data class KotlinWebpackRunner( val tool: String, val config: KotlinWebpackConfig ) { - fun execute() = npmProject.project.execWithProgress("webpack") { + fun execute() = npmProject.project.execWithErrorLogger("webpack") { configureExec(it) }