Do not push back more output lines then has been read by BuildOutputParser IDEA-209816

This commit is contained in:
Vladislav.Soroka
2019-04-12 18:21:56 +03:00
parent e8c6f169af
commit fbef901fa5
5 changed files with 65 additions and 51 deletions
@@ -4,14 +4,11 @@ package com.intellij.build.output;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.io.Closeable;
import java.io.IOException;
/**
* @author Vladislav.Soroka
*/
@ApiStatus.Experimental
public interface BuildOutputInstantReader extends Closeable, Appendable {
public interface BuildOutputInstantReader {
Object getBuildId();
@Nullable
@@ -21,25 +18,8 @@ public interface BuildOutputInstantReader extends Closeable, Appendable {
/***
* Push back the given number of lines.
* @param numberOfLines
*/
void pushBack(int numberOfLines);
String getCurrentLine();
/*
redefine below methods without exceptions
*/
@Override
BuildOutputInstantReader append(CharSequence csq);
@Override
BuildOutputInstantReader append(CharSequence csq, int start, int end);
@Override
BuildOutputInstantReader append(char c);
@Override
void close();
}
@@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.io.Closeable;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
@@ -21,7 +22,7 @@ import java.util.function.Consumer;
/**
* @author Vladislav.Soroka
*/
public class BuildOutputInstantReaderImpl implements BuildOutputInstantReader {
public class BuildOutputInstantReaderImpl implements BuildOutputInstantReader, Closeable, Appendable {
private static final Logger LOG = Logger.getInstance("#com.intellij.build.output.BuildOutputInstantReader");
private static final int MAX_LINES_BUFFER_SIZE = 50;
@@ -58,7 +59,7 @@ public class BuildOutputInstantReaderImpl implements BuildOutputInstantReader {
continue;
}
for (BuildOutputParser parser : parsers) {
if (parser.parse(line, this, messageConsumer)) {
if (parser.parse(line, new BuildOutputInstantReaderWrapper(this), messageConsumer)) {
break;
}
}
@@ -72,7 +73,7 @@ public class BuildOutputInstantReaderImpl implements BuildOutputInstantReader {
}
@Override
public BuildOutputInstantReader append(CharSequence csq) {
public BuildOutputInstantReaderImpl append(CharSequence csq) {
for (int i = 0; i < csq.length(); i++) {
append(csq.charAt(i));
}
@@ -80,13 +81,13 @@ public class BuildOutputInstantReaderImpl implements BuildOutputInstantReader {
}
@Override
public BuildOutputInstantReader append(CharSequence csq, int start, int end) {
public BuildOutputInstantReaderImpl append(CharSequence csq, int start, int end) {
append(csq.subSequence(start, end));
return this;
}
@Override
public BuildOutputInstantReader append(char c) {
public BuildOutputInstantReaderImpl append(char c) {
if (myBuffer == null) {
myBuffer = new StringBuilder();
}
@@ -139,6 +140,10 @@ public class BuildOutputInstantReaderImpl implements BuildOutputInstantReader {
@Nullable
@Override
public String readLine() {
if (myCurrentIndex < -1) {
LOG.error("Wrong buffered output lines index");
myCurrentIndex = -1;
}
if (myClosed.get()) {
if (myCurrentIndex > 0 && myLinesBuffer.size() > myCurrentIndex) {
return myLinesBuffer.get(myCurrentIndex++);
@@ -181,7 +186,7 @@ public class BuildOutputInstantReaderImpl implements BuildOutputInstantReader {
@Override
public String getCurrentLine() {
return myLinesBuffer.size() > myCurrentIndex ? myLinesBuffer.get(myCurrentIndex) : null;
return myCurrentIndex >= 0 && myLinesBuffer.size() > myCurrentIndex ? myLinesBuffer.get(myCurrentIndex) : null;
}
@ApiStatus.Experimental
@@ -189,4 +194,42 @@ public class BuildOutputInstantReaderImpl implements BuildOutputInstantReader {
static int getMaxLinesBufferSize() {
return MAX_LINES_BUFFER_SIZE;
}
private static class BuildOutputInstantReaderWrapper implements BuildOutputInstantReader {
private final BuildOutputInstantReaderImpl myReader;
private int myLinesRead = 0;
public BuildOutputInstantReaderWrapper(@NotNull BuildOutputInstantReaderImpl reader) {myReader = reader;}
@Override
public Object getBuildId() {
return myReader.myBuildId;
}
@Nullable
@Override
public String readLine() {
String line = myReader.readLine();
if (line != null) myLinesRead++;
return line;
}
@Override
public void pushBack() {
pushBack(1);
}
@Override
public void pushBack(int numberOfLines) {
if (numberOfLines > myLinesRead) {
numberOfLines = myLinesRead;
}
myReader.pushBack(numberOfLines);
}
@Override
public String getCurrentLine() {
return myReader.getCurrentLine();
}
}
}
@@ -29,7 +29,6 @@ class BuildOutputInstantReaderImplTest {
}
reader.pushBack(count)
return@BuildOutputParser false
}
doTest(mutableListOf(
@@ -39,6 +38,20 @@ class BuildOutputInstantReaderImplTest {
createParser("[warning]", WARNING)))
}
@Test
fun `test bad parser pushed back too many lines`() {
val badParser = BuildOutputParser { _, reader, _ ->
reader.pushBack(getMaxLinesBufferSize() * 2)
return@BuildOutputParser false
}
doTest(mutableListOf(
createParser("[info]", INFO),
badParser,
createParser("[error]", ERROR),
createParser("[warning]", WARNING)))
}
private fun doTest(parsers: MutableList<BuildOutputParser>) {
val messages = mutableListOf<String>()
@@ -32,7 +32,7 @@ import java.util.Collections;
public class MavenBuildEventProcessor implements AnsiEscapeDecoder.ColoredTextAcceptor {
@NotNull private final BuildProgressListener myBuildProgressListener;
@NotNull private final Project myProject;
@NotNull private final BuildOutputInstantReader myInstantReader;
@NotNull private final BuildOutputInstantReaderImpl myInstantReader;
@NotNull private final ExternalSystemTaskId myTaskId;
@NotNull private final String myWorkingDir;
@NotNull private final MavenLogOutputParser myParser;
@@ -27,7 +27,6 @@ import java.util.function.Function;
import static com.intellij.build.events.MessageEvent.Kind.WARNING;
import static com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType.EXECUTE_TASK;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
public abstract class MavenBuildToolLogTestUtils extends UsefulTestCase {
@@ -256,26 +255,5 @@ public abstract class MavenBuildToolLogTestUtils extends UsefulTestCase {
}
return myLines.get(myPosition);
}
@Override
public BuildOutputInstantReader append(CharSequence csq) {
throw new UnsupportedOperationException();
}
@Override
public BuildOutputInstantReader append(CharSequence csq, int start, int end) {
throw new UnsupportedOperationException();
}
@Override
public BuildOutputInstantReader append(char c) {
throw new UnsupportedOperationException();
}
@Override
public void close() {
}
}
}