From 91a01dfc9e3d78cbe8b855912202540a66a74cdf Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Mon, 13 Apr 2015 09:16:32 +0200 Subject: [PATCH] SONAR-6408 Restore PostJob execution in preview mode --- .../main/java/org/sonar/xoo/XooPlugin.java | 4 +- .../org/sonar/xoo/extensions/XooPostJob.java | 46 ++++++ .../sonar/xoo/rule/OneIssuePerLineSensor.java | 2 +- .../sonar/xoo/extensions/XooPostJobTest.java | 49 ++++++ .../xoo/rule/OneIssuePerLineSensorTest.java | 5 +- .../bootstrap/BatchExtensionDictionnary.java | 36 +++- .../org/sonar/batch/issue/ModuleIssues.java | 11 +- .../phases/DatabaseLessPhaseExecutor.java | 7 +- .../batch/postjob/DefaultPostJobContext.java | 156 ++++++++++++++++++ .../sonar/batch/postjob/PostJobOptimizer.java | 67 ++++++++ .../sonar/batch/postjob/PostJobWrapper.java | 65 ++++++++ .../org/sonar/batch/postjob/package-info.java | 21 +++ .../sonar/batch/scan/ModuleScanContainer.java | 8 +- .../batch/sensor/DefaultSensorStorage.java | 2 +- ...zerOptimizer.java => SensorOptimizer.java} | 8 +- .../batch/{scan => sensor}/SensorWrapper.java | 8 +- .../BatchExtensionDictionnaryTest.java | 20 +-- .../decorator/DecoratorsSelectorTest.java | 8 +- .../mediumtest/issues/IssuesMediumTest.java | 2 +- .../preview/PreviewAndReportsMediumTest.java | 12 ++ .../postjob/DefaultPostJobContextTest.java | 87 ++++++++++ .../batch/postjob/PostJobOptimizerTest.java | 81 +++++++++ .../sensor/DefaultSensorStorageTest.java | 2 +- ...izerTest.java => SensorOptimizerTest.java} | 10 +- .../org/sonar/api/batch/postjob/PostJob.java | 46 ++++++ .../api/batch/postjob/PostJobContext.java | 56 +++++++ .../api/batch/postjob/PostJobDescriptor.java | 55 ++++++ .../internal/DefaultPostJobDescriptor.java | 68 ++++++++ .../sonar/api/batch/postjob/issue/Issue.java | 87 ++++++++++ .../api/batch/postjob/issue/package-info.java | 21 +++ .../sonar/api/batch/postjob/package-info.java | 21 +++ .../org/sonar/api/batch/rule/Severity.java | 34 ++++ .../sonar/api/batch/sensor/SensorContext.java | 4 +- .../sonar/api/batch/sensor/issue/Issue.java | 9 +- .../api/batch/sensor/issue/NewIssue.java | 2 +- .../sensor/issue/internal/DefaultIssue.java | 1 + .../issue/internal/DefaultIssueTest.java | 2 +- 37 files changed, 1050 insertions(+), 73 deletions(-) create mode 100644 plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/extensions/XooPostJob.java create mode 100644 plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobOptimizer.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobWrapper.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/postjob/package-info.java rename sonar-batch/src/main/java/org/sonar/batch/sensor/{AnalyzerOptimizer.java => SensorOptimizer.java} (91%) rename sonar-batch/src/main/java/org/sonar/batch/{scan => sensor}/SensorWrapper.java (93%) create mode 100644 sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java create mode 100644 sonar-batch/src/test/java/org/sonar/batch/postjob/PostJobOptimizerTest.java rename sonar-batch/src/test/java/org/sonar/batch/sensor/{AnalyzerOptimizerTest.java => SensorOptimizerTest.java} (94%) create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJob.java create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobDescriptor.java create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/DefaultPostJobDescriptor.java create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/Issue.java create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/package-info.java create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/package-info.java create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Severity.java diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java index 8aa011ef873..a94fe8c055c 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java @@ -20,6 +20,7 @@ package org.sonar.xoo; import org.sonar.api.SonarPlugin; +import org.sonar.xoo.extensions.XooPostJob; import org.sonar.xoo.extensions.XooProjectBuilder; import org.sonar.xoo.lang.*; import org.sonar.xoo.rule.*; @@ -70,6 +71,7 @@ public class XooPlugin extends SonarPlugin { CreateIssueByInternalKeySensor.class, // Other - XooProjectBuilder.class); + XooProjectBuilder.class, + XooPostJob.class); } } diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/extensions/XooPostJob.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/extensions/XooPostJob.java new file mode 100644 index 00000000000..80b27f29e43 --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/extensions/XooPostJob.java @@ -0,0 +1,46 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 com.google.common.collect.Iterables; +import org.sonar.api.batch.postjob.PostJob; +import org.sonar.api.batch.postjob.PostJobContext; +import org.sonar.api.batch.postjob.PostJobDescriptor; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; + +public class XooPostJob implements PostJob { + + private static final Logger LOG = Loggers.get(XooPostJob.class); + + @Override + public void describe(PostJobDescriptor descriptor) { + descriptor.name("Xoo Post Job") + .requireProperty("sonar.xoo.enablePostJob"); + + } + + @Override + public void execute(PostJobContext context) { + LOG.info("Resolved issues: " + Iterables.size(context.resolvedIssues())); + LOG.info("Open issues: " + Iterables.size(context.issues())); + } + +} 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 4aa4ea7e33f..fc0a564c69c 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 @@ -23,10 +23,10 @@ import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; +import org.sonar.api.batch.rule.Severity; 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.Issue.Severity; import org.sonar.api.rule.RuleKey; import org.sonar.xoo.Xoo; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java new file mode 100644 index 00000000000..4af975c172e --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java @@ -0,0 +1,49 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.junit.Rule; +import org.junit.Test; +import org.sonar.api.batch.postjob.PostJobContext; +import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; +import org.sonar.api.batch.postjob.issue.Issue; +import org.sonar.api.utils.log.LogTester; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class XooPostJobTest { + + @Rule + public LogTester logTester = new LogTester(); + + @Test + public void increaseCoverage() { + new XooPostJob().describe(new DefaultPostJobDescriptor()); + PostJobContext context = mock(PostJobContext.class); + when(context.issues()).thenReturn(Arrays.asList()); + when(context.resolvedIssues()).thenReturn(Arrays.asList()); + new XooPostJob().execute(context); + assertThat(logTester.logs()).contains("Resolved issues: 0", "Open issues: 0"); + } +} diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java index ab8ea247d35..a3cbbf5eb84 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java @@ -19,8 +19,6 @@ */ package org.sonar.xoo.rule; -import org.sonar.api.batch.sensor.internal.SensorStorage; - import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -29,10 +27,11 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; +import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.issue.Issue; -import org.sonar.api.batch.sensor.issue.Issue.Severity; import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; import org.sonar.api.config.Settings; import org.sonar.xoo.Xoo; diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java index 95f333fe93e..0f1eea698ea 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java @@ -28,15 +28,19 @@ import org.sonar.api.batch.CheckProject; import org.sonar.api.batch.DependedUpon; import org.sonar.api.batch.DependsUpon; import org.sonar.api.batch.Phase; +import org.sonar.api.batch.postjob.PostJob; +import org.sonar.api.batch.postjob.PostJobContext; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; import org.sonar.api.utils.AnnotationUtils; import org.sonar.api.utils.dag.DirectAcyclicGraph; -import org.sonar.batch.scan.SensorWrapper; -import org.sonar.batch.sensor.AnalyzerOptimizer; +import org.sonar.batch.postjob.PostJobOptimizer; +import org.sonar.batch.postjob.PostJobWrapper; import org.sonar.batch.sensor.DefaultSensorContext; +import org.sonar.batch.sensor.SensorOptimizer; +import org.sonar.batch.sensor.SensorWrapper; import javax.annotation.Nullable; @@ -55,13 +59,18 @@ import java.util.List; public class BatchExtensionDictionnary { private final ComponentContainer componentContainer; - private final SensorContext context; - private final AnalyzerOptimizer analyzerOptimizer; + private final SensorContext sensorContext; + private final SensorOptimizer sensorOptimizer; + private final PostJobContext postJobContext; + private final PostJobOptimizer postJobOptimizer; - public BatchExtensionDictionnary(ComponentContainer componentContainer, DefaultSensorContext context, AnalyzerOptimizer analyzerOptimizer) { + public BatchExtensionDictionnary(ComponentContainer componentContainer, DefaultSensorContext sensorContext, SensorOptimizer sensorOptimizer, PostJobContext postJobContext, + PostJobOptimizer postJobOptimizer) { this.componentContainer = componentContainer; - this.context = context; - this.analyzerOptimizer = analyzerOptimizer; + this.sensorContext = sensorContext; + this.sensorOptimizer = sensorOptimizer; + this.postJobContext = postJobContext; + this.postJobOptimizer = postJobOptimizer; } public Collection select(Class type, @Nullable Project project, boolean sort, @Nullable ExtensionMatcher matcher) { @@ -90,7 +99,7 @@ public class BatchExtensionDictionnary { List result = Lists.newArrayList(); for (Object extension : getExtensions(type)) { if (org.sonar.api.batch.Sensor.class.equals(type) && extension instanceof Sensor) { - extension = new SensorWrapper((Sensor) extension, context, analyzerOptimizer); + extension = new SensorWrapper((Sensor) extension, sensorContext, sensorOptimizer); } if (shouldKeep(type, extension, project, matcher)) { result.add((T) extension); @@ -99,7 +108,16 @@ public class BatchExtensionDictionnary { if (org.sonar.api.batch.Sensor.class.equals(type)) { // Retrieve new Sensors and wrap then in SensorWrapper for (Object extension : getExtensions(Sensor.class)) { - extension = new SensorWrapper((Sensor) extension, context, analyzerOptimizer); + extension = new SensorWrapper((Sensor) extension, sensorContext, sensorOptimizer); + if (shouldKeep(type, extension, project, matcher)) { + result.add((T) extension); + } + } + } + if (org.sonar.api.batch.PostJob.class.equals(type)) { + // Retrieve new PostJob and wrap then in PostJobWrapper + for (Object extension : getExtensions(PostJob.class)) { + extension = new PostJobWrapper((PostJob) extension, postJobContext, postJobOptimizer); if (shouldKeep(type, extension, project, matcher)) { result.add((T) extension); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java index 64f7e8d2446..f17b42c18db 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java @@ -48,7 +48,7 @@ public class ModuleIssues { private final Project project; private final IssueFilters filters; - public ModuleIssues(ActiveRules activeRules, @Nullable Rules rules, IssueCache cache, @Nullable Project project, IssueFilters filters) { + public ModuleIssues(ActiveRules activeRules, @Nullable Rules rules, IssueCache cache, Project project, IssueFilters filters) { this.activeRules = activeRules; this.rules = rules; this.cache = cache; @@ -56,17 +56,10 @@ public class ModuleIssues { this.filters = filters; } - public ModuleIssues(ActiveRules activeRules, IssueCache cache, @Nullable Project project, IssueFilters filters) { + public ModuleIssues(ActiveRules activeRules, IssueCache cache, Project project, IssueFilters filters) { this(activeRules, null, cache, project, filters); } - /** - * Used by scan2 - */ - public ModuleIssues(ActiveRules activeRules, Rules rules, IssueCache cache, IssueFilters filters) { - this(activeRules, rules, cache, null, filters); - } - public boolean initAndAddViolation(Violation violation) { DefaultIssue issue = newIssue(violation); return initAndAddIssue(issue); diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java index e116bb80565..9a0d765ca66 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java @@ -37,6 +37,7 @@ public final class DatabaseLessPhaseExecutor implements PhaseExecutor { private final EventBus eventBus; private final Phases phases; private final InitializersExecutor initializersExecutor; + private final PostJobsExecutor postJobsExecutor; private final SensorsExecutor sensorsExecutor; private final SensorContext sensorContext; private final DefaultIndex index; @@ -49,12 +50,13 @@ public final class DatabaseLessPhaseExecutor implements PhaseExecutor { private final LocalIssueTracking localIssueTracking; private final ReportPublisher reportPublisher; - public DatabaseLessPhaseExecutor(Phases phases, InitializersExecutor initializersExecutor, SensorsExecutor sensorsExecutor, + public DatabaseLessPhaseExecutor(Phases phases, InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, SensorContext sensorContext, DefaultIndex index, EventBus eventBus, ProjectInitializer pi, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, IssueExclusionsLoader issueExclusionsLoader, LocalIssueTracking localIssueTracking, ReportPublisher reportPublisher) { this.phases = phases; this.initializersExecutor = initializersExecutor; + this.postJobsExecutor = postJobsExecutor; this.sensorsExecutor = sensorsExecutor; this.sensorContext = sensorContext; this.index = index; @@ -97,6 +99,9 @@ public final class DatabaseLessPhaseExecutor implements PhaseExecutor { localIssueTracking(); issuesReport(); publishReportJob(); + if (phases.isEnabled(Phases.Phase.POSTJOB)) { + postJobsExecutor.execute(sensorContext); + } } cleanMemory(); diff --git a/sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java b/sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java new file mode 100644 index 00000000000..56840eb88b4 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java @@ -0,0 +1,156 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.postjob; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.fs.InputPath; +import org.sonar.api.batch.postjob.PostJobContext; +import org.sonar.api.batch.postjob.issue.Issue; +import org.sonar.api.batch.rule.Severity; +import org.sonar.api.config.Settings; +import org.sonar.api.issue.internal.DefaultIssue; +import org.sonar.api.rule.RuleKey; +import org.sonar.batch.index.BatchResource; +import org.sonar.batch.index.ResourceCache; +import org.sonar.batch.issue.IssueCache; + +import javax.annotation.Nullable; + +public class DefaultPostJobContext implements PostJobContext { + + private final Settings settings; + private final AnalysisMode analysisMode; + private final IssueCache cache; + private final ResourceCache resourceCache; + + public DefaultPostJobContext(Settings settings, AnalysisMode analysisMode, IssueCache cache, ResourceCache resourceCache) { + this.settings = settings; + this.analysisMode = analysisMode; + this.cache = cache; + this.resourceCache = resourceCache; + } + + @Override + public Settings settings() { + return settings; + } + + @Override + public AnalysisMode analysisMode() { + return analysisMode; + } + + @Override + public Iterable issues() { + return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(false)), new Function() { + @Override + public Issue apply(DefaultIssue input) { + return new DefaultIssueWrapper(input); + } + }); + } + + @Override + public Iterable resolvedIssues() { + return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(true)), new Function() { + @Override + public Issue apply(DefaultIssue input) { + return new DefaultIssueWrapper(input); + } + }); + } + + private class DefaultIssueWrapper implements Issue { + + private final DefaultIssue wrapped; + + public DefaultIssueWrapper(DefaultIssue wrapped) { + this.wrapped = wrapped; + } + + @Override + public String key() { + return wrapped.key(); + } + + @Override + public RuleKey ruleKey() { + return wrapped.ruleKey(); + } + + @Override + public String componentKey() { + return wrapped.componentKey(); + } + + @Override + public InputPath inputPath() { + BatchResource component = resourceCache.get(wrapped.componentKey()); + return component != null ? component.inputPath() : null; + } + + @Override + public Integer line() { + return wrapped.line(); + } + + @Override + public Double effortToFix() { + return wrapped.effortToFix(); + } + + @Override + public String message() { + return wrapped.message(); + } + + @Override + public Severity severity() { + String severity = wrapped.severity(); + return severity != null ? Severity.valueOf(severity) : null; + } + + @Override + public boolean isNew() { + return wrapped.isNew(); + } + + } + + private static class ResolvedPredicate implements Predicate { + private final boolean resolved; + + private ResolvedPredicate(boolean resolved) { + this.resolved = resolved; + } + + @Override + public boolean apply(@Nullable DefaultIssue issue) { + if (issue != null) { + return resolved ? issue.resolution() != null : issue.resolution() == null; + } + return false; + } + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobOptimizer.java b/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobOptimizer.java new file mode 100644 index 00000000000..fa4f3ea613a --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobOptimizer.java @@ -0,0 +1,67 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.postjob; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.BatchComponent; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; +import org.sonar.api.config.Settings; + +public class PostJobOptimizer implements BatchComponent { + + private static final Logger LOG = LoggerFactory.getLogger(PostJobOptimizer.class); + + private final Settings settings; + private final AnalysisMode analysisMode; + + public PostJobOptimizer(Settings settings, AnalysisMode analysisMode) { + this.settings = settings; + this.analysisMode = analysisMode; + } + + /** + * Decide if the given PostJob should be executed. + */ + public boolean shouldExecute(DefaultPostJobDescriptor descriptor) { + if (!settingsCondition(descriptor)) { + LOG.debug("'{}' skipped because one of the required properties is missing", descriptor.name()); + return false; + } + if (descriptor.isDisabledInPreview() && analysisMode.isPreview()) { + LOG.debug("'{}' skipped in preview mode", descriptor.name()); + return false; + } + return true; + } + + private boolean settingsCondition(DefaultPostJobDescriptor descriptor) { + if (!descriptor.properties().isEmpty()) { + for (String propertyKey : descriptor.properties()) { + if (!settings.hasKey(propertyKey)) { + return false; + } + } + } + return true; + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobWrapper.java b/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobWrapper.java new file mode 100644 index 00000000000..45182e69ee5 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobWrapper.java @@ -0,0 +1,65 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.postjob; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.CheckProject; +import org.sonar.api.batch.postjob.PostJob; +import org.sonar.api.batch.postjob.PostJobContext; +import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; +import org.sonar.api.resources.Project; + +public class PostJobWrapper implements org.sonar.api.batch.PostJob, CheckProject { + + private static final Logger LOG = LoggerFactory.getLogger(PostJobWrapper.class); + + private PostJob wrappedPostJob; + private PostJobContext adaptor; + private DefaultPostJobDescriptor descriptor; + private PostJobOptimizer optimizer; + + public PostJobWrapper(PostJob newPostJob, PostJobContext adaptor, PostJobOptimizer optimizer) { + this.wrappedPostJob = newPostJob; + this.optimizer = optimizer; + descriptor = new DefaultPostJobDescriptor(); + newPostJob.describe(descriptor); + this.adaptor = adaptor; + } + + public PostJob wrappedPostJob() { + return wrappedPostJob; + } + + @Override + public boolean shouldExecuteOnProject(Project project) { + return optimizer.shouldExecute(descriptor); + } + + @Override + public void executeOn(Project project, org.sonar.api.batch.SensorContext context) { + wrappedPostJob.execute(adaptor); + } + + @Override + public String toString() { + return descriptor.name() + (LOG.isDebugEnabled() ? " (wrapped)" : ""); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/postjob/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/postjob/package-info.java new file mode 100644 index 00000000000..b4bab61609d --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/postjob/package-info.java @@ -0,0 +1,21 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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. + */ +@javax.annotation.ParametersAreNonnullByDefault +package org.sonar.batch.postjob; 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 d9a67454ad0..a05aee3193c 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 @@ -55,14 +55,16 @@ import org.sonar.batch.issue.tracking.IssueHandlers; import org.sonar.batch.issue.tracking.IssueTrackingDecorator; import org.sonar.batch.language.LanguageDistributionDecorator; import org.sonar.batch.phases.*; +import org.sonar.batch.postjob.DefaultPostJobContext; +import org.sonar.batch.postjob.PostJobOptimizer; import org.sonar.batch.qualitygate.GenerateQualityGateEvents; import org.sonar.batch.qualitygate.QualityGateVerifier; import org.sonar.batch.rule.*; import org.sonar.batch.scan.filesystem.*; import org.sonar.batch.scan.report.IssuesReports; -import org.sonar.batch.sensor.AnalyzerOptimizer; 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; import org.sonar.batch.source.HighlightableBuilder; import org.sonar.batch.source.SymbolizableBuilder; @@ -134,9 +136,11 @@ public class ModuleScanContainer extends ComponentContainer { ProjectFileSystemAdapter.class, QProfileVerifier.class, - AnalyzerOptimizer.class, + SensorOptimizer.class, + PostJobOptimizer.class, DefaultSensorContext.class, + DefaultPostJobContext.class, DefaultSensorStorage.class, DeprecatedSensorContext.class, BatchExtensionDictionnary.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java index 99cdf8bbb70..f73c35c0679 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java @@ -29,13 +29,13 @@ import org.sonar.api.batch.fs.TextRange; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.duplication.Duplication; import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication; import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.issue.Issue; -import org.sonar.api.batch.sensor.issue.Issue.Severity; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.config.Settings; diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/AnalyzerOptimizer.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/SensorOptimizer.java similarity index 91% rename from sonar-batch/src/main/java/org/sonar/batch/sensor/AnalyzerOptimizer.java rename to sonar-batch/src/main/java/org/sonar/batch/sensor/SensorOptimizer.java index f114e4a24e7..dbc4eac19e1 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/sensor/AnalyzerOptimizer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/SensorOptimizer.java @@ -29,16 +29,16 @@ import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; import org.sonar.api.config.Settings; -public class AnalyzerOptimizer implements BatchComponent { +public class SensorOptimizer implements BatchComponent { - private static final Logger LOG = LoggerFactory.getLogger(AnalyzerOptimizer.class); + private static final Logger LOG = LoggerFactory.getLogger(SensorOptimizer.class); private final FileSystem fs; private final ActiveRules activeRules; private final Settings settings; private final AnalysisMode analysisMode; - public AnalyzerOptimizer(FileSystem fs, ActiveRules activeRules, Settings settings, AnalysisMode analysisMode) { + public SensorOptimizer(FileSystem fs, ActiveRules activeRules, Settings settings, AnalysisMode analysisMode) { this.fs = fs; this.activeRules = activeRules; this.settings = settings; @@ -46,7 +46,7 @@ public class AnalyzerOptimizer implements BatchComponent { } /** - * Decide if the given Analyzer should be executed. + * Decide if the given Sensor should be executed. */ public boolean shouldExecute(DefaultSensorDescriptor descriptor) { if (!fsCondition(descriptor)) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/SensorWrapper.java similarity index 93% rename from sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java rename to sonar-batch/src/main/java/org/sonar/batch/sensor/SensorWrapper.java index 8884bef521f..143160e51c0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/SensorWrapper.java @@ -17,9 +17,7 @@ * 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.scan; - -import org.sonar.batch.sensor.AnalyzerOptimizer; +package org.sonar.batch.sensor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,9 +33,9 @@ public class SensorWrapper implements org.sonar.api.batch.Sensor { private Sensor wrappedSensor; private SensorContext adaptor; private DefaultSensorDescriptor descriptor; - private AnalyzerOptimizer optimizer; + private SensorOptimizer optimizer; - public SensorWrapper(Sensor newSensor, SensorContext adaptor, AnalyzerOptimizer optimizer) { + public SensorWrapper(Sensor newSensor, SensorContext adaptor, SensorOptimizer optimizer) { this.wrappedSensor = newSensor; this.optimizer = optimizer; descriptor = new DefaultSensorDescriptor(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java index 046f6664967..14fde3895ef 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java @@ -22,19 +22,13 @@ package org.sonar.batch.bootstrap; import com.google.common.collect.Lists; import org.junit.Test; import org.sonar.api.BatchExtension; -import org.sonar.api.batch.BuildBreaker; -import org.sonar.api.batch.CheckProject; -import org.sonar.api.batch.Decorator; -import org.sonar.api.batch.DependedUpon; -import org.sonar.api.batch.DependsUpon; -import org.sonar.api.batch.Phase; -import org.sonar.api.batch.PostJob; -import org.sonar.api.batch.Sensor; -import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.*; +import org.sonar.api.batch.postjob.PostJobContext; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; -import org.sonar.batch.sensor.AnalyzerOptimizer; +import org.sonar.batch.postjob.PostJobOptimizer; import org.sonar.batch.sensor.DefaultSensorContext; +import org.sonar.batch.sensor.SensorOptimizer; import java.util.Arrays; import java.util.Collection; @@ -53,7 +47,8 @@ public class BatchExtensionDictionnaryTest { for (BatchExtension extension : extensions) { iocContainer.addSingleton(extension); } - return new BatchExtensionDictionnary(iocContainer, mock(DefaultSensorContext.class), mock(AnalyzerOptimizer.class)); + return new BatchExtensionDictionnary(iocContainer, mock(DefaultSensorContext.class), mock(SensorOptimizer.class), mock(PostJobContext.class), + mock(PostJobOptimizer.class)); } @Test @@ -98,7 +93,8 @@ public class BatchExtensionDictionnaryTest { ComponentContainer child = parent.createChild(); child.addSingleton(c); - BatchExtensionDictionnary dictionnary = new BatchExtensionDictionnary(child, mock(DefaultSensorContext.class), mock(AnalyzerOptimizer.class)); + BatchExtensionDictionnary dictionnary = new BatchExtensionDictionnary(child, mock(DefaultSensorContext.class), mock(SensorOptimizer.class), mock(PostJobContext.class), + mock(PostJobOptimizer.class)); assertThat(dictionnary.select(BatchExtension.class, null, true, null)).containsOnly(a, b, c); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/deprecated/decorator/DecoratorsSelectorTest.java b/sonar-batch/src/test/java/org/sonar/batch/deprecated/decorator/DecoratorsSelectorTest.java index f469d6b52e9..fd9a9ed3727 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/deprecated/decorator/DecoratorsSelectorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/deprecated/decorator/DecoratorsSelectorTest.java @@ -24,11 +24,7 @@ import org.junit.Test; import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.DependedUpon; -import org.sonar.api.measures.Formula; -import org.sonar.api.measures.FormulaContext; -import org.sonar.api.measures.FormulaData; -import org.sonar.api.measures.Measure; -import org.sonar.api.measures.Metric; +import org.sonar.api.measures.*; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; @@ -81,7 +77,7 @@ public class DecoratorsSelectorTest { for (Object extension : extensions) { ioc.addSingleton(extension); } - return new BatchExtensionDictionnary(ioc, null, null); + return new BatchExtensionDictionnary(ioc, null, null, null, null); } class FakeFormula implements Formula { diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java index 22f8a339f13..d97f6ba995d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java @@ -25,7 +25,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.sensor.issue.Issue.Severity; +import org.sonar.api.batch.rule.Severity; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; import org.sonar.batch.protocol.input.ActiveRule; diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java index c8368f37246..ab2157d056d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java @@ -163,6 +163,18 @@ public class PreviewAndReportsMediumTest { assertThat(getReportLog()).contains("+13 issues", "+13 major"); } + @Test + public void testPostJob() throws Exception { + File projectDir = new File(PreviewAndReportsMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); + + tester + .newScanTask(new File(projectDir, "sonar-project.properties")) + .property("sonar.xoo.enablePostJob", "true") + .start(); + + assertThat(logTester.logs()).contains("Resolved issues: 2", "Open issues: 15"); + } + private String getReportLog() { for (String log : logTester.logs()) { if (log.contains(ConsoleReport.HEADER)) { diff --git a/sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java b/sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java new file mode 100644 index 00000000000..9ca6dd40771 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java @@ -0,0 +1,87 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.postjob; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.postjob.issue.Issue; +import org.sonar.api.batch.rule.Severity; +import org.sonar.api.config.Settings; +import org.sonar.api.issue.internal.DefaultIssue; +import org.sonar.api.resources.File; +import org.sonar.batch.index.ResourceCache; +import org.sonar.batch.issue.IssueCache; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DefaultPostJobContextTest { + + private IssueCache issueCache; + private ResourceCache resourceCache; + private AnalysisMode analysisMode; + private DefaultPostJobContext context; + private Settings settings; + + @Before + public void prepare() { + issueCache = mock(IssueCache.class); + resourceCache = new ResourceCache(); + analysisMode = mock(AnalysisMode.class); + settings = new Settings(); + context = new DefaultPostJobContext(settings, analysisMode, issueCache, resourceCache); + } + + @Test + public void test() { + assertThat(context.settings()).isSameAs(settings); + assertThat(context.analysisMode()).isSameAs(analysisMode); + + DefaultIssue defaultIssue = new DefaultIssue(); + defaultIssue.setComponentKey("foo:src/Foo.php"); + defaultIssue.setEffortToFix(2.0); + defaultIssue.setNew(true); + defaultIssue.setKey("xyz"); + defaultIssue.setLine(1); + defaultIssue.setMessage("msg"); + defaultIssue.setSeverity("BLOCKER"); + when(issueCache.all()).thenReturn(Arrays.asList(defaultIssue)); + + Issue issue = context.issues().iterator().next(); + assertThat(issue.componentKey()).isEqualTo("foo:src/Foo.php"); + assertThat(issue.effortToFix()).isEqualTo(2.0); + assertThat(issue.isNew()).isTrue(); + assertThat(issue.key()).isEqualTo("xyz"); + assertThat(issue.line()).isEqualTo(1); + assertThat(issue.message()).isEqualTo("msg"); + assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); + assertThat(issue.inputPath()).isNull(); + + InputFile inputPath = mock(InputFile.class); + resourceCache.add(File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php"), null).setInputPath(inputPath); + assertThat(issue.inputPath()).isEqualTo(inputPath); + + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/postjob/PostJobOptimizerTest.java b/sonar-batch/src/test/java/org/sonar/batch/postjob/PostJobOptimizerTest.java new file mode 100644 index 00000000000..acd9ea1fdb7 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/postjob/PostJobOptimizerTest.java @@ -0,0 +1,81 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.postjob; + +import org.junit.Before; +import org.junit.Rule; +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.postjob.internal.DefaultPostJobDescriptor; +import org.sonar.api.config.Settings; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class PostJobOptimizerTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private PostJobOptimizer optimizer; + private Settings settings; + private AnalysisMode analysisMode; + + @Before + public void prepare() throws Exception { + settings = new Settings(); + analysisMode = mock(AnalysisMode.class); + optimizer = new PostJobOptimizer(settings, analysisMode); + } + + @Test + public void should_run_analyzer_with_no_metadata() throws Exception { + DefaultPostJobDescriptor descriptor = new DefaultPostJobDescriptor(); + + assertThat(optimizer.shouldExecute(descriptor)).isTrue(); + } + + @Test + public void should_optimize_on_settings() throws Exception { + DefaultPostJobDescriptor descriptor = new DefaultPostJobDescriptor() + .requireProperty("sonar.foo.reportPath"); + assertThat(optimizer.shouldExecute(descriptor)).isFalse(); + + settings.setProperty("sonar.foo.reportPath", "foo"); + assertThat(optimizer.shouldExecute(descriptor)).isTrue(); + } + + @Test + public void should_disabled_in_preview() throws Exception { + DefaultPostJobDescriptor descriptor = new DefaultPostJobDescriptor() + .disabledInPreview(); + assertThat(optimizer.shouldExecute(descriptor)).isTrue(); + + when(analysisMode.isPreview()).thenReturn(true); + + assertThat(optimizer.shouldExecute(descriptor)).isFalse(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java index 3114e054718..2ebab61ace3 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java @@ -33,9 +33,9 @@ import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; -import org.sonar.api.batch.sensor.issue.Issue.Severity; import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.config.Settings; diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/AnalyzerOptimizerTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/SensorOptimizerTest.java similarity index 94% rename from sonar-batch/src/test/java/org/sonar/batch/sensor/AnalyzerOptimizerTest.java rename to sonar-batch/src/test/java/org/sonar/batch/sensor/SensorOptimizerTest.java index 1850fe2b001..12d5e00dc0c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/sensor/AnalyzerOptimizerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/SensorOptimizerTest.java @@ -38,7 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class AnalyzerOptimizerTest { +public class SensorOptimizerTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); @@ -47,7 +47,7 @@ public class AnalyzerOptimizerTest { public ExpectedException thrown = ExpectedException.none(); private DefaultFileSystem fs; - private AnalyzerOptimizer optimizer; + private SensorOptimizer optimizer; private Settings settings; private AnalysisMode analysisMode; @@ -56,7 +56,7 @@ public class AnalyzerOptimizerTest { fs = new DefaultFileSystem(temp.newFolder().toPath()); settings = new Settings(); analysisMode = mock(AnalysisMode.class); - optimizer = new AnalyzerOptimizer(fs, new ActiveRulesBuilder().build(), settings, analysisMode); + optimizer = new SensorOptimizer(fs, new ActiveRulesBuilder().build(), settings, analysisMode); } @Test @@ -114,7 +114,7 @@ public class AnalyzerOptimizerTest { .create(RuleKey.of("repo1", "foo")) .activate() .build(); - optimizer = new AnalyzerOptimizer(fs, activeRules, settings, analysisMode); + optimizer = new SensorOptimizer(fs, activeRules, settings, analysisMode); assertThat(optimizer.shouldExecute(descriptor)).isFalse(); @@ -124,7 +124,7 @@ public class AnalyzerOptimizerTest { .create(RuleKey.of("squid", "rule")) .activate() .build(); - optimizer = new AnalyzerOptimizer(fs, activeRules, settings, analysisMode); + optimizer = new SensorOptimizer(fs, activeRules, settings, analysisMode); assertThat(optimizer.shouldExecute(descriptor)).isTrue(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJob.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJob.java new file mode 100644 index 00000000000..06ac3e3533c --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJob.java @@ -0,0 +1,46 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.api.batch.postjob; + +import com.google.common.annotations.Beta; +import org.sonar.api.BatchExtension; + +/** + * PostJobs are executed at the very end of batch analysis. A PostJob can't do any modification + * since everything is already computed (issues, measures,...).
+ * WANRING: Do not rely on the fact that analysis results are available on server side using WS since this is an + * asynchronous process to compute data on server side in 5.x series. + * + * @since 5.2 + */ +@Beta +public interface PostJob extends BatchExtension { + + /** + * Populate {@link PostJobDescriptor} of this PostJob. + */ + void describe(PostJobDescriptor descriptor); + + /** + * The actual sensor code. + */ + void execute(PostJobContext context); + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java new file mode 100644 index 00000000000..8af643a85c9 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java @@ -0,0 +1,56 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.api.batch.postjob; + +import com.google.common.annotations.Beta; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.postjob.issue.Issue; +import org.sonar.api.config.Settings; + +/** + * See {@link PostJob#execute(PostJobContext)} + * @since 5.2 + */ +@Beta +public interface PostJobContext { + + /** + * Get settings of the current project. + */ + Settings settings(); + + /** + * Get analysis mode. + */ + AnalysisMode analysisMode(); + + // ----------- ISSUES -------------- + + /** + * All the unresolved issues of the project, including the issues reported by end-users. + */ + Iterable issues(); + + /** + * All the issues of this project that have been marked as resolved during this scan + */ + Iterable resolvedIssues(); + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobDescriptor.java new file mode 100644 index 00000000000..d82c57b7efb --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobDescriptor.java @@ -0,0 +1,55 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.api.batch.postjob; + +import com.google.common.annotations.Beta; + +/** + * Describe what a {@link PostJob} is doing. Information may be used by the platform + * to log interesting information or perform some optimization. + * See {@link PostJob#describe(PostJobDescriptor)} + * @since 5.2 + */ +@Beta +public interface PostJobDescriptor { + + /** + * Displayable name of the {@link PostJob}. Will be displayed in logs. + */ + PostJobDescriptor name(String postJobName); + + /** + * Property this {@link PostJob} depends on. Used by the platform to skip execution of the {@link PostJob} when + * property is not set. + */ + PostJobDescriptor requireProperty(String... propertyKey); + + /** + * List properties this {@link PostJob} depends on. Used by the platform to skip execution of the {@link PostJob} when + * property is not set. + */ + PostJobDescriptor requireProperties(String... propertyKeys); + + /** + * Should this PostJob be disabled in preview mode. Default is to run all PostJobs in preview mode. + */ + PostJobDescriptor disabledInPreview(); + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/DefaultPostJobDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/DefaultPostJobDescriptor.java new file mode 100644 index 00000000000..f3b51420175 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/DefaultPostJobDescriptor.java @@ -0,0 +1,68 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.api.batch.postjob.internal; + +import org.sonar.api.batch.postjob.PostJobDescriptor; + +import java.util.Arrays; +import java.util.Collection; + +public class DefaultPostJobDescriptor implements PostJobDescriptor { + + private String name; + private String[] properties = new String[0]; + private boolean disabledInPreview = false; + + public String name() { + return name; + } + + public Collection properties() { + return Arrays.asList(properties); + } + + public boolean isDisabledInPreview() { + return disabledInPreview; + } + + @Override + public DefaultPostJobDescriptor name(String name) { + this.name = name; + return this; + } + + @Override + public DefaultPostJobDescriptor requireProperty(String... propertyKey) { + return requireProperties(propertyKey); + } + + @Override + public DefaultPostJobDescriptor requireProperties(String... propertyKeys) { + this.properties = propertyKeys; + return this; + } + + @Override + public DefaultPostJobDescriptor disabledInPreview() { + this.disabledInPreview = true; + return this; + } + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/Issue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/Issue.java new file mode 100644 index 00000000000..ccf79d800fb --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/Issue.java @@ -0,0 +1,87 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.api.batch.postjob.issue; + +import com.google.common.annotations.Beta; +import org.sonar.api.batch.fs.InputPath; +import org.sonar.api.batch.rule.Severity; +import org.sonar.api.rule.RuleKey; + +import javax.annotation.CheckForNull; + +/** + * Represents an issue state at the end of the batch analysis. Only available after local issue tracking in preview mode. + * + * @since 5.2 + */ +@Beta +public interface Issue { + + /** + * Key of the issue. + */ + String key(); + + /** + * The {@link RuleKey} of this issue. + */ + RuleKey ruleKey(); + + /** + * Component key like foo:src/Foo.php + */ + String componentKey(); + + /** + * The {@link InputPath} this issue belongs to. Returns null if issue is global to the project or if component was deleted (for resolved issues). + */ + @CheckForNull + InputPath inputPath(); + + /** + * Line of the issue. Null for global issues and issues on directories. Can also be null + * for files (issue global to the file). + */ + @CheckForNull + Integer line(); + + /** + * Effort to fix the issue. Used by technical debt model. + */ + @CheckForNull + Double effortToFix(); + + /** + * Message of the issue. + */ + @CheckForNull + String message(); + + /** + * Severity. + */ + Severity severity(); + + /** + * If the issue a new one. + */ + boolean isNew(); + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/package-info.java new file mode 100644 index 00000000000..7b3046fc891 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/package-info.java @@ -0,0 +1,21 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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. + */ +@javax.annotation.ParametersAreNonnullByDefault +package org.sonar.api.batch.postjob.issue; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/package-info.java new file mode 100644 index 00000000000..398dee32b77 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/package-info.java @@ -0,0 +1,21 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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. + */ +@javax.annotation.ParametersAreNonnullByDefault +package org.sonar.api.batch.postjob; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Severity.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Severity.java new file mode 100644 index 00000000000..f31055f91d1 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Severity.java @@ -0,0 +1,34 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.api.batch.rule; + +import com.google.common.annotations.Beta; + +/** + * @since 5.2 + */ +@Beta +public enum Severity { + INFO, + MINOR, + MAJOR, + CRITICAL, + BLOCKER +} 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 b52cb989e4c..834325d7792 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 @@ -45,12 +45,12 @@ import java.io.Serializable; public interface SensorContext { /** - * Get settings of the current project. + * Get settings of the current module. */ Settings settings(); /** - * Get filesystem of the current project. + * Get filesystem of the current module. */ FileSystem fileSystem(); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java index e235b33abb4..8a446731c3c 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java @@ -21,6 +21,7 @@ package org.sonar.api.batch.sensor.issue; import com.google.common.annotations.Beta; import org.sonar.api.batch.fs.InputPath; +import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.rule.RuleKey; @@ -34,14 +35,6 @@ import javax.annotation.CheckForNull; @Beta public interface Issue { - enum Severity { - INFO, - MINOR, - MAJOR, - CRITICAL, - BLOCKER - } - /** * The {@link RuleKey} of this issue. */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/NewIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/NewIssue.java index a98ca7eafd9..8a088f533c7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/NewIssue.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/NewIssue.java @@ -22,8 +22,8 @@ package org.sonar.api.batch.sensor.issue; import com.google.common.annotations.Beta; import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.Sensor; -import org.sonar.api.batch.sensor.issue.Issue.Severity; import org.sonar.api.rule.RuleKey; import javax.annotation.Nullable; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java index 280502d23b7..7eee7b189dd 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java @@ -24,6 +24,7 @@ import com.google.common.base.Strings; 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.rule.Severity; import org.sonar.api.batch.sensor.internal.DefaultStorable; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.issue.Issue; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java index 098266cff6f..41ebf8e7a5b 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java @@ -24,8 +24,8 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.api.batch.sensor.issue.Issue.Severity; import org.sonar.api.rule.RuleKey; import static org.assertj.core.api.Assertions.assertThat; -- 2.39.5