From e299d9c3d09e52dbbfe72023f78ea7f8a044963c Mon Sep 17 00:00:00 2001 From: Daniel Dominguez Date: Thu, 19 Dec 2024 15:03:18 -0800 Subject: [PATCH 1/5] Initial vale integration --- .../hm/hafner/analysis/parser/ValeParser.java | 75 ++++++ .../analysis/registry/ParserRegistry.java | 1 + .../analysis/registry/ValeDescriptor.java | 31 +++ .../analysis/parser/ValeParserTest.java | 27 ++ .../analysis/registry/ParserRegistryTest.java | 2 +- .../hafner/analysis/parser/vale-report.json | 234 ++++++++++++++++++ 6 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 src/main/java/edu/hm/hafner/analysis/parser/ValeParser.java create mode 100644 src/main/java/edu/hm/hafner/analysis/registry/ValeDescriptor.java create mode 100644 src/test/java/edu/hm/hafner/analysis/parser/ValeParserTest.java create mode 100644 src/test/resources/edu/hm/hafner/analysis/parser/vale-report.json diff --git a/src/main/java/edu/hm/hafner/analysis/parser/ValeParser.java b/src/main/java/edu/hm/hafner/analysis/parser/ValeParser.java new file mode 100644 index 000000000..f75c5a07a --- /dev/null +++ b/src/main/java/edu/hm/hafner/analysis/parser/ValeParser.java @@ -0,0 +1,75 @@ +package edu.hm.hafner.analysis.parser; + +import java.io.Serial; + +import org.json.JSONArray; +import org.json.JSONObject; + +import edu.hm.hafner.analysis.Issue; +import edu.hm.hafner.analysis.IssueBuilder; +import edu.hm.hafner.analysis.Report; +import edu.hm.hafner.analysis.Severity; + +/** + * Parser for vale reports. + */ +public class ValeParser extends JsonIssueParser { + // Constants for JSON keys + private static final String CHECK = "Check"; + private static final String LINE_KEY = "Line"; + private static final String LINK_KEY = "Link"; + private static final String MESSAGE_KEY = "Message"; + private static final String SPAN_KEY = "Span"; + private static final String SEVERITY_KEY = "Severity"; + + @Serial + private static final long serialVersionUID = -4034450901865555017L; + + @Override + protected void parseJsonObject(final Report report, final JSONObject jsonReport, final IssueBuilder issueBuilder) { + JSONArray fileNames = jsonReport.names(); + for (Object o : fileNames) { + if (o instanceof String f) { + JSONArray jsonArray = jsonReport.getJSONArray(f); + for (Object data : jsonArray) { + if (data instanceof JSONObject dataObject) { + report.add(createIssue(issueBuilder, f, dataObject)); + } + } + } + } + } + + private Issue createIssue(final IssueBuilder issueBuilder, final String fileName, final JSONObject data) { + String checker = data.getString(CHECK); + String message = data.getString(MESSAGE_KEY); + String severity = data.getString(SEVERITY_KEY); + String link = data.getString(LINK_KEY); + int line = data.getInt(LINE_KEY); + JSONArray span = data.getJSONArray(SPAN_KEY); + int startColumn = span.getInt(0); + int endColumn = span.getInt(1); + final Severity analysisSeverity; + switch (severity) { + case "error": + analysisSeverity = Severity.ERROR; + break; + case "warning": + analysisSeverity = Severity.WARNING_NORMAL; + break; + case "suggestion": + analysisSeverity = Severity.WARNING_LOW; + break; + default: + analysisSeverity = Severity.WARNING_NORMAL; + break; + } + return issueBuilder.setFileName(fileName).setDescription(checker) + .setMessage(message).setSeverity(analysisSeverity) + .setReference(link) + .setLineStart(line) + .setLineEnd(line) + .setColumnStart(startColumn).setColumnEnd(endColumn) + .buildAndClean(); + } +} diff --git a/src/main/java/edu/hm/hafner/analysis/registry/ParserRegistry.java b/src/main/java/edu/hm/hafner/analysis/registry/ParserRegistry.java index 57bdea582..3cae5b18b 100644 --- a/src/main/java/edu/hm/hafner/analysis/registry/ParserRegistry.java +++ b/src/main/java/edu/hm/hafner/analysis/registry/ParserRegistry.java @@ -167,6 +167,7 @@ public class ParserRegistry { new TnsdlDescriptor(), new TrivyDescriptor(), new TsLintDescriptor(), + new ValeDescriptor(), new ValgrindDescriptor(), new VeraCodePipelineScannerDescriptor(), new XlcDescriptor(), diff --git a/src/main/java/edu/hm/hafner/analysis/registry/ValeDescriptor.java b/src/main/java/edu/hm/hafner/analysis/registry/ValeDescriptor.java new file mode 100644 index 000000000..130b92dad --- /dev/null +++ b/src/main/java/edu/hm/hafner/analysis/registry/ValeDescriptor.java @@ -0,0 +1,31 @@ +package edu.hm.hafner.analysis.registry; + +import edu.hm.hafner.analysis.IssueParser; +import edu.hm.hafner.analysis.parser.ValeParser; + +/** + * Descriptor for the vale prose linter. + */ +public class ValeDescriptor extends ParserDescriptor { + private static final String ID = "vale"; + private static final String NAME = "Vale"; + + ValeDescriptor() { + super(ID, NAME); + } + + @Override + public IssueParser createParser(Option... options) { + return new ValeParser(); + } + + @Override + public String getPattern() { + return "**/vale-report.json"; + } + + @Override + public String getUrl() { + return "https://vale.sh/"; + } +} diff --git a/src/test/java/edu/hm/hafner/analysis/parser/ValeParserTest.java b/src/test/java/edu/hm/hafner/analysis/parser/ValeParserTest.java new file mode 100644 index 000000000..76f71cc49 --- /dev/null +++ b/src/test/java/edu/hm/hafner/analysis/parser/ValeParserTest.java @@ -0,0 +1,27 @@ +package edu.hm.hafner.analysis.parser; + +import edu.hm.hafner.analysis.IssueParser; +import edu.hm.hafner.analysis.Report; +import edu.hm.hafner.analysis.Severity; +import edu.hm.hafner.analysis.assertions.SoftAssertions; +import edu.hm.hafner.analysis.registry.AbstractParserTest; + +class ValeParserTest extends AbstractParserTest { + ValeParserTest() { + super("vale-report.json"); + } + + @Override + protected void assertThatIssuesArePresent(final Report report, final SoftAssertions softly) { + softly.assertThat(report).hasSize(12).hasDuplicatesSize(0); + softly.assertThat(report.get(0)) + .hasFileName("file3.adoc") + .hasDescription("RedHat.SimpleWords") + .hasSeverity(Severity.WARNING_LOW); + } + + @Override + protected IssueParser createParser() { + return new ValeParser(); + } +} diff --git a/src/test/java/edu/hm/hafner/analysis/registry/ParserRegistryTest.java b/src/test/java/edu/hm/hafner/analysis/registry/ParserRegistryTest.java index d16108447..24dfcb343 100644 --- a/src/test/java/edu/hm/hafner/analysis/registry/ParserRegistryTest.java +++ b/src/test/java/edu/hm/hafner/analysis/registry/ParserRegistryTest.java @@ -21,7 +21,7 @@ class ParserRegistryTest extends ResourceTest { // Note for parser developers: if you add a new parser, // please check if you are using the correct type and increment the corresponding count - private static final long WARNING_PARSERS_COUNT = 127L; + private static final long WARNING_PARSERS_COUNT = 128L; private static final long BUG_PARSERS_COUNT = 3L; private static final long VULNERABILITY_PARSERS_COUNT = 7L; private static final long DUPLICATION_PARSERS_COUNT = 3L; diff --git a/src/test/resources/edu/hm/hafner/analysis/parser/vale-report.json b/src/test/resources/edu/hm/hafner/analysis/parser/vale-report.json new file mode 100644 index 000000000..14e07edc1 --- /dev/null +++ b/src/test/resources/edu/hm/hafner/analysis/parser/vale-report.json @@ -0,0 +1,234 @@ +{ + "file1.adoc": [ + { + "Action": { + "Name": "", + "Params": null + }, + "Span": [ + 1, + 5 + ], + "Check": "RedHat.SentenceLength", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/sentencelength/", + "Message": "Try to keep sentences to an average of 32 words or fewer.", + "Severity": "suggestion", + "Match": "While", + "Line": 10 + } + ], + "file2.adoc": [ + { + "Action": { + "Name": "replace", + "Params": [ + "might", + "can" + ] + }, + "Span": [ + 143, + 145 + ], + "Check": "RedHat.TermsWarnings", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/termswarnings/", + "Message": "Consider using 'might' or 'can' rather than 'may' unless updating existing content that uses the term.", + "Severity": "warning", + "Match": "may", + "Line": 39 + }, + { + "Action": { + "Name": "edit", + "Params": [ + "regex", + "(\\w+)( using)", + "$1 by using" + ] + }, + "Span": [ + 44, + 64 + ], + "Check": "RedHat.Using", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/using/", + "Message": "Use 'by using' instead of 'using' when it follows a noun for clarity and grammatical correctness.", + "Severity": "warning", + "Match": "functionalities using", + "Line": 51 + }, + { + "Action": { + "Name": "replace", + "Params": [ + "might", + "can" + ] + }, + "Span": [ + 24, + 26 + ], + "Check": "RedHat.TermsWarnings", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/termswarnings/", + "Message": "Consider using 'might' or 'can' rather than 'may' unless updating existing content that uses the term.", + "Severity": "warning", + "Match": "may", + "Line": 65 + } + ], + "file3.adoc": [ + { + "Action": { + "Name": "replace", + "Params": [ + "give", + "offer" + ] + }, + "Span": [ + 11, + 17 + ], + "Check": "RedHat.SimpleWords", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/simplewords/", + "Message": "Use simple language. Consider using 'give' or 'offer' rather than 'provide'.", + "Severity": "suggestion", + "Match": "provide", + "Line": 170 + }, + { + "Action": { + "Name": "replace", + "Params": [ + "complete", + "finish" + ] + }, + "Span": [ + 29, + 36 + ], + "Check": "RedHat.SimpleWords", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/simplewords/", + "Message": "Use simple language. Consider using 'complete' or 'finish' rather than 'finalize'.", + "Severity": "suggestion", + "Match": "finalize", + "Line": 212 + }, + { + "Action": { + "Name": "replace", + "Params": [ + "complete", + "finish" + ] + }, + "Span": [ + 5, + 12 + ], + "Check": "RedHat.SimpleWords", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/simplewords/", + "Message": "Use simple language. Consider using 'complete' or 'finish' rather than 'finalize'.", + "Severity": "suggestion", + "Match": "finalize", + "Line": 451 + }, + { + "Action": { + "Name": "replace", + "Params": [ + "give", + "offer" + ] + }, + "Span": [ + 16, + 22 + ], + "Check": "RedHat.SimpleWords", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/simplewords/", + "Message": "Use simple language. Consider using 'give' or 'offer' rather than 'provide'.", + "Severity": "suggestion", + "Match": "provide", + "Line": 530 + }, + { + "Action": { + "Name": "", + "Params": null + }, + "Span": [ + 1, + 4 + ], + "Check": "RedHat.SentenceLength", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/sentencelength/", + "Message": "Try to keep sentences to an average of 32 words or fewer.", + "Severity": "suggestion", + "Match": "When", + "Line": 533 + }, + { + "Action": { + "Name": "", + "Params": null + }, + "Span": [ + 1, + 4 + ], + "Check": "RedHat.SentenceLength", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/sentencelength/", + "Message": "Try to keep sentences to an average of 32 words or fewer.", + "Severity": "suggestion", + "Match": "When", + "Line": 535 + }, + { + "Action": { + "Name": "", + "Params": null + }, + "Span": [ + 1, + 3 + ], + "Check": "RedHat.SentenceLength", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/sentencelength/", + "Message": "Try to keep sentences to an average of 32 words or fewer.", + "Severity": "suggestion", + "Match": "The", + "Line": 571 + }, + { + "Action": { + "Name": "", + "Params": null + }, + "Span": [ + 1, + 12 + ], + "Check": "RedHat.SentenceLength", + "Description": "", + "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/sentencelength/", + "Message": "Try to keep sentences to an average of 32 words or fewer.", + "Severity": "suggestion", + "Match": "Additionally", + "Line": 717 + } + ] +} From db6e9708b8163f0b1e6f443d3e0614c7fe893599 Mon Sep 17 00:00:00 2001 From: Daniel Dominguez Date: Fri, 20 Dec 2024 05:44:21 -0800 Subject: [PATCH 2/5] Remove tab character --- .../java/edu/hm/hafner/analysis/registry/ParserRegistry.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/hm/hafner/analysis/registry/ParserRegistry.java b/src/main/java/edu/hm/hafner/analysis/registry/ParserRegistry.java index 3cae5b18b..d09d9854b 100644 --- a/src/main/java/edu/hm/hafner/analysis/registry/ParserRegistry.java +++ b/src/main/java/edu/hm/hafner/analysis/registry/ParserRegistry.java @@ -167,7 +167,7 @@ public class ParserRegistry { new TnsdlDescriptor(), new TrivyDescriptor(), new TsLintDescriptor(), - new ValeDescriptor(), + new ValeDescriptor(), new ValgrindDescriptor(), new VeraCodePipelineScannerDescriptor(), new XlcDescriptor(), From 3693c6cba84eaa6f8020a979c6b3dbce314fae39 Mon Sep 17 00:00:00 2001 From: Daniel Dominguez Date: Fri, 20 Dec 2024 06:25:11 -0800 Subject: [PATCH 3/5] Added help --- .../java/edu/hm/hafner/analysis/registry/ValeDescriptor.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/edu/hm/hafner/analysis/registry/ValeDescriptor.java b/src/main/java/edu/hm/hafner/analysis/registry/ValeDescriptor.java index 130b92dad..2b120458c 100644 --- a/src/main/java/edu/hm/hafner/analysis/registry/ValeDescriptor.java +++ b/src/main/java/edu/hm/hafner/analysis/registry/ValeDescriptor.java @@ -28,4 +28,9 @@ public String getPattern() { public String getUrl() { return "https://vale.sh/"; } + + @Override + public String getHelp() { + return "Reads vale report files. Use the flag --output=JSON"; + } } From b86f576d154935f3ca72e6ba005e2f7d4630d425 Mon Sep 17 00:00:00 2001 From: Daniel Dominguez Date: Fri, 20 Dec 2024 07:29:47 -0800 Subject: [PATCH 4/5] Complete junit test --- .../analysis/parser/ValeParserTest.java | 26 ++- .../hafner/analysis/parser/vale-report.json | 174 +----------------- 2 files changed, 25 insertions(+), 175 deletions(-) diff --git a/src/test/java/edu/hm/hafner/analysis/parser/ValeParserTest.java b/src/test/java/edu/hm/hafner/analysis/parser/ValeParserTest.java index 76f71cc49..b43bbef28 100644 --- a/src/test/java/edu/hm/hafner/analysis/parser/ValeParserTest.java +++ b/src/test/java/edu/hm/hafner/analysis/parser/ValeParserTest.java @@ -13,11 +13,31 @@ class ValeParserTest extends AbstractParserTest { @Override protected void assertThatIssuesArePresent(final Report report, final SoftAssertions softly) { - softly.assertThat(report).hasSize(12).hasDuplicatesSize(0); + softly.assertThat(report).hasSize(3).hasDuplicatesSize(0); softly.assertThat(report.get(0)) - .hasFileName("file3.adoc") - .hasDescription("RedHat.SimpleWords") + .hasFileName("file1.adoc") + .hasDescription("RedHat.SentenceLength") + .hasMessage("Try to keep sentences to an average of 32 words or fewer.") + .hasLineStart(10) + .hasColumnStart(1) + .hasColumnEnd(5) .hasSeverity(Severity.WARNING_LOW); + softly.assertThat(report.get(1)) + .hasFileName("file2.adoc") + .hasDescription("RedHat.TermsWarnings") + .hasMessage("Consider using 'might' or 'can' rather than 'may' unless updating existing content that uses the term.") + .hasLineStart(39) + .hasColumnStart(143) + .hasColumnEnd(145) + .hasSeverity(Severity.WARNING_NORMAL); + softly.assertThat(report.get(2)) + .hasFileName("file2.adoc") + .hasDescription("RedHat.Using") + .hasMessage("Use 'by using' instead of 'using' when it follows a noun for clarity and grammatical correctness.") + .hasLineStart(51) + .hasColumnStart(44) + .hasColumnEnd(64) + .hasSeverity(Severity.ERROR); } @Override diff --git a/src/test/resources/edu/hm/hafner/analysis/parser/vale-report.json b/src/test/resources/edu/hm/hafner/analysis/parser/vale-report.json index 14e07edc1..2d1a71dc3 100644 --- a/src/test/resources/edu/hm/hafner/analysis/parser/vale-report.json +++ b/src/test/resources/edu/hm/hafner/analysis/parser/vale-report.json @@ -56,179 +56,9 @@ "Description": "", "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/using/", "Message": "Use 'by using' instead of 'using' when it follows a noun for clarity and grammatical correctness.", - "Severity": "warning", + "Severity": "error", "Match": "functionalities using", "Line": 51 - }, - { - "Action": { - "Name": "replace", - "Params": [ - "might", - "can" - ] - }, - "Span": [ - 24, - 26 - ], - "Check": "RedHat.TermsWarnings", - "Description": "", - "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/termswarnings/", - "Message": "Consider using 'might' or 'can' rather than 'may' unless updating existing content that uses the term.", - "Severity": "warning", - "Match": "may", - "Line": 65 - } - ], - "file3.adoc": [ - { - "Action": { - "Name": "replace", - "Params": [ - "give", - "offer" - ] - }, - "Span": [ - 11, - 17 - ], - "Check": "RedHat.SimpleWords", - "Description": "", - "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/simplewords/", - "Message": "Use simple language. Consider using 'give' or 'offer' rather than 'provide'.", - "Severity": "suggestion", - "Match": "provide", - "Line": 170 - }, - { - "Action": { - "Name": "replace", - "Params": [ - "complete", - "finish" - ] - }, - "Span": [ - 29, - 36 - ], - "Check": "RedHat.SimpleWords", - "Description": "", - "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/simplewords/", - "Message": "Use simple language. Consider using 'complete' or 'finish' rather than 'finalize'.", - "Severity": "suggestion", - "Match": "finalize", - "Line": 212 - }, - { - "Action": { - "Name": "replace", - "Params": [ - "complete", - "finish" - ] - }, - "Span": [ - 5, - 12 - ], - "Check": "RedHat.SimpleWords", - "Description": "", - "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/simplewords/", - "Message": "Use simple language. Consider using 'complete' or 'finish' rather than 'finalize'.", - "Severity": "suggestion", - "Match": "finalize", - "Line": 451 - }, - { - "Action": { - "Name": "replace", - "Params": [ - "give", - "offer" - ] - }, - "Span": [ - 16, - 22 - ], - "Check": "RedHat.SimpleWords", - "Description": "", - "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/simplewords/", - "Message": "Use simple language. Consider using 'give' or 'offer' rather than 'provide'.", - "Severity": "suggestion", - "Match": "provide", - "Line": 530 - }, - { - "Action": { - "Name": "", - "Params": null - }, - "Span": [ - 1, - 4 - ], - "Check": "RedHat.SentenceLength", - "Description": "", - "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/sentencelength/", - "Message": "Try to keep sentences to an average of 32 words or fewer.", - "Severity": "suggestion", - "Match": "When", - "Line": 533 - }, - { - "Action": { - "Name": "", - "Params": null - }, - "Span": [ - 1, - 4 - ], - "Check": "RedHat.SentenceLength", - "Description": "", - "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/sentencelength/", - "Message": "Try to keep sentences to an average of 32 words or fewer.", - "Severity": "suggestion", - "Match": "When", - "Line": 535 - }, - { - "Action": { - "Name": "", - "Params": null - }, - "Span": [ - 1, - 3 - ], - "Check": "RedHat.SentenceLength", - "Description": "", - "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/sentencelength/", - "Message": "Try to keep sentences to an average of 32 words or fewer.", - "Severity": "suggestion", - "Match": "The", - "Line": 571 - }, - { - "Action": { - "Name": "", - "Params": null - }, - "Span": [ - 1, - 12 - ], - "Check": "RedHat.SentenceLength", - "Description": "", - "Link": "https://redhat-documentation.github.io/vale-at-red-hat/docs/main/reference-guide/sentencelength/", - "Message": "Try to keep sentences to an average of 32 words or fewer.", - "Severity": "suggestion", - "Match": "Additionally", - "Line": 717 } ] -} +} \ No newline at end of file From d1193c2570feb675afc2dde0a038d41401c35bd3 Mon Sep 17 00:00:00 2001 From: Daniel Dominguez Date: Fri, 20 Dec 2024 08:19:31 -0800 Subject: [PATCH 5/5] Added vale to SUPPORTED-FORMATS.md --- SUPPORTED-FORMATS.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/SUPPORTED-FORMATS.md b/SUPPORTED-FORMATS.md index 7e99e7cfb..e72c9d415 100644 --- a/SUPPORTED-FORMATS.md +++ b/SUPPORTED-FORMATS.md @@ -2178,6 +2178,27 @@ analyze - iccxxxxcompiler_opts cstat2.cFor details check the IAR C- - + + + vale + + + - + + + + Vale + + + + **/vale-report.json + + + + + :bulb: Use option --output=JSON + + valgrind