import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.System2;
+import javax.annotation.Nullable;
+
import java.util.Date;
public class ProjectConfigurator implements BatchComponent {
private Settings settings;
private final System2 system2;
- public ProjectConfigurator(DatabaseSession databaseSession, Settings settings, System2 system2) {
+ public ProjectConfigurator(@Nullable DatabaseSession databaseSession, Settings settings, System2 system2) {
this.databaseSession = databaseSession;
this.settings = settings;
this.system2 = system2;
}
+ public ProjectConfigurator(Settings settings, System2 system2) {
+ this(null, settings, system2);
+ }
+
public Project create(ProjectDefinition definition) {
Project project = new Project(definition.getKey(), loadProjectBranch(), definition.getName());
}
private void checkCurrentAnalysisIsTheLatestOne(String projectKey, Date analysisDate) {
- ResourceModel persistedProject = databaseSession.getSingleResult(ResourceModel.class, "key", projectKey, "enabled", true);
- if (persistedProject != null) {
- Snapshot lastSnapshot = databaseSession.getSingleResult(Snapshot.class, "resourceId", persistedProject.getId(), "last", true);
- if (lastSnapshot != null && !lastSnapshot.getCreatedAt().before(analysisDate)) {
- throw new IllegalArgumentException(
- "'sonar.projectDate' property cannot be older than the date of the last known quality snapshot on this project. Value: '" +
- settings.getString(CoreProperties.PROJECT_DATE_PROPERTY) + "'. " +
- "Latest quality snapshot: '" + DateUtils.formatDateTime(lastSnapshot.getCreatedAt())
- + "'. This property may only be used to rebuild the past in a chronological order.");
+ if (databaseSession != null) {
+ ResourceModel persistedProject = databaseSession.getSingleResult(ResourceModel.class, "key", projectKey, "enabled", true);
+ if (persistedProject != null) {
+ Snapshot lastSnapshot = databaseSession.getSingleResult(Snapshot.class, "resourceId", persistedProject.getId(), "last", true);
+ if (lastSnapshot != null && !lastSnapshot.getCreatedAt().before(analysisDate)) {
+ throw new IllegalArgumentException(
+ "'sonar.projectDate' property cannot be older than the date of the last known quality snapshot on this project. Value: '" +
+ settings.getString(CoreProperties.PROJECT_DATE_PROPERTY) + "'. " +
+ "Latest quality snapshot: '" + DateUtils.formatDateTime(lastSnapshot.getCreatedAt())
+ + "'. This property may only be used to rebuild the past in a chronological order.");
+ }
}
}
}
import org.sonar.api.batch.Event;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.design.Dependency;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.MeasuresFilters;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.MetricFinder;
import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
public Measure addMeasure(Resource resource, Measure measure) {
Bucket bucket = getBucket(resource);
if (bucket != null) {
- Metric metric = metricFinder.findByKey(measure.getMetricKey());
+ org.sonar.api.batch.measure.Metric metric = metricFinder.findByKey(measure.getMetricKey());
if (metric == null) {
throw new SonarException("Unknown metric: " + measure.getMetricKey());
}
LOG.debug("Metric " + metric.key() + " is an internal metric computed by SonarQube. Please update your plugin.");
return measure;
}
- measure.setMetric(metric);
if (measureCache.contains(resource, measure)) {
throw new SonarException("Can not add the same measure twice on " + resource + ": " + measure);
}
import org.sonar.api.database.model.MeasureModel;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
import org.sonar.api.measures.PersistenceMode;
import org.sonar.api.rules.RuleFinder;
import org.sonar.batch.duplication.DuplicationCache;
private final RuleFinder ruleFinder;
private final ResourceCache resourceCache;
private final DuplicationCache duplicationCache;
- private final org.sonar.api.measures.MetricFinder metricFinder;
+ private final MetricFinder metricFinder;
public DuplicationPersister(MyBatis mybatis, RuleFinder ruleFinder, ResourceCache resourceCache,
- DuplicationCache duplicationCache, org.sonar.api.measures.MetricFinder metricFinder) {
+ DuplicationCache duplicationCache, MetricFinder metricFinder) {
this.mybatis = mybatis;
this.ruleFinder = ruleFinder;
this.resourceCache = resourceCache;
// Don't use batch insert for duplications since keeping all data in memory can produce OOM
try (DbSession session = mybatis.openSession(false)) {
MeasureMapper mapper = session.getMapper(MeasureMapper.class);
- org.sonar.api.measures.Metric duplicationMetricWithId = metricFinder.findByKey(CoreMetrics.DUPLICATIONS_DATA_KEY);
+ Metric duplicationMetricWithId = metricFinder.findByKey(CoreMetrics.DUPLICATIONS_DATA_KEY);
for (Entry<List<DuplicationGroup>> entry : duplicationCache.entries()) {
String effectiveKey = entry.key()[0].toString();
Measure measure = new Measure(duplicationMetricWithId, DuplicationUtils.toXml(entry.value())).setPersistenceMode(PersistenceMode.DATABASE);
BatchResource batchResource = resourceCache.get(effectiveKey);
if (MeasurePersister.shouldPersistMeasure(batchResource.resource(), measure)) {
- MeasureModel measureModel = MeasurePersister.model(measure, ruleFinder).setSnapshotId(batchResource.snapshotId());
+ MeasureModel measureModel = MeasurePersister.model(measure, ruleFinder, metricFinder).setSnapshotId(batchResource.snapshotId());
mapper.insert(measureModel);
session.commit();
}
import org.sonar.api.database.model.MeasureMapper;
import org.sonar.api.database.model.MeasureModel;
import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MetricFinder;
import org.sonar.api.measures.RuleMeasure;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
private final RuleFinder ruleFinder;
private final MeasureCache measureCache;
private final ResourceCache resourceCache;
+ private final MetricFinder metricFinder;
- public MeasurePersister(MyBatis mybatis, RuleFinder ruleFinder,
+ public MeasurePersister(MyBatis mybatis, RuleFinder ruleFinder, MetricFinder metricFinder,
MeasureCache measureCache, ResourceCache resourceCache) {
this.mybatis = mybatis;
this.ruleFinder = ruleFinder;
+ this.metricFinder = metricFinder;
this.measureCache = measureCache;
this.resourceCache = resourceCache;
}
BatchResource batchResource = resourceCache.get(effectiveKey);
if (shouldPersistMeasure(batchResource.resource(), measure)) {
- MeasureModel measureModel = model(measure, ruleFinder).setSnapshotId(batchResource.snapshotId());
+ MeasureModel measureModel = model(measure, ruleFinder, metricFinder).setSnapshotId(batchResource.snapshotId());
mapper.insert(measureModel);
}
}
|| isNotEmpty;
}
- static MeasureModel model(Measure measure, RuleFinder ruleFinder) {
+ static MeasureModel model(Measure measure, RuleFinder ruleFinder, MetricFinder metricFinder) {
MeasureModel model = new MeasureModel();
- // we assume that the index has updated the metric
- model.setMetricId(measure.getMetric().getId());
+ model.setMetricId(metricFinder.findByKey(measure.getMetricKey()).getId());
model.setDescription(measure.getDescription());
model.setData(measure.getData());
model.setAlertStatus(measure.getAlertStatus());
private final Settings settings;
private final ResourceDao resourceDao;
- public ProjectReactorValidator(Settings settings, ResourceDao resourceDao) {
+ public ProjectReactorValidator(Settings settings, @Nullable ResourceDao resourceDao) {
this.settings = settings;
this.resourceDao = resourceDao;
}
+ public ProjectReactorValidator(Settings settings) {
+ this(settings, null);
+ }
+
public void validate(ProjectReactor reactor) {
preventAutomaticProjectCreationIfNeeded(reactor);
}
private void preventAutomaticProjectCreationIfNeeded(ProjectReactor reactor) {
- if (settings.getBoolean(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION)) {
- String projectKey = reactor.getRoot().getKeyWithBranch();
- if (resourceDao.findByKey(projectKey) == null) {
- throw new SonarException(String.format("Unable to scan non-existing project \"%s\"", projectKey));
+ if (resourceDao != null) {
+ if (settings.getBoolean(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION)) {
+ String projectKey = reactor.getRoot().getKeyWithBranch();
+ if (resourceDao.findByKey(projectKey) == null) {
+ throw new SonarException(String.format("Unable to scan non-existing project \"%s\"", projectKey));
+ }
}
}
}
if (!ComponentKeys.isValidModuleKey(moduleDef.getKey())) {
validationMessages.add(String.format("\"%s\" is not a valid project or module key. "
+ "Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", moduleDef.getKey()));
- } else if (isSubProject(moduleDef)) {
+ } else if (resourceDao != null && isSubProject(moduleDef)) {
// SONAR-4692 Validate root project is the same than previous analysis to avoid module with same key in different projects
String moduleKey = ComponentKeys.createKey(moduleDef.getKey(), branch);
ResourceDto rootInDB = resourceDao.getRootProjectByComponentKey(moduleKey);
*/
package org.sonar.batch.scan;
-import org.sonar.batch.scan2.ProjectScanContainer;
-
import org.sonar.api.CoreProperties;
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.task.Task;
import org.sonar.batch.bootstrap.BootstrapProperties;
import org.sonar.batch.bootstrap.TaskContainer;
import org.sonar.batch.phases.Phases;
+import org.sonar.batch.scan2.ProjectScanContainer;
public class ScanTask implements Task {
public static final TaskDefinition DEFINITION = TaskDefinition.builder()
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilters;
-import org.sonar.api.measures.MetricFinder;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.config.Settings;
import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.measures.MetricFinder;
import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Library;
when(projectTree.getProjectDefinition(moduleB)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB")));
when(projectTree.getProjectDefinition(moduleB1)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB/moduleB1")));
- DefaultIndex index = new DefaultIndex(persister, null, null, null, projectTree, mock(MetricFinder.class), mock(ScanGraph.class), mock(DeprecatedViolations.class),
+ DefaultIndex index = new DefaultIndex(persister, null, null, null, projectTree, mock(MetricFinder.class), mock(ScanGraph.class),
+ mock(DeprecatedViolations.class),
mock(ResourceKeyMigration.class),
mock(MeasureCache.class));
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
import org.sonar.api.measures.PersistenceMode;
import org.sonar.api.measures.RuleMeasure;
import org.sonar.api.resources.Directory;
when(resourceCache.get("foo:org/foo/Bar.java")).thenReturn(fileResource);
when(resourceCache.get("foo:org/foo")).thenReturn(dirResource);
- measurePersister = new MeasurePersister(getMyBatis(), ruleFinder, measureCache, resourceCache);
+ MetricFinder metricFinder = mock(MetricFinder.class);
+ Metric ncloc = ncloc();
+ Metric coverage = coverage();
+ when(metricFinder.findByKey(ncloc.getKey())).thenReturn(ncloc);
+ when(metricFinder.findByKey(coverage.getKey())).thenReturn(coverage);
+
+ measurePersister = new MeasurePersister(getMyBatis(), ruleFinder, metricFinder, measureCache, resourceCache);
}
@Test
*/
package org.sonar.api.batch.measure;
-import com.google.common.annotations.Beta;
-
import java.io.Serializable;
/**
- * Experimental - do not use
* @since 4.4
*/
-@Beta
public interface Metric<G extends Serializable> {
String key();
*/
package org.sonar.api.batch.measure;
-import com.google.common.annotations.Beta;
import org.sonar.api.BatchComponent;
import javax.annotation.CheckForNull;
import java.util.List;
/**
- * Experimental - do not use
* @since 4.5
*/
-@Beta
public interface MetricFinder extends BatchComponent {
@CheckForNull