Skip to content

Commit cbef8fd

Browse files
authored
SONARPY-2193: Update sonarlint-core.version to v10 (major) (#2068)
1 parent 83dbc83 commit cbef8fd

File tree

6 files changed

+131
-84
lines changed

6 files changed

+131
-84
lines changed

its/plugin/it-python-plugin-test/src/test/java/com/sonar/python/it/plugin/IPythonTest.java renamed to its/plugin/it-python-plugin-test/src/test/java/com/sonar/python/it/plugin/SonarLintIPythonTest.java

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,88 +27,114 @@
2727
import java.nio.file.Files;
2828
import java.nio.file.Path;
2929
import java.util.ArrayList;
30-
import java.util.Collections;
3130
import java.util.HashMap;
3231
import java.util.List;
3332
import java.util.Map;
33+
import java.util.Optional;
34+
import java.util.Set;
35+
import java.util.concurrent.ExecutionException;
3436
import java.util.stream.Stream;
37+
import javax.annotation.Nullable;
3538
import org.junit.jupiter.api.AfterAll;
3639
import org.junit.jupiter.api.BeforeAll;
3740
import org.junit.jupiter.api.Test;
3841
import org.junit.jupiter.api.io.TempDir;
3942
import org.sonar.api.batch.fs.InputFile;
40-
import org.sonarsource.sonarlint.core.StandaloneSonarLintEngineImpl;
43+
import org.sonarsource.sonarlint.core.analysis.AnalysisEngine;
44+
import org.sonarsource.sonarlint.core.analysis.api.ActiveRule;
45+
import org.sonarsource.sonarlint.core.analysis.api.AnalysisConfiguration;
46+
import org.sonarsource.sonarlint.core.analysis.api.AnalysisEngineConfiguration;
4147
import org.sonarsource.sonarlint.core.analysis.api.ClientInputFile;
4248
import org.sonarsource.sonarlint.core.analysis.api.ClientModuleFileSystem;
4349
import org.sonarsource.sonarlint.core.analysis.api.ClientModuleInfo;
50+
import org.sonarsource.sonarlint.core.analysis.api.Issue;
4451
import org.sonarsource.sonarlint.core.analysis.api.WithTextRange;
45-
import org.sonarsource.sonarlint.core.client.api.common.analysis.Issue;
46-
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneAnalysisConfiguration;
47-
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneGlobalConfiguration;
48-
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneSonarLintEngine;
49-
import org.sonarsource.sonarlint.core.commons.IssueSeverity;
50-
import org.sonarsource.sonarlint.core.commons.Language;
51-
import org.sonarsource.sonarlint.core.commons.log.ClientLogOutput;
52+
import org.sonarsource.sonarlint.core.analysis.command.AnalyzeCommand;
53+
import org.sonarsource.sonarlint.core.analysis.command.RegisterModuleCommand;
54+
import org.sonarsource.sonarlint.core.commons.api.SonarLanguage;
55+
import org.sonarsource.sonarlint.core.commons.log.LogOutput;
56+
import org.sonarsource.sonarlint.core.commons.log.LogOutput.Level;
57+
import org.sonarsource.sonarlint.core.commons.log.SonarLintLogger;
58+
import org.sonarsource.sonarlint.core.commons.progress.ProgressMonitor;
59+
import org.sonarsource.sonarlint.core.plugin.commons.PluginsLoader;
5260

5361
import static org.assertj.core.api.Assertions.assertThat;
5462
import static org.assertj.core.api.Assertions.tuple;
5563

56-
class IPythonTest {
64+
class SonarLintIPythonTest {
5765

5866
@TempDir
59-
public static Path TEMP;
67+
public static Path temp;
6068

61-
private static StandaloneSonarLintEngine sonarlintEngine;
69+
private static AnalysisEngine sonarlintEngine;
70+
private final ProgressMonitor progressMonitor = new ProgressMonitor(null);
6271

6372
@BeforeAll
64-
static void prepare() throws Exception {
65-
StandaloneGlobalConfiguration sonarLintConfig = StandaloneGlobalConfiguration.builder()
66-
.addPlugin(TestsUtils.PLUGIN_LOCATION.getFile().toPath())
67-
.setSonarLintUserHome(TEMP)
68-
.addEnabledLanguage(Language.IPYTHON)
69-
.setLogOutput((formattedMessage, level) -> {
70-
/* Don't pollute logs */ })
71-
.setModulesProvider(Collections::emptyList)
73+
static void prepare() {
74+
var sonarLintConfig = AnalysisEngineConfiguration.builder()
75+
.setWorkDir(temp)
7276
.build();
73-
sonarlintEngine = new StandaloneSonarLintEngineImpl(sonarLintConfig);
77+
78+
var logOutput = new LogOutput() {
79+
@Override
80+
public void log(String formattedMessage, Level level, @Nullable String stacktrace) {
81+
/* Don't pollute logs */
82+
}
83+
};
84+
SonarLintLogger.setTarget(logOutput);
85+
var pluginJarLocation = Set.of(TestsUtils.PLUGIN_LOCATION.getFile().toPath());
86+
var enabledLanguages = Set.of(SonarLanguage.IPYTHON);
87+
var pluginConfiguration = new PluginsLoader.Configuration(pluginJarLocation, enabledLanguages, false, Optional.empty());
88+
var pluginLoader = new PluginsLoader().load(pluginConfiguration, Set.of());
89+
90+
sonarlintEngine = new AnalysisEngine(sonarLintConfig, pluginLoader.getLoadedPlugins(), logOutput);
7491
}
7592

7693
@AfterAll
7794
static void stop() {
95+
SonarLintLogger.setTarget(null);
7896
sonarlintEngine.stop();
7997
}
8098

8199
@Test
82-
void shouldRaiseIssues() {
100+
void shouldRaiseIssues() throws InterruptedException, ExecutionException {
83101
var inputFile = createInputFile(Path.of("projects/ipynb_project/file1.ipynb"), "file1.ipynb", false);
84102
var issues = new ArrayList<Issue>();
85103

86-
var configuration = StandaloneAnalysisConfiguration.builder()
104+
var configuration = AnalysisConfiguration.builder()
87105
.setBaseDir(Path.of("projects/ipynb_project"))
88106
.addInputFile(inputFile)
89-
.setModuleKey("myModule")
107+
.addActiveRules(new ActiveRule("ipython:PrintStatementUsage", SonarLanguage.IPYTHON.name()),
108+
new ActiveRule("ipython:S1172", SonarLanguage.IPYTHON.name()),
109+
new ActiveRule("ipython:S930", SonarLanguage.IPYTHON.name()),
110+
new ActiveRule("ipython:S1542", SonarLanguage.IPYTHON.name()),
111+
new ActiveRule("ipython:BackticksUsage", SonarLanguage.IPYTHON.name()))
90112
.build();
91113

92-
var logsByLevel = new HashMap<ClientLogOutput.Level, List<String>>();
114+
var logsByLevel = new HashMap<Level, List<String>>();
93115
var logOutput = createClientLogOutput(logsByLevel);
94116
var clientFileSystem = createClientFileSystem(inputFile);
95-
sonarlintEngine.declareModule(new ClientModuleInfo("myModule", clientFileSystem));
96-
sonarlintEngine.analyze(configuration, issues::add, logOutput, null);
97-
117+
sonarlintEngine.post(new RegisterModuleCommand(new ClientModuleInfo("myModule", clientFileSystem)), progressMonitor).get();
118+
var command = new AnalyzeCommand("myModule", configuration, issues::add, logOutput);
119+
sonarlintEngine.post(command, progressMonitor).get();
98120
assertThat(issues)
99-
.extracting(Issue::getRuleKey, WithTextRange::getStartLine, i -> i.getInputFile().uri(), Issue::getSeverity)
121+
.extracting(Issue::getRuleKey, WithTextRange::getStartLine, i -> i.getInputFile().uri())
100122
.containsOnly(
101-
tuple("ipython:PrintStatementUsage", 32, inputFile.uri(), IssueSeverity.MAJOR),
102-
tuple("ipython:S1172", 40, inputFile.uri(), IssueSeverity.MAJOR),
103-
tuple("ipython:S930", 41, inputFile.uri(), IssueSeverity.BLOCKER),
104-
tuple("ipython:S1172", 42, inputFile.uri(), IssueSeverity.MAJOR),
105-
tuple("ipython:S1542", 57, inputFile.uri(), IssueSeverity.MAJOR),
106-
tuple("ipython:BackticksUsage", 58, inputFile.uri(), IssueSeverity.BLOCKER)
107-
);
123+
tuple("ipython:PrintStatementUsage", 32, inputFile.uri()),
124+
tuple("ipython:S1172", 40, inputFile.uri()),
125+
tuple("ipython:S930", 41, inputFile.uri()),
126+
tuple("ipython:S1172", 42, inputFile.uri()),
127+
tuple("ipython:S1542", 57, inputFile.uri()),
128+
tuple("ipython:BackticksUsage", 58, inputFile.uri()));
108129
}
109130

110-
private static ClientLogOutput createClientLogOutput(Map<ClientLogOutput.Level, List<String>> logsByLevel) {
111-
return (s, level) -> logsByLevel.computeIfAbsent(level, (k) -> new ArrayList<>()).add(s);
131+
private static LogOutput createClientLogOutput(Map<Level, List<String>> logsByLevel) {
132+
return new LogOutput() {
133+
@Override
134+
public void log(String formattedMessage, Level level, @Nullable String stacktrace) {
135+
logsByLevel.computeIfAbsent(level, k -> new ArrayList<>()).add(formattedMessage);
136+
}
137+
};
112138
}
113139

114140
private static ClientModuleFileSystem createClientFileSystem(ClientInputFile... inputFiles) {

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

Lines changed: 62 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -28,81 +28,101 @@
2828
import java.nio.file.Files;
2929
import java.nio.file.Path;
3030
import java.util.ArrayList;
31-
import java.util.Collections;
3231
import java.util.HashMap;
3332
import java.util.List;
3433
import java.util.Map;
34+
import java.util.Optional;
35+
import java.util.Set;
36+
import java.util.concurrent.ExecutionException;
3537
import java.util.stream.Stream;
38+
import javax.annotation.Nullable;
3639
import org.apache.commons.io.FileUtils;
3740
import org.junit.jupiter.api.AfterAll;
3841
import org.junit.jupiter.api.BeforeAll;
3942
import org.junit.jupiter.api.Test;
4043
import org.junit.jupiter.api.io.TempDir;
4144
import org.sonar.api.batch.fs.InputFile;
42-
import org.sonarsource.sonarlint.core.StandaloneSonarLintEngineImpl;
45+
import org.sonarsource.sonarlint.core.analysis.AnalysisEngine;
46+
import org.sonarsource.sonarlint.core.analysis.api.ActiveRule;
47+
import org.sonarsource.sonarlint.core.analysis.api.AnalysisConfiguration;
48+
import org.sonarsource.sonarlint.core.analysis.api.AnalysisEngineConfiguration;
4349
import org.sonarsource.sonarlint.core.analysis.api.ClientInputFile;
4450
import org.sonarsource.sonarlint.core.analysis.api.ClientModuleFileSystem;
4551
import org.sonarsource.sonarlint.core.analysis.api.ClientModuleInfo;
46-
import org.sonarsource.sonarlint.core.client.api.common.analysis.Issue;
47-
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneAnalysisConfiguration;
48-
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneGlobalConfiguration;
49-
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneSonarLintEngine;
50-
import org.sonarsource.sonarlint.core.commons.IssueSeverity;
51-
import org.sonarsource.sonarlint.core.commons.Language;
52-
import org.sonarsource.sonarlint.core.commons.log.ClientLogOutput;
52+
import org.sonarsource.sonarlint.core.analysis.api.Issue;
53+
import org.sonarsource.sonarlint.core.analysis.command.AnalyzeCommand;
54+
import org.sonarsource.sonarlint.core.analysis.command.RegisterModuleCommand;
55+
import org.sonarsource.sonarlint.core.commons.api.SonarLanguage;
56+
import org.sonarsource.sonarlint.core.commons.log.LogOutput;
57+
import org.sonarsource.sonarlint.core.commons.log.LogOutput.Level;
58+
import org.sonarsource.sonarlint.core.commons.log.SonarLintLogger;
59+
import org.sonarsource.sonarlint.core.commons.progress.ProgressMonitor;
60+
import org.sonarsource.sonarlint.core.plugin.commons.PluginsLoader;
5361

5462
import static org.assertj.core.api.Assertions.assertThat;
5563
import static org.assertj.core.api.Assertions.tuple;
5664

5765
class SonarLintTest {
5866

5967
@TempDir
60-
public static Path TEMP;
68+
public static Path temp;
6169

62-
private static StandaloneSonarLintEngine sonarlintEngine;
70+
private static AnalysisEngine sonarlintEngine;
71+
private final ProgressMonitor progressMonitor = new ProgressMonitor(null);
6372

6473
private static File baseDir;
6574

6675
@BeforeAll
67-
static void prepare() throws Exception {
68-
StandaloneGlobalConfiguration sonarLintConfig = StandaloneGlobalConfiguration.builder()
69-
.addPlugin(TestsUtils.PLUGIN_LOCATION.getFile().toPath())
70-
.setSonarLintUserHome(TEMP)
71-
.addEnabledLanguage(Language.PYTHON)
72-
.setLogOutput((formattedMessage, level) -> {
73-
/* Don't pollute logs */ })
74-
.setModulesProvider(Collections::emptyList)
76+
static void prepare() {
77+
var sonarLintConfig = AnalysisEngineConfiguration.builder()
78+
.setWorkDir(temp)
7579
.build();
76-
sonarlintEngine = new StandaloneSonarLintEngineImpl(sonarLintConfig);
77-
baseDir = TEMP.toFile();
80+
81+
var logOutput = new LogOutput() {
82+
@Override
83+
public void log(String formattedMessage, Level level, @Nullable String stacktrace) {
84+
/* Don't pollute logs */
85+
}
86+
};
87+
SonarLintLogger.setTarget(logOutput);
88+
var pluginJarLocation = Set.of(TestsUtils.PLUGIN_LOCATION.getFile().toPath());
89+
var enabledLanguages = Set.of(SonarLanguage.PYTHON);
90+
var pluginConfiguration = new PluginsLoader.Configuration(pluginJarLocation, enabledLanguages, false, Optional.empty());
91+
var pluginLoader = new PluginsLoader().load(pluginConfiguration, Set.of());
92+
93+
sonarlintEngine = new AnalysisEngine(sonarLintConfig, pluginLoader.getLoadedPlugins(), logOutput);
94+
baseDir = temp.toFile();
7895
}
7996

8097
@AfterAll
8198
static void stop() {
99+
SonarLintLogger.setTarget(null);
82100
sonarlintEngine.stop();
83101
}
84102

85103
@Test
86-
void should_raise_issues() throws IOException {
104+
void should_raise_issues() throws IOException, InterruptedException, ExecutionException {
87105
ClientInputFile inputFile = prepareInputFile("foo.py",
88106
"def fooBar():\n"
89107
+ " `1` \n"
90108
+ " `1` #NOSONAR\n",
91109
false);
92110

93111
List<Issue> issues = new ArrayList<>();
94-
StandaloneAnalysisConfiguration configuration =
95-
StandaloneAnalysisConfiguration.builder()
96-
.setBaseDir(baseDir.toPath())
97-
.addInputFile(inputFile)
98-
.setModuleKey("myModule")
99-
.build();
100-
101-
Map<ClientLogOutput.Level, List<String>> logsByLevel = new HashMap<>();
102-
ClientLogOutput logOutput = (s, level) -> {
103-
List<String> logs = logsByLevel.getOrDefault(level, new ArrayList<>());
104-
logs.add(s);
105-
logsByLevel.putIfAbsent(level, logs);
112+
var configuration = AnalysisConfiguration.builder()
113+
.setBaseDir(baseDir.toPath())
114+
.addInputFile(inputFile)
115+
.addActiveRules(
116+
new ActiveRule("python:S1542", SonarLanguage.PYTHON.name()),
117+
new ActiveRule("python:BackticksUsage", SonarLanguage.PYTHON.name()))
118+
.build();
119+
120+
Map<Level, List<String>> logsByLevel = new HashMap<>();
121+
LogOutput logOutput = new LogOutput() {
122+
@Override
123+
public void log(String formattedMessage, Level level, @Nullable String stacktrace) {
124+
logsByLevel.computeIfAbsent(level, k -> new ArrayList<>()).add(formattedMessage);
125+
}
106126
};
107127
ClientModuleFileSystem clientFileSystem = new ClientModuleFileSystem() {
108128
@Override
@@ -115,13 +135,14 @@ public Stream<ClientInputFile> files() {
115135
return Stream.of(inputFile);
116136
}
117137
};
118-
sonarlintEngine.declareModule(new ClientModuleInfo("myModule", clientFileSystem));
119-
sonarlintEngine.analyze(configuration, issues::add, logOutput, null);
120-
121-
assertThat(logsByLevel.get(ClientLogOutput.Level.WARN)).containsExactly("No workDir in SonarLint");
122-
assertThat(issues).extracting("ruleKey", "startLine", "inputFile.path", "severity").containsOnly(
123-
tuple("python:BackticksUsage", 2, inputFile.uri().getPath(), IssueSeverity.BLOCKER),
124-
tuple("python:S1542", 1, inputFile.uri().getPath(), IssueSeverity.MAJOR));
138+
sonarlintEngine.post(new RegisterModuleCommand(new ClientModuleInfo("myModule", clientFileSystem)), progressMonitor).get();
139+
var command = new AnalyzeCommand("myModule", configuration, issues::add, logOutput);
140+
sonarlintEngine.post(command, progressMonitor).get();
141+
142+
assertThat(logsByLevel.get(Level.WARN)).containsExactly("No workDir in SonarLint");
143+
assertThat(issues).extracting("ruleKey", "textRange.startLine", "inputFile.path").containsOnly(
144+
tuple("python:BackticksUsage", 2, inputFile.uri().getPath()),
145+
tuple("python:S1542", 1, inputFile.uri().getPath()));
125146
}
126147

127148
private static ClientInputFile prepareInputFile(String relativePath, String content, final boolean isTest) throws IOException {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
CPDTest.class,
3030
CustomRulesTest.class,
3131
Flake8ReportTest.class,
32-
IPythonTest.class,
32+
SonarLintIPythonTest.class,
3333
MetricsTest.class,
3434
MypyReportTest.class,
3535
NoSonarTest.class,

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
<sonar.api.version>10.11.0.2468</sonar.api.version>
100100
<sonar.orchestrator.version>5.0.0.2065</sonar.orchestrator.version>
101101
<sonar-analyzer-commons.version>2.14.0.3087</sonar-analyzer-commons.version>
102-
<sonarlint-core.version>8.19.0.72745</sonarlint-core.version>
102+
<sonarlint-core.version>10.7.1.79146</sonarlint-core.version>
103103
<sslr.version>1.24.0.633</sslr.version>
104104
<protobuf.version>4.28.2</protobuf.version>
105105
<woodstox.version>6.2.7</woodstox.version>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import java.util.Map;
2626
import org.junit.jupiter.api.Test;
2727
import org.sonar.api.batch.fs.InputFile;
28-
import org.sonar.api.internal.apachecommons.lang.StringUtils;
28+
import org.sonar.api.internal.apachecommons.lang3.StringUtils;
2929
import org.sonar.python.IPythonLocation;
3030

3131
import static org.assertj.core.api.Assertions.assertThat;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
import org.sonarsource.sonarlint.core.analysis.api.ClientInputFile;
105105
import org.sonarsource.sonarlint.core.analysis.container.analysis.filesystem.FileMetadata;
106106
import org.sonarsource.sonarlint.core.analysis.container.analysis.filesystem.SonarLintInputFile;
107-
import org.sonarsource.sonarlint.core.commons.Language;
107+
import org.sonarsource.sonarlint.core.commons.api.SonarLanguage;
108108

109109
import static java.nio.charset.StandardCharsets.UTF_8;
110110
import static org.assertj.core.api.Assertions.assertThat;
@@ -1404,7 +1404,7 @@ private void setup_quickfix_sensor() throws IOException {
14041404

14051405
SonarLintInputFile sonarFile = new SonarLintInputFile(clientFile, metadataGenerator);
14061406
sonarFile.setType(Type.MAIN);
1407-
sonarFile.setLanguage(Language.PYTHON);
1407+
sonarFile.setLanguage(SonarLanguage.PYTHON);
14081408

14091409
context.fileSystem().add(sonarFile);
14101410
sensor().execute(context);

0 commit comments

Comments
 (0)