From 8f4042903f34e2869d647ce70403a21d891a950d Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 22 Jul 2025 16:16:18 +0200 Subject: [PATCH 1/2] JS-793 Add SensorContext as parameter to JsAnalysisConsumer::doneAnalysis (#5568) --- .../samples/javascript/consumer/Consumer.java | 3 +- .../javascript/consumer/ConsumerTest.java | 2 +- .../javascript/api/JsAnalysisConsumer.java | 3 +- .../analysis/AnalysisConsumers.java | 5 +- .../javascript/analysis/JsTsSensor.java | 4 +- .../JavaScriptProfilesDefinitionTest.java | 7 +- .../analysis/AnalysisConsumersTest.java | 3 +- .../javascript/analysis/JsTsSensorTest.java | 87 ++++++++++--------- 8 files changed, 62 insertions(+), 52 deletions(-) diff --git a/its/plugin/plugins/consumer-plugin/src/main/java/org/sonar/samples/javascript/consumer/Consumer.java b/its/plugin/plugins/consumer-plugin/src/main/java/org/sonar/samples/javascript/consumer/Consumer.java index 337d85c1827..89513d12c40 100644 --- a/its/plugin/plugins/consumer-plugin/src/main/java/org/sonar/samples/javascript/consumer/Consumer.java +++ b/its/plugin/plugins/consumer-plugin/src/main/java/org/sonar/samples/javascript/consumer/Consumer.java @@ -20,6 +20,7 @@ import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.batch.sensor.SensorContext; import org.sonar.plugins.javascript.api.JsAnalysisConsumer; import org.sonar.plugins.javascript.api.JsFile; @@ -37,7 +38,7 @@ public void accept(JsFile jsFile) { } @Override - public void doneAnalysis() { + public void doneAnalysis(SensorContext context) { LOG.info("Done analysis"); done = true; } diff --git a/its/plugin/plugins/consumer-plugin/src/test/java/org/sonar/samples/javascript/consumer/ConsumerTest.java b/its/plugin/plugins/consumer-plugin/src/test/java/org/sonar/samples/javascript/consumer/ConsumerTest.java index 9dd9b9ccd63..506f10e88aa 100644 --- a/its/plugin/plugins/consumer-plugin/src/test/java/org/sonar/samples/javascript/consumer/ConsumerTest.java +++ b/its/plugin/plugins/consumer-plugin/src/test/java/org/sonar/samples/javascript/consumer/ConsumerTest.java @@ -25,7 +25,7 @@ class ConsumerTest { @Test void test() { var consumer = new Consumer(); - consumer.doneAnalysis(); + consumer.doneAnalysis(null); assertTrue(consumer.isDone()); } } diff --git a/sonar-plugin/api/src/main/java/org/sonar/plugins/javascript/api/JsAnalysisConsumer.java b/sonar-plugin/api/src/main/java/org/sonar/plugins/javascript/api/JsAnalysisConsumer.java index 2bac1e3fcab..9940bf01794 100644 --- a/sonar-plugin/api/src/main/java/org/sonar/plugins/javascript/api/JsAnalysisConsumer.java +++ b/sonar-plugin/api/src/main/java/org/sonar/plugins/javascript/api/JsAnalysisConsumer.java @@ -16,6 +16,7 @@ */ package org.sonar.plugins.javascript.api; +import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.scanner.ScannerSide; import org.sonarsource.api.sonarlint.SonarLintSide; @@ -36,7 +37,7 @@ public interface JsAnalysisConsumer { * * Called at the end of the analysis. */ - void doneAnalysis(); + void doneAnalysis(SensorContext context); /** * Called only once per analysis. diff --git a/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/analysis/AnalysisConsumers.java b/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/analysis/AnalysisConsumers.java index 37853074f68..ad5b55becda 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/analysis/AnalysisConsumers.java +++ b/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/analysis/AnalysisConsumers.java @@ -19,6 +19,7 @@ import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.scanner.ScannerSide; import org.sonar.plugins.javascript.api.JsAnalysisConsumer; import org.sonar.plugins.javascript.api.JsFile; @@ -49,8 +50,8 @@ public void accept(JsFile jsFile) { } @Override - public void doneAnalysis() { - consumers.forEach(JsAnalysisConsumer::doneAnalysis); + public void doneAnalysis(SensorContext context) { + consumers.forEach(c -> c.doneAnalysis(context)); } @Override diff --git a/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/analysis/JsTsSensor.java b/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/analysis/JsTsSensor.java index 8147f7cc6fb..f0479398a81 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/analysis/JsTsSensor.java +++ b/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/analysis/JsTsSensor.java @@ -127,7 +127,7 @@ protected void analyzeFiles(List inputFiles) throws IOException { analysis.initialize(context, checks, consumers, analysisWarnings); var issues = analysis.analyzeFiles(inputFiles); - consumers.doneAnalysis(); + consumers.doneAnalysis(context.getSensorContext()); ExternalIssueRepository.dedupeAndSaveESLintIssues( this.context.getSensorContext(), externalIssues, @@ -140,7 +140,7 @@ protected void analyzeFiles(List inputFiles) throws IOException { var handler = new AnalyzeProjectHandler(context, inputFiles, externalIssues); bridgeServer.analyzeProject(handler); new PluginTelemetry(context.getSensorContext(), bridgeServer).reportTelemetry(); - consumers.doneAnalysis(); + consumers.doneAnalysis(context.getSensorContext()); } catch (Exception e) { LOG.error("Failed to get response from analysis", e); throw e; diff --git a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/JavaScriptProfilesDefinitionTest.java b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/JavaScriptProfilesDefinitionTest.java index f25a57653b5..0c3ce20320a 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/JavaScriptProfilesDefinitionTest.java +++ b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/JavaScriptProfilesDefinitionTest.java @@ -86,7 +86,8 @@ public void register(RegistrarContext registrarContext) { } }, } - ).define(context); + ) + .define(context); } @Test @@ -103,7 +104,7 @@ void sonar_way_js() { .containsOnly(CheckList.JS_REPOSITORY_KEY, "additionalRepository"); assertThat(profile.rules().size()).isGreaterThan(100); - assertThat(deprecatedRulesInProfile(profile, deprecatedJsRules)).hasSize(1); + assertThat(deprecatedRulesInProfile(profile, deprecatedJsRules)).isEmpty(); } private List deprecatedRulesInProfile( @@ -133,7 +134,7 @@ void sonar_way_ts() { .extracting(BuiltInQualityProfilesDefinition.BuiltInActiveRule::ruleKey) .contains("S5122"); - assertThat(deprecatedRulesInProfile(profile, deprecatedTsRules)).hasSize(1); + assertThat(deprecatedRulesInProfile(profile, deprecatedTsRules)).isEmpty(); } @Test diff --git a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/analysis/AnalysisConsumersTest.java b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/analysis/AnalysisConsumersTest.java index f30ed0aa2cf..1d8e05dbe2c 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/analysis/AnalysisConsumersTest.java +++ b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/analysis/AnalysisConsumersTest.java @@ -21,6 +21,7 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.slf4j.event.Level; +import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.testfixtures.log.LogTesterJUnit5; import org.sonar.plugins.javascript.api.JsAnalysisConsumer; import org.sonar.plugins.javascript.api.JsFile; @@ -86,7 +87,7 @@ static class Consumer implements JsAnalysisConsumer { public void accept(JsFile jsFile) {} @Override - public void doneAnalysis() {} + public void doneAnalysis(SensorContext context) {} @Override public boolean isEnabled() { diff --git a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/analysis/JsTsSensorTest.java b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/analysis/JsTsSensorTest.java index 39a24bb379d..41220566b9f 100644 --- a/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/analysis/JsTsSensorTest.java +++ b/sonar-plugin/sonar-javascript-plugin/src/test/java/org/sonar/plugins/javascript/analysis/JsTsSensorTest.java @@ -71,6 +71,7 @@ import org.sonar.api.batch.rule.CheckFactory; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.rule.internal.NewActiveRule; +import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.cache.ReadCache; import org.sonar.api.batch.sensor.cache.WriteCache; import org.sonar.api.batch.sensor.highlighting.TypeOfText; @@ -171,16 +172,16 @@ void setUp() throws Exception { ) ); when(bridgeServerMock.loadTsConfig(any())).thenAnswer(invocationOnMock -> { - String tsConfigPath = (String) invocationOnMock.getArguments()[0]; - FilePredicates predicates = context.fileSystem().predicates(); - List files = StreamSupport.stream( - context.fileSystem().inputFiles(predicates.hasLanguage("ts")).spliterator(), - false - ) - .map(InputFile::absolutePath) - .toList(); - return new TsConfigFile(tsConfigPath, files, emptyList()); - }); + String tsConfigPath = (String) invocationOnMock.getArguments()[0]; + FilePredicates predicates = context.fileSystem().predicates(); + List files = StreamSupport.stream( + context.fileSystem().inputFiles(predicates.hasLanguage("ts")).spliterator(), + false + ) + .map(InputFile::absolutePath) + .toList(); + return new TsConfigFile(tsConfigPath, files, emptyList()); + }); when(bridgeServerMock.createTsConfigFile(any())).thenReturn( new TsConfigFile(tempFolder.newFile().getAbsolutePath(), emptyList(), emptyList()) ); @@ -625,11 +626,10 @@ void should_raise_a_parsing_error() throws IOException { setSonarLintRuntime(context); createTsConfigFile(); when(bridgeServerMock.analyzeJsTs(any())).thenReturn( - new Gson() - .fromJson( - "{ parsingError: { line: 3, message: \"Parse error message\", code: \"Parsing\"} }", - AnalysisResponse.class - ) + new Gson().fromJson( + "{ parsingError: { line: 3, message: \"Parse error message\", code: \"Parsing\"} }", + AnalysisResponse.class + ) ); createInputFile(context); createSonarLintSensor().execute(context); @@ -648,8 +648,10 @@ void should_raise_a_parsing_error() throws IOException { void should_raise_a_parsing_error_without_line() throws IOException { createVueInputFile(); when(bridgeServerMock.analyzeJsTs(any())).thenReturn( - new Gson() - .fromJson("{ parsingError: { message: \"Parse error message\"} }", AnalysisResponse.class) + new Gson().fromJson( + "{ parsingError: { message: \"Parse error message\"} }", + AnalysisResponse.class + ) ); createInputFile(context); var tsProgram = new TsProgram("1", List.of(), List.of()); @@ -727,7 +729,7 @@ void should_send_skipAst_flag_when_consumer_is_disabled() throws Exception { public void accept(JsFile jsFile) {} @Override - public void doneAnalysis() {} + public void doneAnalysis(SensorContext ctx) {} @Override public boolean isEnabled() { @@ -841,7 +843,9 @@ void should_send_content_when_not_utf8() throws Exception { ArgumentCaptor captor = ArgumentCaptor.forClass(JsAnalysisRequest.class); createSensor().execute(ctx); verify(bridgeServerMock, times(2)).analyzeJsTs(captor.capture()); - assertThat(captor.getAllValues()).extracting(c -> c.fileContent()).contains(content); + assertThat(captor.getAllValues()) + .extracting(c -> c.fileContent()) + .contains(content); } @Test @@ -1140,8 +1144,10 @@ void should_fail_fast() throws Exception { void should_fail_fast_with_parsing_error_without_line() throws IOException { createVueInputFile(); when(bridgeServerMock.analyzeJsTs(any())).thenReturn( - new Gson() - .fromJson("{ parsingError: { message: \"Parse error message\"} }", AnalysisResponse.class) + new Gson().fromJson( + "{ parsingError: { message: \"Parse error message\"} }", + AnalysisResponse.class + ) ); MapSettings settings = new MapSettings().setProperty("sonar.internal.analysis.failFast", true); context.setSettings(settings); @@ -1294,7 +1300,7 @@ public void accept(JsFile jsFile) { } @Override - public void doneAnalysis() { + public void doneAnalysis(SensorContext ctx) { done = true; } }; @@ -1372,7 +1378,7 @@ public void accept(JsFile jsFile) { } @Override - public void doneAnalysis() { + public void doneAnalysis(SensorContext ctx) { done = true; } }; @@ -1398,7 +1404,7 @@ public void accept(JsFile jsFile) { } @Override - public void doneAnalysis() { + public void doneAnalysis(SensorContext ctx) { done = true; } }; @@ -1462,7 +1468,7 @@ public void accept(JsFile jsFile) { } @Override - public void doneAnalysis() { + public void doneAnalysis(SensorContext ctx) { done = true; } }; @@ -1516,7 +1522,7 @@ public void accept(JsFile jsFile) { } @Override - public void doneAnalysis() { + public void doneAnalysis(SensorContext ctx) { done = true; } @@ -1635,21 +1641,20 @@ private BridgeServer.AnalysisResponseDTO createResponse(List } private BridgeServer.AnalysisResponseDTO createResponse() { - return new Gson() - .fromJson( - "{" + - createIssues() + - "," + - createHighlights() + - "," + - createMetrics() + - "," + - createCpdTokens() + - "," + - createHighlightedSymbols() + - "}", - BridgeServer.AnalysisResponseDTO.class - ); + return new Gson().fromJson( + "{" + + createIssues() + + "," + + createHighlights() + + "," + + createMetrics() + + "," + + createCpdTokens() + + "," + + createHighlightedSymbols() + + "}", + BridgeServer.AnalysisResponseDTO.class + ); } private String createIssues() { From ec66fb727b37ace220efd6526a7a0bca20b58694 Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 24 Jul 2025 11:00:28 +0200 Subject: [PATCH 2/2] JS-817 Prepare next development iteration for v10.X (#5571) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f19ea9368c8..d97b7547ae5 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ - 10.25.0-SNAPSHOT + 10.26.0-SNAPSHOT SonarJS SonarQube JavaScript Plugin