Skip to content

Commit 30629fb

Browse files
SONARPY-898 Avoid failing on older SonarLint (#1002)
1 parent 605c07e commit 30629fb

File tree

11 files changed

+54
-76
lines changed

11 files changed

+54
-76
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import org.sonar.plugins.python.indexer.SonarLintPythonIndexer;
3636
import org.sonar.plugins.python.pylint.PylintRulesDefinition;
3737
import org.sonar.plugins.python.pylint.PylintSensor;
38-
import org.sonar.plugins.python.warnings.DefaultAnalysisWarningsWrapper;
38+
import org.sonar.plugins.python.warnings.AnalysisWarningsWrapper;
3939
import org.sonar.plugins.python.xunit.PythonXUnitSensor;
4040

4141
public class PythonPlugin implements Plugin {
@@ -72,11 +72,11 @@ public void define(Context context) {
7272
PythonProfile.class,
7373

7474
PythonSensor.class,
75-
PythonRuleRepository.class);
75+
PythonRuleRepository.class,
76+
AnalysisWarningsWrapper.class);
7677

7778
SonarRuntime sonarRuntime = context.getRuntime();
7879
if (sonarRuntime.getProduct() != SonarProduct.SONARLINT) {
79-
context.addExtension(DefaultAnalysisWarningsWrapper.class);
8080
addCoberturaExtensions(context);
8181
addXUnitExtensions(context);
8282
addPylintExtensions(context);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public void execute(SensorContext context) {
6262
processReports(context, reports);
6363
} catch (Exception e) {
6464
LOG.warn("Cannot read report '{}', the following exception occurred: {}", reportPath, e.getMessage());
65-
analysisWarnings.addWarning(String.format("An error occurred while trying to import %s report(s): '%s'", reportType, reportPath));
65+
analysisWarnings.addUnique(String.format("An error occurred while trying to import %s report(s): '%s'", reportType, reportPath));
6666
}
6767
}
6868

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

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import org.sonar.api.batch.sensor.SensorDescriptor;
3939
import org.sonar.api.issue.NoSonarFilter;
4040
import org.sonar.api.measures.FileLinesContextFactory;
41-
import org.sonar.api.notifications.AnalysisWarnings;
4241
import org.sonar.api.utils.log.Logger;
4342
import org.sonar.api.utils.log.Loggers;
4443
import org.sonar.plugins.python.api.ProjectPythonVersion;
@@ -49,6 +48,7 @@
4948
import org.sonar.plugins.python.api.tree.FileInput;
5049
import org.sonar.plugins.python.indexer.PythonIndexer;
5150
import org.sonar.plugins.python.indexer.SonarQubePythonIndexer;
51+
import org.sonar.plugins.python.warnings.AnalysisWarningsWrapper;
5252
import org.sonar.python.checks.CheckList;
5353
import org.sonar.python.parser.PythonParser;
5454
import org.sonar.python.semantic.ProjectLevelSymbolTable;
@@ -67,8 +67,7 @@ public final class PythonSensor implements Sensor {
6767
private final FileLinesContextFactory fileLinesContextFactory;
6868
private final NoSonarFilter noSonarFilter;
6969
private final PythonIndexer indexer;
70-
@Nullable
71-
private final AnalysisWarnings analysisWarnings;
70+
private final AnalysisWarningsWrapper analysisWarnings;
7271
private static final Logger LOG = Loggers.get(PythonSensor.class);
7372
static final String UNSET_VERSION_WARNING =
7473
"Your code is analyzed as compatible with python 2 and 3 by default. This will prevent the detection of issues specific to python 2 or python 3." +
@@ -77,22 +76,23 @@ public final class PythonSensor implements Sensor {
7776
/**
7877
* Constructor to be used by pico if neither PythonCustomRuleRepository nor PythonIndexer are to be found and injected.
7978
*/
80-
public PythonSensor(FileLinesContextFactory fileLinesContextFactory, CheckFactory checkFactory, NoSonarFilter noSonarFilter, AnalysisWarnings analysisWarnings) {
79+
public PythonSensor(FileLinesContextFactory fileLinesContextFactory, CheckFactory checkFactory,
80+
NoSonarFilter noSonarFilter, AnalysisWarningsWrapper analysisWarnings) {
8181
this(fileLinesContextFactory, checkFactory, noSonarFilter, null, null, analysisWarnings);
8282
}
8383

8484
public PythonSensor(FileLinesContextFactory fileLinesContextFactory, CheckFactory checkFactory, NoSonarFilter noSonarFilter,
85-
PythonIndexer indexer) {
86-
this(fileLinesContextFactory, checkFactory, noSonarFilter, null, indexer, null);
85+
PythonCustomRuleRepository[] customRuleRepositories, AnalysisWarningsWrapper analysisWarnings) {
86+
this(fileLinesContextFactory, checkFactory, noSonarFilter, customRuleRepositories, null, analysisWarnings);
8787
}
8888

8989
public PythonSensor(FileLinesContextFactory fileLinesContextFactory, CheckFactory checkFactory, NoSonarFilter noSonarFilter,
90-
PythonCustomRuleRepository[] customRuleRepositories, AnalysisWarnings analysisWarnings) {
91-
this(fileLinesContextFactory, checkFactory, noSonarFilter, customRuleRepositories, null, analysisWarnings);
90+
PythonIndexer indexer, AnalysisWarningsWrapper analysisWarnings) {
91+
this(fileLinesContextFactory, checkFactory, noSonarFilter, null, indexer, analysisWarnings);
9292
}
9393

9494
public PythonSensor(FileLinesContextFactory fileLinesContextFactory, CheckFactory checkFactory, NoSonarFilter noSonarFilter,
95-
@Nullable PythonCustomRuleRepository[] customRuleRepositories, @Nullable PythonIndexer indexer, @Nullable AnalysisWarnings analysisWarnings) {
95+
@Nullable PythonCustomRuleRepository[] customRuleRepositories, @Nullable PythonIndexer indexer, AnalysisWarningsWrapper analysisWarnings) {
9696
this.checks = new PythonChecks(checkFactory)
9797
.addChecks(CheckList.REPOSITORY_KEY, CheckList.getChecks())
9898
.addCustomChecks(customRuleRepositories);
@@ -118,9 +118,7 @@ public void execute(SensorContext context) {
118118
Optional<String> pythonVersionParameter = context.config().get(PYTHON_VERSION_KEY);
119119
if (!pythonVersionParameter.isPresent() && context.runtime().getProduct() != SonarProduct.SONARLINT) {
120120
LOG.warn(UNSET_VERSION_WARNING);
121-
if (analysisWarnings != null) {
122-
analysisWarnings.addUnique(UNSET_VERSION_WARNING);
123-
}
121+
analysisWarnings.addUnique(UNSET_VERSION_WARNING);
124122
}
125123
pythonVersionParameter.ifPresent(value -> ProjectPythonVersion.setCurrentVersions(PythonVersionUtils.fromString(value)));
126124
PythonIndexer pythonIndexer = this.indexer != null ? this.indexer : new SonarQubePythonIndexer(mainFiles);

sonar-python-plugin/src/main/java/org/sonar/plugins/python/coverage/PythonCoverageSensor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ private void warnDeprecatedPropertyUsage(Configuration config) {
9898
if (config.hasKey(REPORT_PATH_KEY)) {
9999
String msg = "Property 'sonar.python.coverage.reportPath' has been removed. Please use 'sonar.python.coverage.reportPaths' instead.";
100100
LOG.warn(msg);
101-
analysisWarnings.addWarning(msg);
101+
analysisWarnings.addUnique(msg);
102102
}
103103
}
104104

sonar-python-plugin/src/main/java/org/sonar/plugins/python/warnings/AnalysisWarningsWrapper.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
*/
2020
package org.sonar.plugins.python.warnings;
2121

22-
import org.sonar.api.batch.InstantiationStrategy;
23-
import org.sonar.api.batch.ScannerSide;
22+
import javax.annotation.Nullable;
23+
import org.sonar.api.notifications.AnalysisWarnings;
24+
import org.sonar.api.scanner.ScannerSide;
25+
import org.sonarsource.api.sonarlint.SonarLintSide;
2426

2527
/**
2628
* As {@link org.sonar.api.notifications.AnalysisWarnings} has been added in SQ 7.4, previous version of the API
@@ -29,7 +31,21 @@
2931
* warnings to the underlying {@link org.sonar.api.notifications.AnalysisWarnings} or do nothing when not available.
3032
*/
3133
@ScannerSide
32-
@InstantiationStrategy("PER_BATCH")
33-
public interface AnalysisWarningsWrapper {
34-
void addWarning(String text);
34+
@SonarLintSide(lifespan = SonarLintSide.MULTIPLE_ANALYSES)
35+
public class AnalysisWarningsWrapper {
36+
private final AnalysisWarnings analysisWarnings;
37+
38+
public AnalysisWarningsWrapper(@Nullable AnalysisWarnings analysisWarnings) {
39+
this.analysisWarnings = analysisWarnings;
40+
}
41+
42+
public AnalysisWarningsWrapper() {
43+
this.analysisWarnings = null;
44+
}
45+
46+
public void addUnique(String text) {
47+
if (analysisWarnings != null) {
48+
this.analysisWarnings.addUnique(text);
49+
}
50+
}
3551
}

sonar-python-plugin/src/main/java/org/sonar/plugins/python/warnings/DefaultAnalysisWarningsWrapper.java

Lines changed: 0 additions & 36 deletions
This file was deleted.

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import org.sonar.api.utils.Version;
3030
import org.sonar.api.utils.log.LogTester;
3131
import org.sonar.api.utils.log.LoggerLevel;
32-
import org.sonar.plugins.python.warnings.DefaultAnalysisWarningsWrapper;
32+
import org.sonar.plugins.python.warnings.AnalysisWarningsWrapper;
3333

3434
import static org.assertj.core.api.Assertions.assertThat;
3535
import static org.mockito.Mockito.mock;
@@ -45,8 +45,8 @@ public void testGetExtensions() {
4545
Version v79 = Version.create(7, 9);
4646
SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(v79, SonarQubeSide.SERVER, SonarEdition.DEVELOPER);
4747
assertThat(extensions(runtime)).hasSize(21);
48-
assertThat(extensions(runtime)).contains(DefaultAnalysisWarningsWrapper.class);
49-
assertThat(extensions(SonarRuntimeImpl.forSonarLint(v79))).hasSize(6);
48+
assertThat(extensions(runtime)).contains(AnalysisWarningsWrapper.class);
49+
assertThat(extensions(SonarRuntimeImpl.forSonarLint(v79))).hasSize(7);
5050
}
5151

5252
@Test

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
import org.sonar.api.measures.CoreMetrics;
5959
import org.sonar.api.measures.FileLinesContext;
6060
import org.sonar.api.measures.FileLinesContextFactory;
61-
import org.sonar.api.notifications.AnalysisWarnings;
6261
import org.sonar.api.rule.RuleKey;
6362
import org.sonar.api.utils.Version;
6463
import org.sonar.api.utils.log.LogTester;
@@ -73,6 +72,7 @@
7372
import org.sonar.plugins.python.indexer.PythonIndexer;
7473
import org.sonar.plugins.python.indexer.SonarLintPythonIndexer;
7574
import org.sonar.plugins.python.indexer.TestModuleFileSystem;
75+
import org.sonar.plugins.python.warnings.AnalysisWarningsWrapper;
7676
import org.sonar.python.checks.CheckList;
7777

7878
import static org.assertj.core.api.Assertions.assertThat;
@@ -131,7 +131,7 @@ public void scanFile(PythonVisitorContext visitorContext) {
131131

132132
private ActiveRules activeRules;
133133

134-
private final AnalysisWarnings analysisWarning = mock(AnalysisWarnings.class);
134+
private final AnalysisWarningsWrapper analysisWarning = mock(AnalysisWarningsWrapper.class);
135135

136136
@org.junit.Rule
137137
public LogTester logTester = new LogTester();
@@ -319,7 +319,7 @@ public void cross_files_issues_only_one_file_analyzed() {
319319
// "mod.py" created but not added to context
320320
InputFile modFile = createInputFile("mod.py");
321321
PythonIndexer pythonIndexer = pythonIndexer(Arrays.asList(mainFile, modFile));
322-
sensor(CUSTOM_RULES, pythonIndexer, null).execute(context);
322+
sensor(null, pythonIndexer, analysisWarning).execute(context);
323323
assertThat(context.allIssues()).hasSize(1);
324324
Issue issue = context.allIssues().iterator().next();
325325
assertThat(issue.primaryLocation().inputComponent()).isEqualTo(mainFile);
@@ -341,7 +341,7 @@ public void no_indexer_when_project_too_large_sonarlint() {
341341

342342
InputFile mainFile = inputFile("main.py");
343343
PythonIndexer pythonIndexer = pythonIndexer(Collections.singletonList(mainFile));
344-
sensor(CUSTOM_RULES, pythonIndexer, null).execute(context);
344+
sensor(CUSTOM_RULES, pythonIndexer, analysisWarning).execute(context);
345345
assertThat(context.allIssues()).isEmpty();
346346
assertThat(logTester.logs(LoggerLevel.DEBUG)).contains("Project symbol table deactivated due to project size (total number of lines is 4, maximum for indexing is 1)");
347347
assertThat(logTester.logs(LoggerLevel.DEBUG)).contains("Update \"sonar.python.sonarlint.indexing.maxlines\" to set a different limit.");
@@ -358,7 +358,7 @@ public void loop_in_class_hierarchy() {
358358
InputFile mainFile = inputFile("modA.py");
359359
InputFile modFile = inputFile("modB.py");
360360
PythonIndexer pythonIndexer = pythonIndexer(Arrays.asList(mainFile, modFile));
361-
sensor(null, pythonIndexer, null).execute(context);
361+
sensor(null, pythonIndexer, analysisWarning).execute(context);
362362

363363
assertThat(context.allIssues()).hasSize(1);
364364
}
@@ -494,7 +494,7 @@ public void cancelled_analysis() {
494494
InputFile inputFile = inputFile(FILE_1);
495495
activeRules = (new ActiveRulesBuilder()).build();
496496
context.setCancelled(true);
497-
sensor(null, null, null).execute(context);
497+
sensor(null, null, analysisWarning).execute(context);
498498
assertThat(context.measure(inputFile.key(), CoreMetrics.NCLOC)).isNull();
499499
assertThat(context.allAnalysisErrors()).isEmpty();
500500
}
@@ -562,20 +562,20 @@ private PythonSensor sensor() {
562562
return sensor(CUSTOM_RULES, null, analysisWarning);
563563
}
564564

565-
private PythonSensor sensor(@Nullable PythonCustomRuleRepository[] customRuleRepositories, @Nullable PythonIndexer indexer, @Nullable AnalysisWarnings analysisWarnings) {
565+
private PythonSensor sensor(@Nullable PythonCustomRuleRepository[] customRuleRepositories, @Nullable PythonIndexer indexer, AnalysisWarningsWrapper analysisWarnings) {
566566
FileLinesContextFactory fileLinesContextFactory = mock(FileLinesContextFactory.class);
567567
FileLinesContext fileLinesContext = mock(FileLinesContext.class);
568568
when(fileLinesContextFactory.createFor(Mockito.any(InputFile.class))).thenReturn(fileLinesContext);
569569
CheckFactory checkFactory = new CheckFactory(activeRules);
570570
if (indexer == null && customRuleRepositories == null) {
571571
return new PythonSensor(fileLinesContextFactory, checkFactory, mock(NoSonarFilter.class), analysisWarnings);
572572
}
573-
if (indexer != null && customRuleRepositories == null) {
574-
return new PythonSensor(fileLinesContextFactory, checkFactory, mock(NoSonarFilter.class), indexer);
575-
}
576573
if (indexer == null) {
577574
return new PythonSensor(fileLinesContextFactory, checkFactory, mock(NoSonarFilter.class), customRuleRepositories, analysisWarnings);
578575
}
576+
if (customRuleRepositories == null) {
577+
return new PythonSensor(fileLinesContextFactory, checkFactory, mock(NoSonarFilter.class), indexer, analysisWarnings);
578+
}
579579
return new PythonSensor(fileLinesContextFactory, checkFactory, mock(NoSonarFilter.class), customRuleRepositories, indexer, analysisWarnings);
580580
}
581581

sonar-python-plugin/src/test/java/org/sonar/plugins/python/coverage/PythonCoverageSensorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ public void test_unique_report() {
198198
List<Integer> actual = IntStream.range(1, 18).mapToObj(line -> context.lineHits(FILE4_KEY, line)).collect(Collectors.toList());
199199
Integer coverageAtLine6 = actual.get(5);
200200
assertThat(coverageAtLine6).isEqualTo(1);
201-
verify(analysisWarnings, times(1)).addWarning(eq("Property 'sonar.python.coverage.reportPath' has been removed. Please use 'sonar.python.coverage.reportPaths' instead."));
201+
verify(analysisWarnings, times(1)).addUnique(eq("Property 'sonar.python.coverage.reportPath' has been removed. Please use 'sonar.python.coverage.reportPaths' instead."));
202202
}
203203

204204
@Test

sonar-python-plugin/src/test/java/org/sonar/plugins/python/warnings/AnalysisWarningsWrapperTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ public class AnalysisWarningsWrapperTest {
3232
@Test
3333
public void test() {
3434
AnalysisWarnings analysisWarnings = spy(AnalysisWarnings.class);
35-
DefaultAnalysisWarningsWrapper defaultAnalysisWarningsWrapper = new DefaultAnalysisWarningsWrapper(analysisWarnings);
36-
defaultAnalysisWarningsWrapper.addWarning("abcd");
37-
defaultAnalysisWarningsWrapper.addWarning("def");
35+
AnalysisWarningsWrapper defaultAnalysisWarningsWrapper = new AnalysisWarningsWrapper(analysisWarnings);
36+
defaultAnalysisWarningsWrapper.addUnique("abcd");
37+
defaultAnalysisWarningsWrapper.addUnique("def");
3838
verify(analysisWarnings, times(2)).addUnique(anyString());
3939
}
4040

0 commit comments

Comments
 (0)