From d14f04de7d223379632f986b6b0ec55b8d02be05 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Mon, 27 Jan 2020 08:45:07 +0300 Subject: [PATCH] IDEA-230992 IDEA console stalls when Gradle asks user to accept terms of use GitOrigin-RevId: 31f4320b712cd960d9ff4985245c9ac9f9b5237d --- .../test/runner/GradleConsoleProperties.java | 5 ++ .../runner/GradleTestsExecutionConsole.java | 23 ++++++ ...eTestsExecutionConsoleOutputProcessor.java | 70 ++++++++++++++----- .../plugins/gradle/IJTestLogger.groovy | 4 +- 4 files changed, 81 insertions(+), 21 deletions(-) diff --git a/plugins/gradle/java/src/execution/test/runner/GradleConsoleProperties.java b/plugins/gradle/java/src/execution/test/runner/GradleConsoleProperties.java index 9c2bfd1dec66..8f5c2c21bf8b 100644 --- a/plugins/gradle/java/src/execution/test/runner/GradleConsoleProperties.java +++ b/plugins/gradle/java/src/execution/test/runner/GradleConsoleProperties.java @@ -74,6 +74,11 @@ public class GradleConsoleProperties extends SMTRunnerConsoleProperties { return GRADLE_TEST_LOCATOR; } + @Override + public boolean isEditable() { + return true; + } + @NotNull private ToggleBooleanProperty createShowInternalNodesAction(TestConsoleProperties target) { String text = GradleBundle.message("gradle.test.show.internal.nodes.action.name"); diff --git a/plugins/gradle/java/src/execution/test/runner/GradleTestsExecutionConsole.java b/plugins/gradle/java/src/execution/test/runner/GradleTestsExecutionConsole.java index f8ba099abffe..5a458db21c3d 100644 --- a/plugins/gradle/java/src/execution/test/runner/GradleTestsExecutionConsole.java +++ b/plugins/gradle/java/src/execution/test/runner/GradleTestsExecutionConsole.java @@ -6,7 +6,10 @@ import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.execution.testframework.sm.runner.SMTestLocator; import com.intellij.execution.testframework.sm.runner.SMTestProxy; import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerConsoleView; +import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; @@ -18,6 +21,7 @@ import java.util.Map; public class GradleTestsExecutionConsole extends SMTRunnerConsoleView implements BuildViewSettingsProvider { private final Map testsMap = new HashMap<>(); private final StringBuilder myBuffer = new StringBuilder(); + private boolean lastMessageWasEmptyLine; public GradleTestsExecutionConsole(TestConsoleProperties consoleProperties, @Nullable String splitterProperty) { super(consoleProperties, splitterProperty); @@ -45,4 +49,23 @@ public class GradleTestsExecutionConsole extends SMTRunnerConsoleView implements public boolean isExecutionViewHidden() { return Registry.is("build.view.side-by-side", true); } + + @Override + public void print(@NotNull String s, @NotNull ConsoleViewContentType contentType) { + if (isUnwantedEmptyLineCandidate(s)) return; + super.print(s, contentType); + } + + // IJ Gradle test runner xml events protocol produces many unwanted empty strings + // this is a workaround to avoid the trash in the console + private boolean isUnwantedEmptyLineCandidate(@NotNull String s) { + if (s.length() == 1 && StringUtil.isLineBreak(s.charAt(0))) { + if (lastMessageWasEmptyLine) return true; + lastMessageWasEmptyLine = true; + } + else { + lastMessageWasEmptyLine = false; + } + return false; + } } diff --git a/plugins/gradle/java/src/execution/test/runner/GradleTestsExecutionConsoleOutputProcessor.java b/plugins/gradle/java/src/execution/test/runner/GradleTestsExecutionConsoleOutputProcessor.java index c57f3a3c155e..8ed50a37fec7 100644 --- a/plugins/gradle/java/src/execution/test/runner/GradleTestsExecutionConsoleOutputProcessor.java +++ b/plugins/gradle/java/src/execution/test/runner/GradleTestsExecutionConsoleOutputProcessor.java @@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.execution.test.runner.events.*; /** @@ -27,30 +28,21 @@ import org.jetbrains.plugins.gradle.execution.test.runner.events.*; */ public class GradleTestsExecutionConsoleOutputProcessor { private static final Logger LOG = Logger.getInstance(GradleTestsExecutionConsoleOutputProcessor.class); + @SuppressWarnings("HardCodedStringLiteral") + private static final String LOG_EOL = ""; + @SuppressWarnings("HardCodedStringLiteral") + private static final String LOG_START = ""; + @SuppressWarnings("HardCodedStringLiteral") + private static final String LOG_END = ""; public static void onOutput(@NotNull GradleTestsExecutionConsole executionConsole, @NotNull String text, - @NotNull Key processOutputType) { - final StringBuilder consoleBuffer = executionConsole.getBuffer(); - if (StringUtil.endsWith(text, "\n")) { - consoleBuffer.append(StringUtil.trimEnd(text, "\n")).append('\n'); - return; - } - else { - consoleBuffer.append(text); - } - - String trimmedText = consoleBuffer.toString().trim(); - consoleBuffer.setLength(0); - - if (!StringUtil.startsWith(trimmedText, "") || !StringUtil.endsWith(trimmedText, "")) { - if (text.trim().isEmpty()) return; - executionConsole.print(text, ConsoleViewContentType.getConsoleViewType(processOutputType)); - return; - } + @NotNull Key processOutputType) { + String eventMessage = getEventMessage(executionConsole, text, processOutputType); + if (eventMessage == null) return; try { - final TestEventXmlView xml = new TestEventXPPXmlView(trimmedText); + final TestEventXmlView xml = new TestEventXPPXmlView(eventMessage); final TestEventType eventType = TestEventType.fromValue(xml.getTestEventType()); TestEvent testEvent = null; @@ -87,4 +79,44 @@ public class GradleTestsExecutionConsoleOutputProcessor { LOG.error("Gradle test events parser error", e); } } + + @Nullable + private static String getEventMessage(@NotNull GradleTestsExecutionConsole executionConsole, + @NotNull String text, + @NotNull Key processOutputType) { + String eventMessage = null; + final StringBuilder consoleBuffer = executionConsole.getBuffer(); + String trimmedText = text.trim(); + if (StringUtil.endsWith(trimmedText, LOG_EOL)) { + consoleBuffer.append(StringUtil.trimEnd(trimmedText, LOG_EOL)); + return null; + } + else { + if (consoleBuffer.length() == 0) { + if (StringUtil.startsWith(trimmedText, LOG_START) && StringUtil.endsWith(trimmedText, LOG_END)) { + eventMessage = text; + } + else { + executionConsole.print(text, ConsoleViewContentType.getConsoleViewType(processOutputType)); + return null; + } + } + else { + consoleBuffer.append(text); + if (trimmedText.isEmpty()) return null; + } + } + + if (eventMessage == null) { + String bufferText = consoleBuffer.toString().trim(); + consoleBuffer.setLength(0); + if (!StringUtil.startsWith(bufferText, LOG_START) || !StringUtil.endsWith(bufferText, LOG_END)) { + executionConsole.print(bufferText, ConsoleViewContentType.getConsoleViewType(processOutputType)); + return null; + } + eventMessage = bufferText; + } + assert consoleBuffer.length() == 0; + return eventMessage; + } } diff --git a/plugins/gradle/resources/org/jetbrains/plugins/gradle/IJTestLogger.groovy b/plugins/gradle/resources/org/jetbrains/plugins/gradle/IJTestLogger.groovy index 202d2c4a1710..97a06f29b988 100644 --- a/plugins/gradle/resources/org/jetbrains/plugins/gradle/IJTestLogger.groovy +++ b/plugins/gradle/resources/org/jetbrains/plugins/gradle/IJTestLogger.groovy @@ -89,11 +89,11 @@ class IJTestEventLogger { static def wrap(String s) { if(!s) return s; - s.replaceAll("\r\n|\n\r|\n|\r","\n") + s.replaceAll("\r\n|\n\r|\n|\r","") } static def writeLog(s) { - println String.format("\n%s", wrap(s)) + println String.format("%s", wrap(s)) } static def logTestReportLocation(def report) {