import org.sonar.xoo.coverage.ItCoverageSensor;
import org.sonar.xoo.coverage.OverallCoverageSensor;
import org.sonar.xoo.coverage.UtCoverageSensor;
+import org.sonar.xoo.extensions.XooIssueFilter;
import org.sonar.xoo.extensions.XooPostJob;
import org.sonar.xoo.extensions.XooProjectBuilder;
import org.sonar.xoo.global.GlobalSensor;
// Other
XooProjectBuilder.class,
- XooPostJob.class);
+ XooPostJob.class,
+ XooIssueFilter.class);
if (context.getRuntime().getProduct() != SonarProduct.SONARLINT) {
context.addExtension(MeasureSensor.class);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info 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.xoo.extensions;
+
+import org.sonar.api.batch.fs.TextRange;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.scan.issue.filter.FilterableIssue;
+import org.sonar.api.scan.issue.filter.IssueFilter;
+import org.sonar.api.scan.issue.filter.IssueFilterChain;
+
+public class XooIssueFilter implements IssueFilter {
+
+ private final Configuration config;
+
+ public XooIssueFilter(Configuration config) {
+ this.config = config;
+ }
+
+
+ @Override
+ public boolean accept(FilterableIssue issue, IssueFilterChain chain) {
+ if (config.getBoolean("sonar.xoo.excludeAllIssuesOnOddLines").orElse(false) && isOdd(issue)) {
+ return false;
+ }
+ return chain.accept(issue);
+ }
+
+ private static boolean isOdd(FilterableIssue issue) {
+ TextRange textRange = issue.textRange();
+ return textRange != null && textRange.start().line() % 2 == 1;
+ }
+}
Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build();
new XooPlugin().define(context);
assertThat(getExtensions(context))
- .hasSize(46)
+ .hasSize(47)
.doesNotContain(XooBuiltInQualityProfilesDefinition.class);
}
Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build();
new XooPlugin().define(context);
assertThat(getExtensions(context))
- .hasSize(49)
+ .hasSize(50)
.contains(XooBuiltInQualityProfilesDefinition.class);
}
Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build();
new XooPlugin().define(context);
assertThat(getExtensions(context))
- .hasSize(53)
+ .hasSize(54)
.contains(OneExternalIssuePerLineSensor.class);
}
Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build();
new XooPlugin().define(context);
assertThat(getExtensions(context))
- .hasSize(54)
+ .hasSize(55)
.contains(OneExternalIssuePerLineSensor.class);
}
* </pre>
*
* @since 6.0
+ * @deprecated since 7.6 use {@link org.sonar.api.scanner.ScannerSide} that will move the component to the project container
*/
+@Deprecated
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.api.batch.sensor;
+package org.sonar.api.batch;
/**
* @since 5.3
+ * @deprecated since 7.6
*/
@ThreadSafe
+@Deprecated
public interface FilterableIssue {
/**
@ThreadSafe
/**
* @since 5.3
+ * @deprecated since 7.6
*/
+@Deprecated
public interface IssueFilter {
/**
import java.util.Optional;
import org.picocontainer.Startable;
import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.ScannerSide;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.DateUtils;
*
* Immutable after {@link #start()}
*/
-@ScannerSide
public class ProjectAnalysisInfo implements Startable {
private final Clock clock;
private Configuration settings;
package org.sonar.scanner.bootstrap;
import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.utils.AnnotationUtils;
public class ExtensionUtils {
return InstantiationStrategy.PER_PROJECT.equals(strategy);
}
+ public static boolean isDeprecatedScannerSide(Object extension) {
+ return AnnotationUtils.getAnnotation(extension, org.sonar.api.batch.ScannerSide.class) != null;
+ }
+
public static boolean isScannerSide(Object extension) {
return AnnotationUtils.getAnnotation(extension, ScannerSide.class) != null;
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.issue;
-
-import org.sonar.api.batch.ScannerSide;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.scan.issue.filter.FilterableIssue;
-import org.sonar.api.scan.issue.filter.IssueFilter;
-import org.sonar.api.scan.issue.filter.IssueFilterChain;
-import org.sonar.scanner.ProjectAnalysisInfo;
-import org.sonar.scanner.protocol.output.ScannerReport;
-
-@ScannerSide
-public class IssueFilters {
- private final IssueFilterChain filterChain;
- private final DefaultInputModule module;
- private final ProjectAnalysisInfo projectAnalysisInfo;
-
- public IssueFilters(DefaultInputModule module, ProjectAnalysisInfo projectAnalysisInfo, IssueFilter[] exclusionFilters) {
- this.module = module;
- this.filterChain = new DefaultIssueFilterChain(exclusionFilters);
- this.projectAnalysisInfo = projectAnalysisInfo;
- }
-
- public IssueFilters(DefaultInputModule module, ProjectAnalysisInfo projectAnalysisInfo) {
- this(module, projectAnalysisInfo, new IssueFilter[0]);
- }
-
- public boolean accept(String componentKey, ScannerReport.Issue rawIssue) {
- FilterableIssue fIssue = new DefaultFilterableIssue(module, projectAnalysisInfo, rawIssue, componentKey);
- return filterChain.accept(fIssue);
- }
-
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info 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.scanner.issue;
+
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.scan.issue.filter.FilterableIssue;
+import org.sonar.api.scan.issue.filter.IssueFilter;
+import org.sonar.api.scan.issue.filter.IssueFilterChain;
+import org.sonar.scanner.ProjectAnalysisInfo;
+import org.sonar.scanner.protocol.output.ScannerReport;
+
+/**
+ * @deprecated since 7.6, {@link IssueFilter} is deprecated
+ */
+@Deprecated
+public class ModuleIssueFilters {
+ private final IssueFilterChain filterChain;
+ private final DefaultInputModule module;
+ private final ProjectAnalysisInfo projectAnalysisInfo;
+
+ public ModuleIssueFilters(DefaultInputModule module, ProjectAnalysisInfo projectAnalysisInfo, IssueFilter[] exclusionFilters) {
+ this.module = module;
+ this.filterChain = new DefaultIssueFilterChain(exclusionFilters);
+ this.projectAnalysisInfo = projectAnalysisInfo;
+ }
+
+ public ModuleIssueFilters(DefaultInputModule module, ProjectAnalysisInfo projectAnalysisInfo) {
+ this(module, projectAnalysisInfo, new IssueFilter[0]);
+ }
+
+ public boolean accept(String componentKey, ScannerReport.Issue rawIssue) {
+ FilterableIssue fIssue = new DefaultFilterableIssue(module, projectAnalysisInfo, rawIssue, componentKey);
+ return filterChain.accept(fIssue);
+ }
+
+}
public class ModuleIssues {
private final ActiveRules activeRules;
- private final IssueFilters filters;
+ private final ModuleIssueFilters filters;
private final ReportPublisher reportPublisher;
- public ModuleIssues(ActiveRules activeRules, IssueFilters filters, ReportPublisher reportPublisher) {
+ public ModuleIssues(ActiveRules activeRules, ModuleIssueFilters filters, ReportPublisher reportPublisher) {
this.activeRules = activeRules;
this.filters = filters;
this.reportPublisher = reportPublisher;
import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
import org.sonar.scanner.bootstrap.ScannerExtensionDictionnary;
import org.sonar.scanner.deprecated.perspectives.ScannerPerspectives;
-import org.sonar.scanner.issue.IssueFilters;
+import org.sonar.scanner.issue.ModuleIssueFilters;
import org.sonar.scanner.issue.ModuleIssues;
import org.sonar.scanner.issue.ignore.EnforceIssuesFilter;
import org.sonar.scanner.issue.ignore.IgnoreIssuesFilter;
import static org.sonar.api.batch.InstantiationStrategy.PER_PROJECT;
import static org.sonar.core.extension.CoreExtensionsInstaller.noExtensionFilter;
+import static org.sonar.scanner.bootstrap.ExtensionUtils.isDeprecatedScannerSide;
import static org.sonar.scanner.bootstrap.ExtensionUtils.isInstantiationStrategy;
-import static org.sonar.scanner.bootstrap.ExtensionUtils.isScannerSide;
public class ModuleScanContainer extends ComponentContainer {
private static final Logger LOG = LoggerFactory.getLogger(ModuleScanContainer.class);
DefaultSensorStorage.class,
DefaultSensorContext.class,
ScannerExtensionDictionnary.class,
- IssueFilters.class,
+ ModuleIssueFilters.class,
CoverageExclusions.class,
// rules
CoreExtensionsInstaller coreExtensionsInstaller = getComponentByType(CoreExtensionsInstaller.class);
coreExtensionsInstaller.install(this, noExtensionFilter(), t -> isInstantiationStrategy(t, PER_PROJECT));
ExtensionInstaller pluginInstaller = getComponentByType(ExtensionInstaller.class);
- pluginInstaller.install(this, e -> isScannerSide(e) && isInstantiationStrategy(e, PER_PROJECT));
+ pluginInstaller.install(this, e -> isDeprecatedScannerSide(e) && isInstantiationStrategy(e, PER_PROJECT));
}
@Override
import static org.sonar.api.batch.InstantiationStrategy.PER_BATCH;
import static org.sonar.core.extension.CoreExtensionsInstaller.noExtensionFilter;
+import static org.sonar.scanner.bootstrap.ExtensionUtils.isDeprecatedScannerSide;
import static org.sonar.scanner.bootstrap.ExtensionUtils.isInstantiationStrategy;
import static org.sonar.scanner.bootstrap.ExtensionUtils.isScannerSide;
@VisibleForTesting
static ExtensionMatcher getBatchPluginExtensionsFilter() {
- return extension -> isScannerSide(extension) && isInstantiationStrategy(extension, PER_BATCH);
+ return extension -> isScannerSide(extension) || (isDeprecatedScannerSide(extension) && isInstantiationStrategy(extension, PER_BATCH));
}
@Override
import static org.sonar.api.batch.InstantiationStrategy.PER_TASK;
import static org.sonar.core.extension.CoreExtensionsInstaller.noExtensionFilter;
import static org.sonar.scanner.bootstrap.ExtensionUtils.isInstantiationStrategy;
-import static org.sonar.scanner.bootstrap.ExtensionUtils.isScannerSide;
+import static org.sonar.scanner.bootstrap.ExtensionUtils.isDeprecatedScannerSide;
public class TaskContainer extends ComponentContainer {
getComponentByType(CoreExtensionsInstaller.class)
.install(this, noExtensionFilter(), t -> isInstantiationStrategy(t, PER_TASK));
getComponentByType(ExtensionInstaller.class)
- .install(this, extension -> isScannerSide(extension) && isInstantiationStrategy(extension, PER_TASK));
+ .install(this, extension -> isDeprecatedScannerSide(extension) && isInstantiationStrategy(extension, PER_TASK));
}
@Override
@Test
public void testIsScannerSide() {
- assertThat(ExtensionUtils.isScannerSide(ScannerService.class)).isTrue();
+ assertThat(ExtensionUtils.isDeprecatedScannerSide(ScannerService.class)).isTrue();
- assertThat(ExtensionUtils.isScannerSide(ServerService.class)).isFalse();
- assertThat(ExtensionUtils.isScannerSide(new ServerService())).isFalse();
- assertThat(ExtensionUtils.isScannerSide(new WebServerService())).isFalse();
- assertThat(ExtensionUtils.isScannerSide(new ComputeEngineService())).isFalse();
+ assertThat(ExtensionUtils.isDeprecatedScannerSide(ServerService.class)).isFalse();
+ assertThat(ExtensionUtils.isDeprecatedScannerSide(new ServerService())).isFalse();
+ assertThat(ExtensionUtils.isDeprecatedScannerSide(new WebServerService())).isFalse();
+ assertThat(ExtensionUtils.isDeprecatedScannerSide(new ComputeEngineService())).isFalse();
}
@ScannerSide
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
-import org.sonar.api.utils.MessageException;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.report.ReportPublisher;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
static final String SQUID_RULE_NAME = "Avoid Cycle";
@Mock
- IssueFilters filters;
+ ModuleIssueFilters filters;
ActiveRulesBuilder activeRulesBuilder = new ActiveRulesBuilder();
RulesBuilder ruleBuilder = new RulesBuilder();
List<ExternalIssue> externalIssues = result.externalIssuesFor(result.inputFile("xources/hello/HelloJava.xoo"));
assertThat(externalIssues).isEmpty();
-
- Issue issue = issues.get(0);
- assertThat(issue.getTextRange().getStartLine()).isEqualTo(issue.getTextRange().getStartLine());
}
@Test
List<ExternalIssue> externalIssues = result.externalIssuesFor(result.inputFile("xources/hello/HelloJava.xoo"));
assertThat(externalIssues).hasSize(8 /* lines */);
-
- ExternalIssue externalIssue = externalIssues.get(0);
- assertThat(externalIssue.getTextRange().getStartLine()).isEqualTo(externalIssue.getTextRange().getStartLine());
}
@Test
.contains(tuple("This issue is generated on each line", 1, 0.0));
}
+ @Test
+ public void testIssueFilter() throws Exception {
+ File projectDir = new File(IssuesMediumTest.class.getResource("/mediumtest/xoo/sample").toURI());
+ File tmpDir = temp.newFolder();
+ FileUtils.copyDirectory(projectDir, tmpDir);
+
+ TaskResult result = tester
+ .newScanTask(new File(tmpDir, "sonar-project.properties"))
+ .property("sonar.xoo.excludeAllIssuesOnOddLines", "true")
+ .execute();
+
+ List<Issue> issues = result.issuesFor(result.inputFile("xources/hello/HelloJava.xoo"));
+ assertThat(issues).hasSize(4 /* even lines */);
+ }
+
}