diff --git a/README.md b/README.md index ad489274..93d4448b 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ A number of **parsers** have been implemented. Some **parsers** can parse output | [_PHPCS_](https://github.com/squizlabs/PHP_CodeSniffer) | `CHECKSTYLE` | With `phpcs api.php --report=checkstyle`. | [_PHPPMD_](https://phpmd.org/) | `PMD` | With `phpmd api.php xml ruleset.xml`. | [_PMD_](https://pmd.github.io/) | `PMD` | +| [_Patch_](https://en.wikipedia.org/wiki/Diff) | `DIFF` | Often called 'patch'. | [_Pep8_](https://github.com/PyCQA/pycodestyle) | `FLAKE8` | | [_PerlCritic_](https://github.com/Perl-Critic) | `PERLCRITIC` | | [_PiTest_](http://pitest.org/) | `PITEST` | diff --git a/src/main/java/se/bjurr/violations/lib/parsers/DiffParser.java b/src/main/java/se/bjurr/violations/lib/parsers/DiffParser.java new file mode 100644 index 00000000..1b518368 --- /dev/null +++ b/src/main/java/se/bjurr/violations/lib/parsers/DiffParser.java @@ -0,0 +1,143 @@ +package se.bjurr.violations.lib.parsers; + +import static se.bjurr.violations.lib.model.Violation.violationBuilder; +import static se.bjurr.violations.lib.parsers.DiffParser.DiffState.ADDED; +import static se.bjurr.violations.lib.parsers.DiffParser.DiffState.CHANGED; +import static se.bjurr.violations.lib.parsers.DiffParser.DiffState.DELETED; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import se.bjurr.violations.lib.ViolationsLogger; +import se.bjurr.violations.lib.model.Violation; + +public class DiffParser implements ViolationsParser { + public class CommonParsed { + private final Integer startLineBefore; + private final Integer endLineBefore; + private final Integer startLineAfter; + private final Integer endLineAfter; + + public CommonParsed(Integer startLineBefore, Integer endLineBefore, Integer startLineAfter, + Integer endLineAfter) { + super(); + this.startLineBefore = startLineBefore; + this.endLineBefore = endLineBefore; + this.startLineAfter = startLineAfter; + this.endLineAfter = endLineAfter; + } + + @Override + public String toString() { + return "CommonParsed [startLineBefore=" + startLineBefore + ", endLineBefore=" + endLineBefore + + ", startLineAfter=" + startLineAfter + ", endLineAfter=" + endLineAfter + "]"; + } + + } + + private static Logger LOG = Logger.getLogger(DiffParser.class.getSimpleName()); + private static final String LINE_PATTERN_STR = "([0-9]+),?([0-9]+)?"; + private static final Pattern LINE_PATTERN = Pattern.compile(LINE_PATTERN_STR); + + public enum DiffState { + ADDED("a"), DELETED("d"), CHANGED("c"); + + private final Pattern pattern; + + private DiffState(String letter) { + this.pattern = Pattern.compile("^" + LINE_PATTERN_STR + letter + LINE_PATTERN_STR); + } + + public Pattern getScopePattern() { + return pattern; + } + + public boolean matches(String line) { + return this.pattern.matcher(line).find(); + } + } + + @Override + public Set parseReportOutput(String reportContent, ViolationsLogger violationsLogger) throws Exception { + Set violations = new TreeSet<>(); + Iterator linesItr = Arrays.asList(reportContent.split("\\r?\\n")).iterator(); + while (linesItr.hasNext()) { + String line = linesItr.next(); + if (ADDED.matches(line)) { + violations.add(parseAdded(line, linesItr)); + } else if (DELETED.matches(line)) { + violations.add(parseDeleted(line, linesItr)); + } else if (CHANGED.matches(line)) { + violations.add(parseChanged(line, linesItr)); + } else { + LOG.log(Level.FINE, "Was unable to detect diff state " + line); + } + } + return violations; + } + + private CommonParsed parseCommon(String line) { + String[] orignalAndNew = line.split("[acd]"); + + String originalLines = orignalAndNew[0]; + Matcher originalMatcher = LINE_PATTERN.matcher(originalLines); + int startLineBefore = Integer.parseInt(originalMatcher.group(0)); + Integer endLineBefore = null; + if (originalMatcher.groupCount() > 1) { + endLineBefore = Integer.parseInt(originalMatcher.group(1)); + } + + String newLines = orignalAndNew[1]; + Matcher newMatcher = LINE_PATTERN.matcher(newLines); + int startLineAfter = Integer.parseInt(newMatcher.group(0)); + Integer endLineAfter = null; + if (newMatcher.groupCount() > 1) { + endLineAfter = Integer.parseInt(newMatcher.group(1)); + } + return new CommonParsed(startLineBefore, endLineBefore, startLineAfter, endLineAfter); + } + + private Violation parseChanged(String line, Iterator linesItr) { + CommonParsed commonParsed = parseCommon(line); + new StringBuilder(); + while (linesItr.hasNext()) { + line = linesItr.next(); + if (line.equals("---")) { + break; + } + } + return violationBuilder() + .setStartLine(commonParsed.startLineBefore) + .setEndLine(commonParsed.endLineBefore) + .setSpecific("START_LINE_AFTER", commonParsed.startLineAfter) + .setSpecific("END_LINE_AFTER", commonParsed.endLineAfter) + .build(); + } + + private Violation parseDeleted(String line, Iterator linesItr) { + CommonParsed commonParsed = parseCommon(line); + return violationBuilder() + .setStartLine(commonParsed.startLineBefore) + .setEndLine(commonParsed.endLineBefore) + .setSpecific("START_LINE_AFTER", commonParsed.startLineAfter) + .setSpecific("END_LINE_AFTER", commonParsed.endLineAfter) + .build(); + } + + private Violation parseAdded(String line, Iterator linesItr) { + CommonParsed commonParsed = parseCommon(line); + return violationBuilder() + .setStartLine(commonParsed.startLineBefore) + .setEndLine(commonParsed.endLineBefore) + .setSpecific("START_LINE_AFTER", commonParsed.startLineAfter) + .setSpecific("END_LINE_AFTER", commonParsed.endLineAfter) + .build(); + } + +} diff --git a/src/main/java/se/bjurr/violations/lib/reports/Parser.java b/src/main/java/se/bjurr/violations/lib/reports/Parser.java index 86f2ff22..3e285777 100644 --- a/src/main/java/se/bjurr/violations/lib/reports/Parser.java +++ b/src/main/java/se/bjurr/violations/lib/reports/Parser.java @@ -9,6 +9,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.logging.Logger; + import se.bjurr.violations.lib.ViolationsLogger; import se.bjurr.violations.lib.model.Violation; import se.bjurr.violations.lib.parsers.AndroidLintParser; @@ -39,6 +40,7 @@ import se.bjurr.violations.lib.parsers.MyPyParser; import se.bjurr.violations.lib.parsers.PCLintParser; import se.bjurr.violations.lib.parsers.PMDParser; +import se.bjurr.violations.lib.parsers.DiffParser; import se.bjurr.violations.lib.parsers.PerlCriticParser; import se.bjurr.violations.lib.parsers.PiTestParser; import se.bjurr.violations.lib.parsers.ProtoLintParser; @@ -79,6 +81,7 @@ public enum Parser { KOTLINGRADLE(new KotlinGradleParser()), // MSCPP(new MSCPPParser()), // MYPY(new MyPyParser()), // + DIFF(new DiffParser()), // GOLINT(new GoLintParser()), // GOOGLEERRORPRONE(new GoogleErrorProneParser()), // PERLCRITIC(new PerlCriticParser()), // diff --git a/src/main/java/se/bjurr/violations/lib/reports/Reporter.java b/src/main/java/se/bjurr/violations/lib/reports/Reporter.java index 9ebab6dc..f0c00a7c 100644 --- a/src/main/java/se/bjurr/violations/lib/reports/Reporter.java +++ b/src/main/java/se/bjurr/violations/lib/reports/Reporter.java @@ -93,10 +93,15 @@ public enum Reporter { MYPY("MyPy", Parser.MYPY, "https://pypi.python.org/pypi/mypy-lang", ""), MSCPP("MSCpp", Parser.MSCPP, "https://visualstudio.microsoft.com/vs/features/cplusplus/", ""), NULLAWAY( - "NullAway", - Parser.GOOGLEERRORPRONE, - "https://github.com/uber/NullAway", - "Same format as Google Error Prone."), + "NullAway", + Parser.GOOGLEERRORPRONE, + "https://github.com/uber/NullAway", + "Same format as Google Error Prone."), + DIFF( + "Patch", + Parser.DIFF, + "https://en.wikipedia.org/wiki/Diff", + "Unidiff, often used by the `patch` program."), PCLINT( "PCLint", Parser.PCLINT, diff --git a/src/test/java/se/bjurr/violations/lib/DiffTest.java b/src/test/java/se/bjurr/violations/lib/DiffTest.java new file mode 100644 index 00000000..9d451ed1 --- /dev/null +++ b/src/test/java/se/bjurr/violations/lib/DiffTest.java @@ -0,0 +1,42 @@ +package se.bjurr.violations.lib; + +import static org.assertj.core.api.Assertions.assertThat; +import static se.bjurr.violations.lib.TestUtils.getRootFolder; +import static se.bjurr.violations.lib.ViolationsApi.violationsApi; +import static se.bjurr.violations.lib.model.SEVERITY.INFO; +import static se.bjurr.violations.lib.reports.Parser.DIFF; + +import java.util.ArrayList; +import java.util.Set; + +import org.junit.Test; + +import se.bjurr.violations.lib.model.Violation; + +public class DiffTest { + + @Test + public void testThatGoVetViolationsCanBeParsed() { + final String rootFolder = getRootFolder(); + + final Set actual = + violationsApi() // + .withPattern(".*/diff/diff-1\\.txt$") // + .inFolder(rootFolder) // + .findAll(DIFF) // + .violations(); + + assertThat(actual) // + .hasSize(3); + + Violation violation0 = new ArrayList<>(actual).get(0); + assertThat(violation0.getMessage()) // + .isEqualTo("this is a message"); + assertThat(violation0.getFile()) // + .isEqualTo("my_file.go"); + assertThat(violation0.getSeverity()) // + .isEqualTo(INFO); + assertThat(violation0.getStartLine()) // + .isEqualTo(46); + } +} diff --git a/src/test/resources/diff/0001-Gradle-Release-Plugin-new-version-commit-1.128-SNAPS.patch b/src/test/resources/diff/0001-Gradle-Release-Plugin-new-version-commit-1.128-SNAPS.patch new file mode 100644 index 00000000..d1e5c30f --- /dev/null +++ b/src/test/resources/diff/0001-Gradle-Release-Plugin-new-version-commit-1.128-SNAPS.patch @@ -0,0 +1,41 @@ +From 513d19e33d0a78b778bc2cd33551a300e7605975 Mon Sep 17 00:00:00 2001 +From: Tomas Bjerre +Date: Sun, 6 Sep 2020 07:26:13 +0200 +Subject: [PATCH] [Gradle Release Plugin] - new version commit: + '1.128-SNAPSHOT'. + +--- + CHANGELOG.md | 9 +++++++++ + gradle.properties | 2 +- + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG.md b/CHANGELOG.md +index 7b2cb23..a1ee761 100644 +--- a/CHANGELOG.md ++++ b/CHANGELOG.md +@@ -3,6 +3,15 @@ + + Changelog of Violations lib. + ++## 1.127 ++### GitHub [#95](https://github.com/tomasbjerre/violations-lib/issues/95) Add support for "suggested change" *enhancement* ++ ++**Moving PatchParser from violation-comments-lib** ++ ++ ++[5c52a3933792d14](https://github.com/tomasbjerre/violations-lib/commit/5c52a3933792d14) Tomas Bjerre *2020-09-06 05:24:56* ++ ++ + ## 1.126 + ### GitHub [#95](https://github.com/tomasbjerre/violations-lib/issues/95) Add support for "suggested change" *enhancement* + +diff --git a/gradle.properties b/gradle.properties +index aca4c1a..eda4430 100644 +--- a/gradle.properties ++++ b/gradle.properties +@@ -1 +1 @@ +-version = 1.127 ++version = 1.128-SNAPSHOT +-- +2.25.1 + diff --git a/src/test/resources/diff/diff-1.txt b/src/test/resources/diff/diff-1.txt new file mode 100644 index 00000000..55236b08 --- /dev/null +++ b/src/test/resources/diff/diff-1.txt @@ -0,0 +1,22 @@ +0a1,6 +> This is an important +> notice! It should +> therefore be located at +> the beginning of this +> document! +> +11,15d16 +< This paragraph contains +< text that is outdated. +< It will be deleted in the +< near future. +< +17c18 +< check this dokument. On +--- +> check this document. On +24a26,29 +> +> This paragraph contains +> important new additions +> to this document.