Skip to content

Commit 1d800d6

Browse files
maksim-grebeniuk-sonarsourcesonartech
authored andcommitted
SONARPY-3180 Add support of trailing text for the noqa issue suppression (#392)
GitOrigin-RevId: 07209be932557838d2a3fa85d22542c60b70e71e
1 parent 900d5b4 commit 1d800d6

File tree

5 files changed

+44
-15
lines changed

5 files changed

+44
-15
lines changed

its/plugin/it-python-plugin-test/src/test/java/com/sonar/python/it/plugin/NoSonarTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void test_noqa() {
101101
analyzeProject(createScanner(NOQA_PROJECT_KEY, "projects/nosonar/noqa-project"));
102102

103103
IssueListAssert.assertThat(issues(NOQA_PROJECT_KEY))
104-
.hasSize(20)
104+
.hasSize(19)
105105
// basic noqa checks
106106
.containsIssue(1, "python:PrintStatementUsage")
107107
.containsIssue(2, "python:S1309").doesNotContainIssue(2, "python:PrintStatementUsage")

python-checks/src/test/resources/checks/nosonarCommentFormat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@
2727
# noqa: a,,c
2828
# Noncompliant@+1
2929
# noqa: a,c,
30-
# Noncompliant@+1
30+
3131
# noqa: a, some text

python-commons/src/test/java/org/sonar/plugins/python/nosonar/NoSonarLineInfoCollectorTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,10 @@ private static Stream<Arguments> provideCollectorParameters() {
145145
""
146146
),
147147
Arguments.of("# noqa: some text",
148-
Map.of(1, new NoSonarLineInfo(Set.of("some text"))),
148+
Map.of(1, new NoSonarLineInfo(Set.of("some"))),
149149
Set.of(),
150-
"some text",
151-
"some text:"
150+
"some",
151+
"some:"
152152
),
153153
Arguments.of("# noqa: a,b",
154154
Map.of(1, new NoSonarLineInfo(Set.of("a", "b"))),

python-frontend/src/main/java/org/sonar/plugins/python/api/nosonar/NoSonarInfoParser.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@
2222
import java.util.function.Predicate;
2323
import java.util.regex.Matcher;
2424
import java.util.regex.Pattern;
25+
import java.util.stream.Collectors;
2526
import java.util.stream.Stream;
2627
import javax.annotation.CheckForNull;
2728

2829
public class NoSonarInfoParser {
2930

3031
private static final Integer MAX_COMMENT_LENGTH = 50;
3132
private static final String NOQA_PREFIX_REGEX = "#\\s*noqa([\\s:].*)?";
32-
private static final String NOQA_PATTERN_REGEX = "^#\\s*noqa(?::\\s*(.+))?.*";
33+
private static final String NOQA_PATTERN_REGEX = "^#\\s*noqa(?::\\s*(.+))?(?:[\\s;:].*)?";
3334
private static final String NOSONAR_PREFIX_REGEX = "^#\\s*NOSONAR(\\W.*)?";
3435
private static final String NOSONAR_PATTERN_REGEX = "^#\\s*NOSONAR(?:\\s*\\(([^)]*)\\))?($|\\s.*)";
3536

@@ -65,7 +66,7 @@ private boolean isInvalidNoQaComment(String comment) {
6566
if (!isValidNoQa(comment)) {
6667
return true;
6768
}
68-
var rules = parseNoQaRules(comment).toList();
69+
var rules = parseNoQaRules(comment);
6970
return !rules.isEmpty() && rules.stream().anyMatch(r -> r.isBlank() || r.contains(" "));
7071
}
7172

@@ -111,6 +112,7 @@ private NoSonarLineInfo parseComment(String commentLine) {
111112
comment = parseNoSonarComment(commentLine);
112113
} else if (isValidNoQa(commentLine)) {
113114
parseNoQaRules(commentLine)
115+
.stream()
114116
.filter(Predicate.not(String::isEmpty))
115117
.forEach(rules::add);
116118
comment = parseNoQaComment(commentLine);
@@ -136,9 +138,20 @@ private String parseNoSonarComment(String noSonarCommentLine) {
136138
return getTruncatedCommentString(noSonarPattern, noSonarCommentLine).strip();
137139
}
138140

139-
private Stream<String> parseNoQaRules(String noSonarCommentLine) {
140-
var contentInsideParentheses = getParamsString(noQaPattern, noSonarCommentLine);
141-
return parseParamsString(contentInsideParentheses);
141+
private List<String> parseNoQaRules(String noSonarCommentLine) {
142+
var paramsString = getParamsString(noQaPattern, noSonarCommentLine);
143+
var paramsList = parseParamsString(paramsString).collect(Collectors.toList());
144+
if (!paramsList.isEmpty()) {
145+
// to get the last suppressed rule ID we need to split it to cut the trailing comment text.
146+
// valid cases are:
147+
// split by space: ruleID1, ruleID2 some comment
148+
// or colon with space: ruleID1, ruleID2: some comment
149+
var lastParamIndex = paramsList.size() - 1;
150+
var lastParamRaw = paramsList.get(lastParamIndex);
151+
var lastParam = lastParamRaw.split("(:?\\s)", 0)[0].trim();
152+
paramsList.set(lastParamIndex, lastParam);
153+
}
154+
return paramsList;
142155
}
143156

144157
private String parseNoQaComment(String noSonarCommentLine) {
@@ -169,7 +182,8 @@ private static Stream<String> parseParamsString(String paramsString) {
169182
return Stream.of();
170183
}
171184

172-
return Stream.of(paramsString.split(",", -1))
185+
var paramsArray = paramsString.split(",", -1);
186+
return Stream.of(paramsArray)
173187
.map(String::trim);
174188
}
175189
}

python-frontend/src/test/java/org/sonar/plugins/python/api/nosonar/NoSonarInfoParserTest.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ void noNoSonarCommentTest() {
3131
var parser = new NoSonarInfoParser();
3232
var parsingResult = parser.parse("# comment string");
3333
Assertions.assertThat(parsingResult).isNotPresent();
34+
parsingResult = parser.parse("# noqal");
35+
Assertions.assertThat(parsingResult).isNotPresent();
3436
}
3537

3638
@ParameterizedTest
@@ -95,7 +97,7 @@ private static Stream<Arguments> provideParserParameters() {
9597
),
9698
Arguments.of(
9799
"# noqa: some text",
98-
new NoSonarLineInfo(Set.of("some text"))
100+
new NoSonarLineInfo(Set.of("some"))
99101
),
100102
Arguments.of(
101103
"# noqa: a,b",
@@ -116,6 +118,18 @@ private static Stream<Arguments> provideParserParameters() {
116118
Arguments.of(
117119
"# noqa some text",
118120
new NoSonarLineInfo(Set.of())
121+
),
122+
Arguments.of(
123+
"# noqa: rule1, rule2 some explanation",
124+
new NoSonarLineInfo(Set.of("rule1", "rule2"))
125+
),
126+
Arguments.of(
127+
"# noqa: rule1, rule2: some explanation",
128+
new NoSonarLineInfo(Set.of("rule1", "rule2"))
129+
),
130+
Arguments.of(
131+
"# noqa; noqa; noqa; noqa; noqa",
132+
new NoSonarLineInfo(Set.of())
119133
)
120134
);
121135
}
@@ -143,6 +157,9 @@ private static Stream<Arguments> provideValidationParameters() {
143157
Arguments.of("# noqa: one,two", false),
144158
Arguments.of("# noqa:one,two", false),
145159
Arguments.of("# noqa- one,two", false),
160+
Arguments.of("# noqa: one,two some text", false),
161+
Arguments.of("# noqa: one some text", false),
162+
Arguments.of("# noqa:", false),
146163

147164
Arguments.of("# something unrelated", false),
148165

@@ -154,9 +171,7 @@ private static Stream<Arguments> provideValidationParameters() {
154171
Arguments.of("# NOSONAR(a (b))", true),
155172
Arguments.of("# noqa: one,", true),
156173
Arguments.of("# noqa: ,two", true),
157-
Arguments.of("# noqa: , ", true),
158-
Arguments.of("# noqa: one,two some text", true),
159-
Arguments.of("# noqa: one some text", true)
174+
Arguments.of("# noqa: , ", true)
160175
);
161176
}
162177

0 commit comments

Comments
 (0)