diff --git a/pom.xml b/pom.xml index 84e4aaabf..cef26419d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ edu.hm.hafner analysis-model - 4.0.1-SNAPSHOT + 4.1.0-SNAPSHOT jar diff --git a/src/main/java/edu/hm/hafner/analysis/parser/CMakeParser.java b/src/main/java/edu/hm/hafner/analysis/parser/CMakeParser.java new file mode 100644 index 000000000..d44cd1984 --- /dev/null +++ b/src/main/java/edu/hm/hafner/analysis/parser/CMakeParser.java @@ -0,0 +1,52 @@ +package edu.hm.hafner.analysis.parser; + +import java.util.Optional; +import java.util.regex.Matcher; + +import org.apache.commons.lang3.StringUtils; + +import edu.hm.hafner.analysis.Issue; +import edu.hm.hafner.analysis.IssueBuilder; +import edu.hm.hafner.analysis.Severity; +import edu.hm.hafner.analysis.LookaheadParser; +import edu.hm.hafner.util.LookaheadStream; + +/** + * A parser for CMake warnings. + * + * @author Uwe Brandt + */ +public class CMakeParser extends LookaheadParser { + private static final long serialVersionUID = 8149238560432255036L; + + private static final String CMAKE_WARNING_PATTERN = + "^(?.*?)CMake\\s+(?Warning|Deprecation Warning|Error)(?:.*?(?\\S+)){0,1}(?::(?\\d+)\\s+(?\\S+)){0,1}\\s*:"; + + /** + * Creates a new instance of {@link CMakeParser}. + */ + public CMakeParser() { + super(CMAKE_WARNING_PATTERN); + } + + @Override + protected Optional createIssue(final Matcher matcher, final LookaheadStream lookahead, + final IssueBuilder builder) { + // if the category is contained in brackets, remove those brackets + String category = StringUtils.strip(matcher.group("category"), "()"); + int prefixLength = matcher.group("prefix").length(); + return builder.setFileName(matcher.group("file")) + .setLineStart(matcher.group("line")) + .setCategory(category) + .setMessage(readMessage(lookahead, prefixLength)) + .setSeverity(Severity.guessFromString(matcher.group("type"))) + .buildOptional(); + } + + private String readMessage(final LookaheadStream lookahead, final int prefixLength) { + if (lookahead.hasNext()) { + return lookahead.next().substring(prefixLength).trim(); + } + return ""; + } +} diff --git a/src/test/java/edu/hm/hafner/analysis/parser/CMakeParserTest.java b/src/test/java/edu/hm/hafner/analysis/parser/CMakeParserTest.java new file mode 100644 index 000000000..6e197a7a2 --- /dev/null +++ b/src/test/java/edu/hm/hafner/analysis/parser/CMakeParserTest.java @@ -0,0 +1,76 @@ +package edu.hm.hafner.analysis.parser; + +import edu.hm.hafner.analysis.AbstractParserTest; +import edu.hm.hafner.analysis.Severity; +import edu.hm.hafner.analysis.Report; +import edu.hm.hafner.analysis.assertj.SoftAssertions; + +/** + * Tests the class {@link CMakeParser}. + * + * @author Uwe Brandt + */ +class CMakeParserTest extends AbstractParserTest { + CMakeParserTest() { + super("cmake.txt"); + } + + @Override + protected void assertThatIssuesArePresent(final Report report, final SoftAssertions softly) { + softly.assertThat(report).hasSize(8); + softly.assertThat(report.get(0)) + .hasSeverity(Severity.WARNING_NORMAL) + .hasCategory("") + .hasLineStart(0) + .hasMessage("Manually-specified variables were not used by the project") + .hasFileName("-"); + softly.assertThat(report.get(1)) + .hasSeverity(Severity.WARNING_NORMAL) + .hasCategory("") + .hasLineStart(0) + .hasMessage("The build directory is a subdirectory of the source directory.") + .hasFileName("CMakeLists.txt"); + softly.assertThat(report.get(2)) + .hasSeverity(Severity.WARNING_NORMAL) + .hasCategory("option") + .hasLineStart(10) + .hasMessage("I'm the message") + .hasFileName("tools/gtest-1.8/googlemock/CMakeLists.txt"); + softly.assertThat(report.get(3)) + .hasSeverity(Severity.WARNING_NORMAL) + .hasCategory("message") + .hasLineStart(423) + .hasMessage("Special workaround applied") + .hasFileName("project/utils/fancy.cmake"); + softly.assertThat(report.get(4)) + .hasSeverity(Severity.ERROR) + .hasCategory("message") + .hasLineStart(2) + .hasMessage("Uh oh !$%@!") + .hasFileName("error.cmake"); + softly.assertThat(report.get(5)) + .hasSeverity(Severity.WARNING_NORMAL) + .hasCategory("message") + .hasLineStart(23) + .hasMessage("function foo is deprecated, use bar instead") + .hasFileName("legacy.cmake"); + softly.assertThat(report.get(6)) + .hasSeverity(Severity.WARNING_NORMAL) + .hasCategory("nonexistingcategory") + .hasLineStart(357) + .hasMessage("strange things can happen") + .hasFileName("unlikely.cmake"); + softly.assertThat(report.get(7)) + .hasSeverity(Severity.WARNING_NORMAL) + .hasCategory("message") + .hasLineStart(362) + .hasMessage("") + .hasFileName("unlikely.cmake"); + } + + @Override + protected CMakeParser createParser() { + return new CMakeParser(); + } +} + diff --git a/src/test/resources/edu/hm/hafner/analysis/parser/cmake.txt b/src/test/resources/edu/hm/hafner/analysis/parser/cmake.txt new file mode 100644 index 000000000..08541e7f2 --- /dev/null +++ b/src/test/resources/edu/hm/hafner/analysis/parser/cmake.txt @@ -0,0 +1,22 @@ +[step1] CMake Warning: +[step1] Manually-specified variables were not used by the project + +[step2] CMake Warning in CMakeLists.txt: +[step2] The build directory is a subdirectory of the source directory. + +CMake Warning (dev) at tools/gtest-1.8/googlemock/CMakeLists.txt:10 (option): + I'm the message + +CMake Warning at project/utils/fancy.cmake:423 (message): + Special workaround applied + +CMake Error at error.cmake:2 (message): + Uh oh !$%@! + +CMake Deprecation Warning at legacy.cmake:23 (message): + function foo is deprecated, use bar instead + +CMake Warning at unlikely.cmake:357 nonexistingcategory: + strange things can happen + +CMake Warning at unlikely.cmake:362 (message): \ No newline at end of file