Browse Source

SONAR-6408 Restore PostJob execution in preview mode

tags/5.2-RC1
Julien HENRY 9 years ago
parent
commit
91a01dfc9e
37 changed files with 1050 additions and 73 deletions
  1. 3
    1
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
  2. 46
    0
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/extensions/XooPostJob.java
  3. 1
    1
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
  4. 49
    0
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java
  5. 2
    3
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java
  6. 27
    9
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java
  7. 2
    9
      sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java
  8. 6
    1
      sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java
  9. 156
    0
      sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java
  10. 67
    0
      sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobOptimizer.java
  11. 65
    0
      sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobWrapper.java
  12. 21
    0
      sonar-batch/src/main/java/org/sonar/batch/postjob/package-info.java
  13. 6
    2
      sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
  14. 1
    1
      sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
  15. 4
    4
      sonar-batch/src/main/java/org/sonar/batch/sensor/SensorOptimizer.java
  16. 3
    5
      sonar-batch/src/main/java/org/sonar/batch/sensor/SensorWrapper.java
  17. 8
    12
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java
  18. 2
    6
      sonar-batch/src/test/java/org/sonar/batch/deprecated/decorator/DecoratorsSelectorTest.java
  19. 1
    1
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java
  20. 12
    0
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java
  21. 87
    0
      sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java
  22. 81
    0
      sonar-batch/src/test/java/org/sonar/batch/postjob/PostJobOptimizerTest.java
  23. 1
    1
      sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java
  24. 5
    5
      sonar-batch/src/test/java/org/sonar/batch/sensor/SensorOptimizerTest.java
  25. 46
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJob.java
  26. 56
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java
  27. 55
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobDescriptor.java
  28. 68
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/DefaultPostJobDescriptor.java
  29. 87
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/Issue.java
  30. 21
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/package-info.java
  31. 21
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/package-info.java
  32. 34
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Severity.java
  33. 2
    2
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
  34. 1
    8
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java
  35. 1
    1
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/NewIssue.java
  36. 1
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java
  37. 1
    1
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java

+ 3
- 1
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java View File

@@ -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);
}
}

+ 46
- 0
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/extensions/XooPostJob.java View File

@@ -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()));
}

}

+ 1
- 1
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java View File

@@ -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;


+ 49
- 0
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java View File

@@ -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.<Issue>asList());
when(context.resolvedIssues()).thenReturn(Arrays.<Issue>asList());
new XooPostJob().execute(context);
assertThat(logTester.logs()).contains("Resolved issues: 0", "Open issues: 0");
}
}

+ 2
- 3
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java View File

@@ -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;

+ 27
- 9
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java View File

@@ -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 <T> Collection<T> select(Class<T> type, @Nullable Project project, boolean sort, @Nullable ExtensionMatcher matcher) {
@@ -90,7 +99,7 @@ public class BatchExtensionDictionnary {
List<T> 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);
}

+ 2
- 9
sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java View File

@@ -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);

+ 6
- 1
sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java View File

@@ -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();

+ 156
- 0
sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java View File

@@ -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<Issue> issues() {
return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(false)), new Function<DefaultIssue, Issue>() {
@Override
public Issue apply(DefaultIssue input) {
return new DefaultIssueWrapper(input);
}
});
}

@Override
public Iterable<Issue> resolvedIssues() {
return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(true)), new Function<DefaultIssue, Issue>() {
@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<DefaultIssue> {
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;
}
}

}

+ 67
- 0
sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobOptimizer.java View File

@@ -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;
}

}

+ 65
- 0
sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobWrapper.java View File

@@ -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)" : "");
}
}

+ 21
- 0
sonar-batch/src/main/java/org/sonar/batch/postjob/package-info.java View File

@@ -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;

+ 6
- 2
sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java View File

@@ -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,

+ 1
- 1
sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java View File

@@ -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;

sonar-batch/src/main/java/org/sonar/batch/sensor/AnalyzerOptimizer.java → sonar-batch/src/main/java/org/sonar/batch/sensor/SensorOptimizer.java View File

@@ -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)) {

sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java → sonar-batch/src/main/java/org/sonar/batch/sensor/SensorWrapper.java View File

@@ -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();

+ 8
- 12
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java View File

@@ -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);
}


+ 2
- 6
sonar-batch/src/test/java/org/sonar/batch/deprecated/decorator/DecoratorsSelectorTest.java View File

@@ -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 {

+ 1
- 1
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java View File

@@ -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;

+ 12
- 0
sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java View File

@@ -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)) {

+ 87
- 0
sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java View File

@@ -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);

}
}

+ 81
- 0
sonar-batch/src/test/java/org/sonar/batch/postjob/PostJobOptimizerTest.java View File

@@ -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();
}
}

+ 1
- 1
sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java View File

@@ -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;

sonar-batch/src/test/java/org/sonar/batch/sensor/AnalyzerOptimizerTest.java → sonar-batch/src/test/java/org/sonar/batch/sensor/SensorOptimizerTest.java View File

@@ -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();
}


+ 46
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJob.java View File

@@ -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,...). <br/>
* 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);

}

+ 56
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java View File

@@ -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<Issue> issues();

/**
* All the issues of this project that have been marked as resolved during this scan
*/
Iterable<Issue> resolvedIssues();

}

+ 55
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobDescriptor.java View File

@@ -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();

}

+ 68
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/DefaultPostJobDescriptor.java View File

@@ -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<String> 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;
}

}

+ 87
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/Issue.java View File

@@ -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();

}

+ 21
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/issue/package-info.java View File

@@ -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;

+ 21
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/package-info.java View File

@@ -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;

+ 34
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Severity.java View File

@@ -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
}

+ 2
- 2
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java View File

@@ -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();


+ 1
- 8
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java View File

@@ -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.
*/

+ 1
- 1
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/NewIssue.java View File

@@ -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;

+ 1
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java View File

@@ -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;

+ 1
- 1
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java View File

@@ -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;

Loading…
Cancel
Save