Skip to content

Commit 131106a

Browse files
vilchik-elenapynicolas
authored andcommitted
SONARPY-129 Support NOSONAR to ignore specific issues on the same line (SonarSource#34)
1 parent 8021f09 commit 131106a

6 files changed

Lines changed: 96 additions & 4 deletions

File tree

its/plugin/profiles/nosonar.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<profile>
2+
<name>nosonar</name>
3+
<language>py</language>
4+
<rules>
5+
<rule>
6+
<repositoryKey>python</repositoryKey>
7+
<key>PrintStatementUsage</key>
8+
<priority>INFO</priority>
9+
</rule>
10+
</rules>
11+
</profile>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
print "Hello"
2+
print "Hello" # NOSONAR
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* SonarQube Python Plugin
3+
* Copyright (C) 2012-2016 SonarSource SA
4+
* mailto:contact AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package com.sonar.python.it.plugin;
21+
22+
import com.sonar.orchestrator.Orchestrator;
23+
import com.sonar.orchestrator.build.SonarRunner;
24+
import java.io.File;
25+
import org.junit.BeforeClass;
26+
import org.junit.ClassRule;
27+
import org.junit.Test;
28+
import org.sonar.wsclient.Sonar;
29+
import org.sonar.wsclient.services.Measure;
30+
import org.sonar.wsclient.services.Resource;
31+
import org.sonar.wsclient.services.ResourceQuery;
32+
33+
import static org.fest.assertions.Assertions.assertThat;
34+
35+
public class NoSonarTest {
36+
37+
private static final String PROJECT_KEY = "nosonar";
38+
39+
@ClassRule
40+
public static Orchestrator orchestrator = Tests.ORCHESTRATOR;
41+
42+
private static Sonar wsClient;
43+
44+
@BeforeClass
45+
public static void startServer() {
46+
orchestrator.getServer().provisionProject(PROJECT_KEY, PROJECT_KEY);
47+
orchestrator.getServer().associateProjectToQualityProfile(PROJECT_KEY, "py", "nosonar");
48+
SonarRunner build = SonarRunner.create()
49+
.setProjectDir(new File("projects", PROJECT_KEY))
50+
.setProjectKey(PROJECT_KEY)
51+
.setProjectName(PROJECT_KEY)
52+
.setProjectVersion("1.0-SNAPSHOT")
53+
.setSourceDirs(".");
54+
orchestrator.executeBuild(build);
55+
56+
wsClient = orchestrator.getServer().getWsClient();
57+
}
58+
59+
@Test
60+
public void test_nosonar() {
61+
assertThat(getProjectMeasure("violations").getValue()).isEqualTo(1.0);
62+
}
63+
64+
65+
/* Helper methods */
66+
67+
private Measure getProjectMeasure(String metricKey) {
68+
Resource resource = wsClient.find(ResourceQuery.createForMetrics(PROJECT_KEY, metricKey));
69+
return resource == null ? null : resource.getMeasure(metricKey);
70+
}
71+
}

its/plugin/src/test/java/com/sonar/python/it/plugin/Tests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
MetricsTest.class,
4040
CoverageTest.class,
4141
PylintReportTest.class,
42-
TestReportTest.class
42+
TestReportTest.class,
43+
NoSonarTest.class
4344
})
4445
public class Tests {
4546

@@ -48,6 +49,7 @@ public class Tests {
4849
.addPlugin(FileLocation.byWildcardMavenFilename(new File("../../sonar-python-plugin/target"), "sonar-python-plugin-*.jar"))
4950
.restoreProfileAtStartup(FileLocation.of("profiles/no_rule.xml"))
5051
.restoreProfileAtStartup(FileLocation.of("profiles/pylint.xml"))
52+
.restoreProfileAtStartup(FileLocation.of("profiles/nosonar.xml"))
5153
.build();
5254

5355
public static Integer getProjectMeasure(String projectKey, String metricKey) {

sonar-python-plugin/src/main/java/org/sonar/plugins/python/PythonSquidSensor.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.sonar.api.batch.sensor.issue.NewIssue;
4242
import org.sonar.api.batch.sensor.issue.NewIssueLocation;
4343
import org.sonar.api.ce.measure.RangeDistributionBuilder;
44+
import org.sonar.api.issue.NoSonarFilter;
4445
import org.sonar.api.measures.CoreMetrics;
4546
import org.sonar.api.measures.FileLinesContextFactory;
4647
import org.sonar.api.measures.Metric;
@@ -70,15 +71,17 @@ public final class PythonSquidSensor implements Sensor {
7071

7172
private final Checks<SquidAstVisitor<Grammar>> checks;
7273
private final FileLinesContextFactory fileLinesContextFactory;
74+
private final NoSonarFilter noSonarFilter;
7375

7476
private SensorContext context;
7577
private AstScanner<Grammar> scanner;
7678

77-
public PythonSquidSensor(FileLinesContextFactory fileLinesContextFactory, CheckFactory checkFactory) {
79+
public PythonSquidSensor(FileLinesContextFactory fileLinesContextFactory, CheckFactory checkFactory, NoSonarFilter noSonarFilter) {
7880
this.checks = checkFactory
7981
.<SquidAstVisitor<Grammar>>create(CheckList.REPOSITORY_KEY)
8082
.addAnnotatedChecks(CheckList.getChecks());
8183
this.fileLinesContextFactory = fileLinesContextFactory;
84+
this.noSonarFilter = noSonarFilter;
8285
}
8386

8487

@@ -103,13 +106,13 @@ public void execute(SensorContext context) {
103106
scanner.scanFiles(Lists.newArrayList(context.fileSystem().files(p.and(p.hasType(InputFile.Type.MAIN), p.hasLanguage(Python.KEY)))));
104107

105108
Collection<SourceCode> squidSourceFiles = scanner.getIndex().search(new QueryByType(SourceFile.class));
109+
save(squidSourceFiles);
106110
savePreciseIssues(
107111
visitors
108112
.stream()
109113
.filter(v -> v instanceof PythonCheck)
110114
.map(v -> (PythonCheck) v)
111115
.collect(Collectors.toList()));
112-
save(squidSourceFiles);
113116

114117
(new PythonCoverageSensor()).execute(context, linesOfCode);
115118
}
@@ -160,6 +163,8 @@ private void save(Collection<SourceCode> squidSourceFiles) {
160163

161164
InputFile inputFile = context.fileSystem().inputFile(context.fileSystem().predicates().is(new java.io.File(squidFile.getKey())));
162165

166+
noSonarFilter.noSonarInFile(inputFile, squidFile.getNoSonarTagLines());
167+
163168
saveFilesComplexityDistribution(inputFile, squidFile);
164169
saveFunctionsComplexityDistribution(inputFile, squidFile);
165170
saveMeasures(inputFile, squidFile);

sonar-python-plugin/src/test/java/org/sonar/plugins/python/PythonSquidSensorTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.sonar.api.batch.sensor.issue.Issue;
3636
import org.sonar.api.batch.sensor.issue.IssueLocation;
3737
import org.sonar.api.internal.google.common.base.Charsets;
38+
import org.sonar.api.issue.NoSonarFilter;
3839
import org.sonar.api.measures.CoreMetrics;
3940
import org.sonar.api.measures.FileLinesContext;
4041
import org.sonar.api.measures.FileLinesContextFactory;
@@ -136,7 +137,7 @@ private PythonSquidSensor sensor() {
136137
FileLinesContext fileLinesContext = mock(FileLinesContext.class);
137138
when(fileLinesContextFactory.createFor(Mockito.any(InputFile.class))).thenReturn(fileLinesContext);
138139
CheckFactory checkFactory = new CheckFactory(activeRules);
139-
return new PythonSquidSensor(fileLinesContextFactory, checkFactory);
140+
return new PythonSquidSensor(fileLinesContextFactory, checkFactory, new NoSonarFilter());
140141
}
141142

142143
private InputFile inputFile(String name) {

0 commit comments

Comments
 (0)