aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java3
-rw-r--r--sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java28
-rw-r--r--sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptorTest.java29
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java8
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractSensorWrapper.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java36
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java2
7 files changed, 87 insertions, 21 deletions
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
index a2d03803220..0c1aa2d81e0 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
@@ -44,7 +44,8 @@ public class OneIssuePerLineSensor implements Sensor {
descriptor
.name("One Issue Per Line")
.onlyOnLanguages(Xoo.KEY, Xoo2.KEY)
- .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY, XooRulesDefinition.XOO2_REPOSITORY);
+ .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY, XooRulesDefinition.XOO2_REPOSITORY)
+ .processesFilesIndependently();
}
@Override
diff --git a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java
index e0819050190..558dfe17c1f 100644
--- a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java
+++ b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java
@@ -27,16 +27,17 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
+
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.config.Configuration;
public class DefaultSensorDescriptor implements SensorDescriptor {
- public static final Set<String> SENSORS_ONLY_CHANGED_IN_PR = Collections.unmodifiableSet(Stream.of(
- "CSS Metrics",
- "CSS Rules",
- "HTML",
- "XML Sensor"
+ public static final Set<String> HARDCODED_INDEPENDENT_FILE_SENSORS = Collections.unmodifiableSet(Stream.of(
+ "CSS Metrics",
+ "CSS Rules",
+ "HTML",
+ "XML Sensor"
).collect(Collectors.toSet()));
private String name;
@@ -45,7 +46,7 @@ public class DefaultSensorDescriptor implements SensorDescriptor {
private String[] ruleRepositories = new String[0];
private boolean global = false;
private Predicate<Configuration> configurationPredicate;
- private boolean onlyChangedFilesInPullRequests = false;
+ private boolean processesFilesIndependently = false;
public String name() {
return name;
@@ -72,15 +73,15 @@ public class DefaultSensorDescriptor implements SensorDescriptor {
return global;
}
- public boolean onlyChangedFilesInPullRequest() {
- return onlyChangedFilesInPullRequests;
+ public boolean isProcessesFilesIndependently() {
+ return processesFilesIndependently;
}
@Override
public DefaultSensorDescriptor name(String name) {
- // TODO: Add onlyChangedFilesInPullRequest into API and implement it at sensors
- if (SENSORS_ONLY_CHANGED_IN_PR.contains(name)) {
- onlyChangedFilesInPullRequests = true;
+ // TODO: Remove this hardcoded list once all plugins will implement the new API "processFilesIndependently"
+ if (HARDCODED_INDEPENDENT_FILE_SENSORS.contains(name)) {
+ processesFilesIndependently = true;
}
this.name = name;
return this;
@@ -126,4 +127,9 @@ public class DefaultSensorDescriptor implements SensorDescriptor {
return this;
}
+ @Override
+ public SensorDescriptor processesFilesIndependently() {
+ this.processesFilesIndependently = true;
+ return this;
+ }
}
diff --git a/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptorTest.java b/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptorTest.java
index e34c5385cad..a5cd716a04e 100644
--- a/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptorTest.java
+++ b/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptorTest.java
@@ -33,6 +33,19 @@ import static org.assertj.core.api.Assertions.assertThat;
public class DefaultSensorDescriptorTest {
@Test
+ public void describe_defaults() {
+ DefaultSensorDescriptor descriptor = new DefaultSensorDescriptor();
+ descriptor
+ .name("Foo");
+
+ assertThat(descriptor.name()).isEqualTo("Foo");
+ assertThat(descriptor.languages()).isEmpty();
+ assertThat(descriptor.type()).isNull();
+ assertThat(descriptor.ruleRepositories()).isEmpty();
+ assertThat(descriptor.isProcessesFilesIndependently()).isFalse();
+ }
+
+ @Test
public void describe() {
DefaultSensorDescriptor descriptor = new DefaultSensorDescriptor();
descriptor
@@ -40,7 +53,8 @@ public class DefaultSensorDescriptorTest {
.onlyOnLanguage("java")
.onlyOnFileType(InputFile.Type.MAIN)
.onlyWhenConfiguration(c -> c.hasKey("sonar.foo.reportPath2") && c.hasKey("sonar.foo.reportPath"))
- .createIssuesForRuleRepository("squid-java");
+ .createIssuesForRuleRepository("squid-java")
+ .processesFilesIndependently();
assertThat(descriptor.name()).isEqualTo("Foo");
assertThat(descriptor.languages()).containsOnly("java");
@@ -51,31 +65,32 @@ public class DefaultSensorDescriptorTest {
settings.setProperty("sonar.foo.reportPath2", "foo");
assertThat(descriptor.configurationPredicate().test(settings.asConfig())).isTrue();
assertThat(descriptor.ruleRepositories()).containsOnly("squid-java");
+ assertThat(descriptor.isProcessesFilesIndependently()).isTrue();
}
@Test
- @UseDataProvider("sensorsOnlyChangedInPR")
+ @UseDataProvider("independentFilesSensors")
public void describe_with_restricted_sensor(String sensorName) {
DefaultSensorDescriptor descriptor = new DefaultSensorDescriptor();
descriptor
.name(sensorName);
- assertThat(descriptor.onlyChangedFilesInPullRequest()).isTrue();
+ assertThat(descriptor.isProcessesFilesIndependently()).isTrue();
}
@Test
- @UseDataProvider("sensorsOnlyChangedInPR")
+ @UseDataProvider("independentFilesSensors")
public void describe_with_non_restricted_sensor(String sensorName) {
DefaultSensorDescriptor descriptor = new DefaultSensorDescriptor();
descriptor
.name(sensorName + "other");
- assertThat(descriptor.onlyChangedFilesInPullRequest()).isFalse();
+ assertThat(descriptor.isProcessesFilesIndependently()).isFalse();
}
@DataProvider
- public static Object[][] sensorsOnlyChangedInPR() {
- return new Object[][] {DefaultSensorDescriptor.SENSORS_ONLY_CHANGED_IN_PR.toArray()};
+ public static Object[][] independentFilesSensors() {
+ return new Object[][] {DefaultSensorDescriptor.HARDCODED_INDEPENDENT_FILE_SENSORS.toArray()};
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java
index 0117afae923..72e8ec2547c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java
@@ -83,4 +83,12 @@ public interface SensorDescriptor {
* @since 6.5
*/
SensorDescriptor onlyWhenConfiguration(Predicate<Configuration> predicate);
+
+ /**
+ * Advertise that this sensor process each file independently. It means executing the sensor twice with FileSystem=[FileA] and FileSystem=[FileB] will produce the same result
+ * than executing the sensor only once with FileSystem=[FileA,FileB].
+ * This will allow the platform to optimize sensor execution.
+ * @since 9.3
+ */
+ SensorDescriptor processesFilesIndependently();
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractSensorWrapper.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractSensorWrapper.java
index 21e5308d66e..2df1bec52c7 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractSensorWrapper.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractSensorWrapper.java
@@ -56,7 +56,7 @@ public abstract class AbstractSensorWrapper<G extends ProjectSensor> {
}
public void analyse() {
- boolean sensorIsRestricted = descriptor.onlyChangedFilesInPullRequest() && isPullRequest;
+ boolean sensorIsRestricted = descriptor.isProcessesFilesIndependently() && isPullRequest;
if (sensorIsRestricted) {
LOGGER.info("Sensor {} is restricted to changed files only", descriptor.name());
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java
index bab0b6757ce..7f7484e6159 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java
@@ -20,11 +20,14 @@
package org.sonar.scanner.mediumtest.branch;
import com.google.common.collect.ImmutableMap;
+
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.List;
+
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
@@ -33,6 +36,7 @@ import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.FileMetadata;
import org.sonar.api.notifications.AnalysisWarnings;
+import org.sonar.api.utils.log.LogTester;
import org.sonar.scanner.mediumtest.AnalysisResult;
import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.scanner.protocol.output.ScannerReport;
@@ -50,12 +54,16 @@ public class BranchMediumTest {
private static final String PROJECT_KEY = "sample";
private static final String FILE_PATH = "HelloJava.xoo";
private static final String FILE_CONTENT = "xoooo";
+ public static final String ONE_ISSUE_PER_LINE_IS_RESTRICTED_TO_CHANGED_FILES_ONLY = "Sensor One Issue Per Line is restricted to changed files only";
private File baseDir;
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@Rule
+ public LogTester logTester = new LogTester();
+
+ @Rule
public ScannerMediumTester tester = new ScannerMediumTester()
.registerPlugin("xoo", new XooPlugin())
.addDefaultQProfile("xoo", "Sonar Way")
@@ -100,6 +108,34 @@ public class BranchMediumTest {
}
@Test
+ public void shouldSkipSensorForUnchangedFilesOnPr() throws Exception {
+ AnalysisResult result = getResult(tester
+ .setBranchName("myBranch")
+ .setBranchTarget("master")
+ .setBranchType(BranchType.PULL_REQUEST));
+ final DefaultInputFile file = (DefaultInputFile) result.inputFile(FILE_PATH);
+
+ List<ScannerReport.Issue> issues = result.issuesFor(file);
+ assertThat(issues).isEmpty();
+
+ assertThat(logTester.logs()).contains(ONE_ISSUE_PER_LINE_IS_RESTRICTED_TO_CHANGED_FILES_ONLY);
+ }
+
+ @Test
+ public void shouldNotSkipSensorForUnchangedFilesOnBranch() throws Exception {
+ AnalysisResult result = getResult(tester
+ .setBranchName("myBranch")
+ .setBranchTarget("master")
+ .setBranchType(BranchType.BRANCH));
+ final DefaultInputFile file = (DefaultInputFile) result.inputFile(FILE_PATH);
+
+ List<ScannerReport.Issue> issues = result.issuesFor(file);
+ assertThat(issues).isNotEmpty();
+
+ assertThat(logTester.logs()).doesNotContain(ONE_ISSUE_PER_LINE_IS_RESTRICTED_TO_CHANGED_FILES_ONLY);
+ }
+
+ @Test
public void verify_metadata() {
String branchName = "feature";
String branchTarget = "branch-1.x";
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java
index 820a528c040..e99bc31d5fa 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java
@@ -177,7 +177,7 @@ public class ModuleSensorsExecutorTest {
@DataProvider
public static Object[][] sensorsOnlyChangedInPR() {
- return new Object[][] {DefaultSensorDescriptor.SENSORS_ONLY_CHANGED_IN_PR.toArray()};
+ return new Object[][] {DefaultSensorDescriptor.HARDCODED_INDEPENDENT_FILE_SENSORS.toArray()};
}
private ModuleSensorsExecutor createModuleExecutor(String sensorName) throws IOException {