aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2016-02-18 15:13:05 +0100
committerJulien HENRY <julien.henry@sonarsource.com>2016-02-19 10:40:05 +0100
commit0c2b2d0afe3f28f7075fcadb78a81c59a21b34d3 (patch)
tree3993f596df253de5d2aa56f50e3b70872960d279
parentef6ebbd8c6a82b3371163509e5e022eccd79a243 (diff)
downloadsonarqube-0c2b2d0afe3f28f7075fcadb78a81c59a21b34d3.tar.gz
sonarqube-0c2b2d0afe3f28f7075fcadb78a81c59a21b34d3.zip
SONAR-7366 Expose InputModule in SensorContext
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerModuleSensor.java46
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java5
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java22
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java10
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnModuleMediumTest.java84
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java9
10 files changed, 151 insertions, 42 deletions
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerModuleSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerModuleSensor.java
index 94ba20d7bc9..4b700f4cb61 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerModuleSensor.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerModuleSensor.java
@@ -19,13 +19,10 @@
*/
package org.sonar.xoo.rule;
-import org.sonar.api.batch.Sensor;
-import org.sonar.api.batch.SensorContext;
-import org.sonar.api.batch.fs.FileSystem;
-import org.sonar.api.batch.rule.ActiveRules;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.issue.Issuable;
-import org.sonar.api.resources.Project;
+import org.sonar.api.batch.sensor.Sensor;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorDescriptor;
+import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.xoo.Xoo;
@@ -33,27 +30,28 @@ public class OneIssuePerModuleSensor implements Sensor {
public static final String RULE_KEY = "OneIssuePerModule";
- private final ResourcePerspectives perspectives;
- private final FileSystem fs;
- private final ActiveRules activeRules;
-
- public OneIssuePerModuleSensor(ResourcePerspectives perspectives, FileSystem fs, ActiveRules activeRules) {
- this.perspectives = perspectives;
- this.fs = fs;
- this.activeRules = activeRules;
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("One Issue Per Module")
+ .onlyOnLanguages(Xoo.KEY)
+ .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY);
}
@Override
- public void analyse(Project project, SensorContext context) {
- Issuable issuable = perspectives.as(Issuable.class, project);
- issuable.addIssue(issuable.newIssueBuilder()
- .ruleKey(RuleKey.of(XooRulesDefinition.XOO_REPOSITORY, RULE_KEY))
- .message("This issue is generated on each module")
- .build());
+ public void execute(SensorContext context) {
+ analyse(context, Xoo.KEY, XooRulesDefinition.XOO_REPOSITORY);
}
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return fs.hasFiles(fs.predicates().hasLanguages(Xoo.KEY)) && (activeRules.find(RuleKey.of(XooRulesDefinition.XOO_REPOSITORY, RULE_KEY)) != null);
+ private void analyse(SensorContext context, String language, String repo) {
+ RuleKey ruleKey = RuleKey.of(repo, RULE_KEY);
+ NewIssue newIssue = context.newIssue();
+ newIssue
+ .forRule(ruleKey)
+ .at(newIssue.newLocation()
+ .on(context.module())
+ .message("This issue is generated on each module"))
+ .save();
}
+
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java
index 51ca8699152..33a56f3e5ee 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java
@@ -29,6 +29,7 @@ import org.sonar.api.batch.SonarIndex;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.InputPath;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.internal.SensorStorage;
@@ -53,10 +54,10 @@ public class DeprecatedSensorContext extends DefaultSensorContext implements Sen
private final Project project;
private final CoverageExclusions coverageFilter;
- public DeprecatedSensorContext(SonarIndex index, Project project, Settings settings, FileSystem fs, ActiveRules activeRules,
+ public DeprecatedSensorContext(InputModule module, SonarIndex index, Project project, Settings settings, FileSystem fs, ActiveRules activeRules,
AnalysisMode analysisMode, CoverageExclusions coverageFilter,
SensorStorage sensorStorage) {
- super(settings, fs, activeRules, analysisMode, sensorStorage);
+ super(module, settings, fs, activeRules, analysisMode, sensorStorage);
this.index = index;
this.project = project;
this.coverageFilter = coverageFilter;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
index 7e9e33e572c..04d2b8843e7 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
@@ -34,12 +34,11 @@ import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.AnalysisMode;
+import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.InputPath;
import org.sonar.api.batch.fs.TextPointer;
import org.sonar.api.batch.fs.TextRange;
-import org.sonar.api.batch.fs.internal.DefaultInputDir;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.batch.issue.IssueCache;
@@ -119,23 +118,26 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver {
return reportComponents.get(key);
}
- public List<BatchReport.Issue> issuesFor(InputPath inputPath) {
+ public List<BatchReport.Issue> issuesFor(InputComponent inputComponent) {
+ int ref = reportComponents.get(inputComponent.key()).getRef();
+ return issuesFor(ref);
+ }
+
+ public List<BatchReport.Issue> issuesFor(Component reportComponent) {
+ int ref = reportComponent.getRef();
+ return issuesFor(ref);
+ }
+
+ private List<BatchReport.Issue> issuesFor(int ref) {
List<BatchReport.Issue> result = Lists.newArrayList();
- int ref = reportComponents.get(key(inputPath)).getRef();
try (CloseableIterator<BatchReport.Issue> it = reader.readComponentIssues(ref)) {
while (it.hasNext()) {
result.add(it.next());
}
- } catch (Exception e) {
- throw new IllegalStateException("Can't read issues for " + inputPath.absolutePath(), e);
}
return result;
}
- private static String key(InputPath inputPath) {
- return inputPath instanceof InputFile ? ((DefaultInputFile) inputPath).key() : ((DefaultInputDir) inputPath).key();
- }
-
public Collection<InputFile> inputFiles() {
return inputFiles.values();
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
index 972a7681ff6..9f16173f65e 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
@@ -35,6 +35,7 @@ import org.sonar.batch.bootstrap.ExtensionUtils;
import org.sonar.batch.deprecated.DeprecatedSensorContext;
import org.sonar.batch.deprecated.perspectives.BatchPerspectives;
import org.sonar.batch.events.EventBus;
+import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.issue.IssuableFactory;
import org.sonar.batch.issue.IssueFilters;
@@ -68,7 +69,6 @@ import org.sonar.batch.scan.filesystem.ModuleFileSystemInitializer;
import org.sonar.batch.scan.filesystem.ModuleInputFileCache;
import org.sonar.batch.scan.filesystem.StatusDetectionFactory;
import org.sonar.batch.scan.report.IssuesReports;
-import org.sonar.batch.sensor.DefaultSensorContext;
import org.sonar.batch.sensor.DefaultSensorStorage;
import org.sonar.batch.sensor.SensorOptimizer;
import org.sonar.batch.sensor.coverage.CoverageExclusions;
@@ -97,6 +97,7 @@ public class ModuleScanContainer extends ComponentContainer {
add(
moduleDefinition,
module,
+ getComponentByType(BatchComponentCache.class).get(module).inputComponent(),
ModuleSettings.class);
// hack to initialize settings before ExtensionProviders
@@ -132,7 +133,6 @@ public class ModuleScanContainer extends ComponentContainer {
SensorOptimizer.class,
PostJobOptimizer.class,
- DefaultSensorContext.class,
DefaultPostJobContext.class,
DefaultSensorStorage.class,
DeprecatedSensorContext.class,
diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java
index 9896907d319..22251b3de9c 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java
@@ -23,6 +23,7 @@ import java.io.Serializable;
import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.coverage.NewCoverage;
@@ -65,8 +66,10 @@ public class DefaultSensorContext implements SensorContext {
private final ActiveRules activeRules;
private final SensorStorage sensorStorage;
private final AnalysisMode analysisMode;
+ private final InputModule module;
- public DefaultSensorContext(Settings settings, FileSystem fs, ActiveRules activeRules, AnalysisMode analysisMode, SensorStorage sensorStorage) {
+ public DefaultSensorContext(InputModule module, Settings settings, FileSystem fs, ActiveRules activeRules, AnalysisMode analysisMode, SensorStorage sensorStorage) {
+ this.module = module;
this.settings = settings;
this.fs = fs;
this.activeRules = activeRules;
@@ -95,6 +98,11 @@ public class DefaultSensorContext implements SensorContext {
}
@Override
+ public InputModule module() {
+ return module;
+ }
+
+ @Override
public <G extends Serializable> NewMeasure<G> newMeasure() {
return new DefaultMeasure<>(sensorStorage);
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnModuleMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnModuleMediumTest.java
new file mode 100644
index 00000000000..73434ed872d
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnModuleMediumTest.java
@@ -0,0 +1,84 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.mediumtest.issues;
+
+import com.google.common.collect.ImmutableMap;
+import java.io.File;
+import java.io.IOException;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.batch.mediumtest.BatchMediumTester;
+import org.sonar.batch.mediumtest.TaskResult;
+import org.sonar.xoo.XooPlugin;
+import org.sonar.xoo.rule.XooRulesDefinition;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class IssuesOnModuleMediumTest {
+
+ @org.junit.Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ public BatchMediumTester tester = BatchMediumTester.builder()
+ .registerPlugin("xoo", new XooPlugin())
+ .addDefaultQProfile("xoo", "Sonar Way")
+ .addRules(new XooRulesDefinition())
+ .addActiveRule("xoo", "OneIssuePerModule", null, "One issue per module", "MINOR", "xoo", "xoo")
+ .build();
+
+ @Before
+ public void prepare() {
+ tester.start();
+ }
+
+ @After
+ public void stop() {
+ tester.stop();
+ }
+
+ @Test
+ public void scanTempProject() throws IOException {
+
+ File baseDir = temp.getRoot();
+ File srcDir = new File(baseDir, "src");
+ srcDir.mkdir();
+
+ File xooFile1 = new File(srcDir, "sample1.xoo");
+ FileUtils.write(xooFile1, "Sample1 xoo\ncontent");
+
+ TaskResult result = tester.newTask()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.task", "scan")
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.projectName", "Foo Project")
+ .put("sonar.projectVersion", "1.0-SNAPSHOT")
+ .put("sonar.projectDescription", "Description of Foo Project")
+ .put("sonar.sources", "src")
+ .build())
+ .start();
+
+ assertThat(result.issuesFor(result.getReportComponent("com.foo.project"))).hasSize(1);
+ }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java
index 75e22478579..d2b6163fbeb 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java
@@ -25,6 +25,7 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.AnalysisMode;
+import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.rule.ActiveRules;
@@ -62,7 +63,7 @@ public class DefaultSensorContextTest {
settings = new Settings();
sensorStorage = mock(SensorStorage.class);
analysisMode = mock(AnalysisMode.class);
- adaptor = new DefaultSensorContext(settings, fs, activeRules, analysisMode, sensorStorage);
+ adaptor = new DefaultSensorContext(mock(InputModule.class), settings, fs, activeRules, analysisMode, sensorStorage);
}
@Test
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java
index 22fe01c2e65..a2197634ff8 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java
@@ -20,12 +20,12 @@
package org.sonar.api.batch.sensor;
import com.google.common.annotations.Beta;
-import org.sonar.api.batch.BatchSide;
import org.sonar.api.ExtensionPoint;
+import org.sonar.api.batch.BatchSide;
/**
* <p>
- * A sensor is invoked once during the analysis of a project. The sensor can parse a flat file, connect to a web server... Sensors are
+ * A sensor is invoked once for each module of a project, starting from leaf modules. The sensor can parse a flat file, connect to a web server... Sensors are
* used to add measure and issues at file level.
* </p>
*
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
index 78d18a08869..66734f4026f 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
@@ -23,6 +23,7 @@ import com.google.common.annotations.Beta;
import java.io.Serializable;
import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.coverage.NewCoverage;
import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
@@ -61,6 +62,11 @@ public interface SensorContext {
*/
AnalysisMode analysisMode();
+ /**
+ * @since 5.5
+ */
+ InputModule module();
+
// ----------- MEASURES --------------
/**
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
index 79c1b20462c..d5bb9d21ea1 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
@@ -33,7 +33,9 @@ import java.util.List;
import java.util.Map;
import javax.annotation.CheckForNull;
import org.sonar.api.batch.AnalysisMode;
+import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.DefaultTextPointer;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
@@ -71,6 +73,7 @@ public class SensorContextTester implements SensorContext {
private ActiveRules activeRules;
private MockAnalysisMode analysisMode;
private InMemorySensorStorage sensorStorage;
+ private InputModule module;
private SensorContextTester(File moduleBaseDir) {
this.settings = new Settings();
@@ -78,6 +81,7 @@ public class SensorContextTester implements SensorContext {
this.activeRules = new ActiveRulesBuilder().build();
this.analysisMode = new MockAnalysisMode();
this.sensorStorage = new InMemorySensorStorage();
+ this.module = new DefaultInputModule("projectKey");
}
public static SensorContextTester create(File moduleBaseDir) {
@@ -117,6 +121,11 @@ public class SensorContextTester implements SensorContext {
}
@Override
+ public InputModule module() {
+ return module;
+ }
+
+ @Override
public <G extends Serializable> NewMeasure<G> newMeasure() {
return new DefaultMeasure<>(sensorStorage);
}