CmakeOutputParser implements BuildOutputParser { @Override public boolean parse(String line, BuildOutputInstantReader reader, Consumer<? super BuildEvent> messageConsumer) { if (cmakeErrorOrWarning.matcher(line).matches()) { List<String> messages = new ArrayList<>(); messages.add(line.trim()); String nextLine; while ((nextLine = reader.readLine()) != null) { if (nextLine.isEmpty() || cmakeErrorOrWarning.matcher(nextLine).matches()) { reader.pushBack(); break; } else { nextLine = nextLine.trim(); if (!nextLine.isEmpty()) { messages.add(nextLine); } } } if (matchesErrorFileAndLineNumberError(messages, reader.getParentEventId(), messageConsumer) || matchesFileAndLineNumberError(messages, reader.getParentEventId(), messageConsumer)) { return true; } if (messages.get(0).startsWith(CMAKE_ERROR)) { messageConsumer.accept( new MessageEventImpl(reader.getParentEventId(), MessageEvent.Kind.ERROR, CMAKE + MESSAGE_GROUP_ERROR_SUFFIX, String.join(" ", messages), String.join("\n", messages))); } else { messageConsumer.accept( new MessageEventImpl(reader.getParentEventId(), MessageEvent.Kind.WARNING, CMAKE + MESSAGE_GROUP_WARNING_SUFFIX, String.join(" ", messages), String.join("\n", messages))); } return true; } return false; }  @Override boolean parse(String line, BuildOutputInstantReader reader, Consumer<? super BuildEvent> messageConsumer);  }
@Test public void testMultilineCmakeWarningInFileWithoutLineNumberOrColumn() { String prefix = "CMake Warning: Warning in cmake code at\n"; String filePath = sourceFile.getAbsolutePath(); String fileAndLineNumber = String.format(Locale.getDefault(), "%s::\n", filePath); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake warnings", MessageEvent.Kind.WARNING, 0, 0); }
@Test public void testMultilineCmakeWarningInFileWithLineNumber() { String prefix = "CMake Warning: Warning in cmake code at\n"; int lineNumber = 13; String filePath = sourceFile.getAbsolutePath(); String fileAndLineNumber = String.format(Locale.getDefault(), "%s:%d:\n", filePath, lineNumber); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake warnings", MessageEvent.Kind.WARNING, lineNumber, 0); }
@Test public void testMultilineCmakeWarningInFileWithLineNumberAndColumnNumber() { String prefix = "CMake Warning: Warning in cmake code at\n"; int lineNumber = 13; int columnNumber = 42; String filePath = sourceFile.getAbsolutePath(); String fileAndLineNumber = String.format( Locale.getDefault(), "%s:%d:%d\n", filePath, lineNumber, columnNumber); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake warnings", MessageEvent.Kind.WARNING, lineNumber, columnNumber); }
@Test public void testMultilineCmakeErrorInFileWithoutLineNumberOrColumn() { String prefix = "CMake Error: Error in cmake code at\n"; String filePath = sourceFile.getAbsolutePath(); String fileAndLineNumber = String.format(Locale.getDefault(), "%s::\n", filePath); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake errors", MessageEvent.Kind.ERROR, 0, 0); }
@Test public void testMultilineCmakeErrorInFileWithLineNumber() { String prefix = "CMake Error: Error in cmake code at\n"; int lineNumber = 13; String filePath = sourceFile.getAbsolutePath(); String fileAndLineNumber = String.format(Locale.getDefault(), "%s:%d:\n", filePath, lineNumber); String warning = "CMake Warning: warning message\n"; String err = warning + prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer, times(2)).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(2); verifyMessageEvent(captor.getAllValues().get(0), MessageEvent.Kind.WARNING, "CMake warnings"); verifyFileMessageEvent(captor.getAllValues().get(1), filePath, "CMake errors", MessageEvent.Kind.ERROR, lineNumber, 0); }
@Test public void testMultilineCmakeErrorInFileWithLineNumberAndColumnNumber() { String prefix = "CMake Error: Error in cmake code at\n"; int lineNumber = 13; int columnNumber = 42; String filePath = sourceFile.getAbsolutePath(); String fileAndLineNumber = String.format( Locale.getDefault(), "%s:%d:%d\n", filePath, lineNumber, columnNumber); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake errors", MessageEvent.Kind.ERROR, lineNumber, columnNumber); }
@Test public void testSingleLineCmakeErrorInFileWithoutLineNumberOrColumn() { String prefix = "CMake Error: Error in cmake code at "; String filePath = sourceFile.getAbsolutePath(); String fileAndLineNumber = String.format(Locale.getDefault(), "%s::\n", filePath); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake errors", MessageEvent.Kind.ERROR, 0, 0); }
@Test public void testSingleLineCmakeErrorInFileWithLineNumber() { String prefix = "CMake Error: Error in cmake code at "; String filePath = sourceFile.getAbsolutePath(); int lineNumber = 13; String fileAndLineNumber = String.format(Locale.getDefault(), "%s:%d:\n", filePath, lineNumber); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake errors", MessageEvent.Kind.ERROR, lineNumber, 0); }
@Test public void testSingleLineCmakeErrorInFileWithLineNumberAndColumn() { String prefix = "CMake Error: Error in cmake code at "; String filePath = sourceFile.getAbsolutePath(); int lineNumber = 13; int columnNumber = 42; String fileAndLineNumber = String.format( Locale.getDefault(), "%s:%d:%d\n", filePath, lineNumber, columnNumber); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake errors", MessageEvent.Kind.ERROR, lineNumber, columnNumber); }
@Test public void testSingleLineCmakeWarningInFileWithoutLineNumberOrColumn() { String prefix = "CMake Warning: Warning in cmake code at "; String filePath = sourceFile.getAbsolutePath(); String fileAndLineNumber = String.format(Locale.getDefault(), "%s::\n", filePath); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake warnings", MessageEvent.Kind.WARNING, 0, 0); }
@Test public void testSingleLineCmakeWarningInFileWithLineNumber() { String prefix = "CMake Warning: Warning in cmake code at "; String filePath = sourceFile.getAbsolutePath(); int lineNumber = 13; String fileAndLineNumber = String.format(Locale.getDefault(), "%s:%d:\n", filePath, lineNumber); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake warnings", MessageEvent.Kind.WARNING, lineNumber, 0); }
@Test public void testSingleLineCmakeWarningInFileWithLineNumberAndColumn() { String prefix = "CMake Warning: Warning in cmake code at "; String filePath = sourceFile.getAbsolutePath(); int lineNumber = 13; int columnNumber = 42; String fileAndLineNumber = String.format( Locale.getDefault(), "%s:%d:%d\n", filePath, lineNumber, columnNumber); String err = prefix + fileAndLineNumber; BuildOutputInstantReader reader = new TestBuildOutputInstantReader(err); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), filePath, "CMake warnings", MessageEvent.Kind.WARNING, lineNumber, columnNumber); }
@Test public void testLongErrorMessage() throws IOException { File makefile = temporaryFolder.newFile("CMakeLists.txt"); String errorMessage = "CMake Error at %s:49 (message): %s"; String loremIpsum = "Lorem ipsum dolor\n" + "amet, consectetur adipiscing elit. Etiam ac aliquam lacus. Nullam suscipit nisl\n" + "vitae sodales varius. Donec eu enim ante. Maecenas congue ante a nibh tristique,\n" + "in sagittis velit suscipit. Ut hendrerit molestie augue quis sodales. Praesent ac\n" + "consectetur est. Duis at auctor neque."; errorMessage = String.format( Locale.getDefault(), errorMessage, makefile.getAbsolutePath(), loremIpsum); BuildOutputInstantReader reader = new TestBuildOutputInstantReader(errorMessage); ArgumentCaptor<BuildEvent> captor = ArgumentCaptor.forClass(BuildEvent.class); assertThat(parser.parse(reader.readLine(), reader, messageConsumer)).isTrue(); verify(messageConsumer).accept(captor.capture()); assertThat(captor.getAllValues()).hasSize(1); verifyFileMessageEvent(captor.getAllValues().get(0), makefile.getAbsolutePath(), "CMake errors", MessageEvent.Kind.ERROR, 49, 0); }