Gradle IT: Intercept and log Gradle process output on import failures

This commit is contained in:
Dmitriy Dolovov
2020-11-03 01:02:34 +03:00
parent 4de1bf8d35
commit 0dd329d3d4
2 changed files with 33 additions and 8 deletions
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.gradle
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.*
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiReference
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.runInEdtAndGet
import org.jetbrains.kotlin.idea.codeInsight.gradle.MasterPluginVersionGradleImportingTestCase
@@ -23,7 +25,7 @@ class ImportAndCheckNavigation : MasterPluginVersionGradleImportingTestCase() {
@Test
@PluginTargetVersions(gradleVersion = "6.0+", pluginVersion = "1.4+", gradleVersionForLatestPlugin = mppImportTestMinVersionForMaster)
fun testNavigationToCommonizedLibrary() {
val files = configureAndImportProject()
val files = importProjectFromTestData()
files.forEach { vFile ->
val referencesToTest = vFile.collectReferencesToTest()
@@ -48,12 +50,6 @@ class ImportAndCheckNavigation : MasterPluginVersionGradleImportingTestCase() {
override fun testDataDirName() = "importAndCheckNavigation"
private fun configureAndImportProject(): List<VirtualFile> {
val files = configureByFiles()
importProject()
return files
}
private fun VirtualFile.collectReferencesToTest(): Map<PsiReference, String> {
if (extension != "kt") return emptyMap()
@@ -54,6 +54,7 @@ import org.gradle.wrapper.GradleWrapperMain
import org.gradle.wrapper.PathAssembler
import org.intellij.lang.annotations.Language
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.idea.test.GradleProcessOutputInterceptor
import org.jetbrains.kotlin.idea.test.KotlinSdkCreationChecker
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe
@@ -162,6 +163,8 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
"${jvmHeapArgsByGradleVersion(gradleVersion)} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${System.getProperty("user.dir")}"
sdkCreationChecker = KotlinSdkCreationChecker()
GradleProcessOutputInterceptor.install(testRootDisposable)
}
override fun tearDown() {
@@ -243,6 +246,32 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
super.importProject(config)
}
override fun handleImportFailure(errorMessage: String, errorDetails: String?) {
val gradleOutput = GradleProcessOutputInterceptor.getInstance()?.getOutput().orEmpty()
// Typically Gradle error message consists of a line with the description of the error followed by
// a multi-line stacktrace. The idea is to cut off the stacktrace if it is already contained in
// the intercepted Gradle process output to avoid unnecessary verbosity.
val compactErrorMessage = when (val indexOfNewLine = errorMessage.indexOf('\n')) {
-1 -> errorMessage
else -> {
val compactErrorMessage = errorMessage.substring(0, indexOfNewLine)
val theRest = errorMessage.substring(indexOfNewLine + 1)
if (theRest in gradleOutput) compactErrorMessage else errorMessage
}
}
val failureMessage = buildString {
append("Gradle import failed: ").append(compactErrorMessage).append('\n')
if (!errorDetails.isNullOrBlank()) append("Error details: ").append(errorDetails).append('\n')
append("Gradle process output (BEGIN):\n")
append(gradleOutput)
if (!gradleOutput.endsWith('\n')) append('\n')
append("Gradle process output (END)")
}
fail(failureMessage)
}
protected open fun injectRepo(@NonNls @Language("Groovy") config: String?): String {
var config = config ?: ""
config = """allprojects {