SONAR-6897 Precise if scm data should be copied

In scanner report and for each file we will now explicitely request compute engine to copy previous
SCM data.
This commit is contained in:
Julien HENRY 2016-05-09 14:28:20 +02:00 committed by Sébastien Lesaint
parent 78d5368a7d
commit d66fed5a96
3 changed files with 35 additions and 12 deletions

View File

@ -32,10 +32,13 @@ import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.report.ReportPublisher;
import org.sonar.batch.repository.FileData;
import org.sonar.batch.repository.ProjectRepositories;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Changesets.Builder;
public final class ScmSensor implements Sensor {
@ -45,16 +48,16 @@ public final class ScmSensor implements Sensor {
private final ScmConfiguration configuration;
private final FileSystem fs;
private final ProjectRepositories projectRepositories;
private final BatchComponentCache resourceCache;
private final BatchComponentCache componentCache;
private final ReportPublisher publishReportJob;
public ScmSensor(ProjectDefinition projectDefinition, ScmConfiguration configuration,
ProjectRepositories projectRepositories, FileSystem fs, BatchComponentCache resourceCache, ReportPublisher publishReportJob) {
ProjectRepositories projectRepositories, FileSystem fs, BatchComponentCache componentCache, ReportPublisher publishReportJob) {
this.projectDefinition = projectDefinition;
this.configuration = configuration;
this.projectRepositories = projectRepositories;
this.fs = fs;
this.resourceCache = resourceCache;
this.componentCache = componentCache;
this.publishReportJob = publishReportJob;
}
@ -78,7 +81,7 @@ public final class ScmSensor implements Sensor {
if (!filesToBlame.isEmpty()) {
String key = configuration.provider().key();
LOG.info("SCM provider for this project is: " + key);
DefaultBlameOutput output = new DefaultBlameOutput(publishReportJob.getWriter(), resourceCache, filesToBlame);
DefaultBlameOutput output = new DefaultBlameOutput(publishReportJob.getWriter(), componentCache, filesToBlame);
try {
configuration.provider().blameCommand().blame(new DefaultBlameInput(fs, filesToBlame), output);
} catch (Exception e) {
@ -102,12 +105,22 @@ public final class ScmSensor implements Sensor {
FileData fileData = projectRepositories.fileData(projectDefinition.getKeyWithBranch(), f.relativePath());
if (StringUtils.isEmpty(fileData.revision())) {
addIfNotEmpty(filesToBlame, f);
} else {
askToCopyDataFromPreviousAnalysis(f);
}
}
}
return filesToBlame;
}
private void askToCopyDataFromPreviousAnalysis(InputFile f) {
BatchComponent batchComponent = componentCache.get(f);
Builder scmBuilder = ScannerReport.Changesets.newBuilder();
scmBuilder.setComponentRef(batchComponent.batchId());
scmBuilder.setCopyFromPrevious(true);
publishReportJob.getWriter().writeComponentChangesets(scmBuilder.build());
}
private static void addIfNotEmpty(List<InputFile> filesToBlame, InputFile f) {
if (!f.isEmpty()) {
filesToBlame.add(f);

View File

@ -47,6 +47,7 @@ public class ScmMediumTest {
private static final String MISSING_BLAME_INFORMATION_FOR_THE_FOLLOWING_FILES = "Missing blame information for the following files:";
private static final String CHANGED_CONTENT_SCM_ON_SERVER_XOO = "src/changed_content_scm_on_server.xoo";
private static final String NO_BLAME_SCM_ON_SERVER_XOO = "src/no_blame_scm_on_server.xoo";
private static final String SAME_CONTENT_SCM_ON_SERVER_XOO = "src/same_content_scm_on_server.xoo";
private static final String SAME_CONTENT_NO_SCM_ON_SERVER_XOO = "src/same_content_no_scm_on_server.xoo";
private static final String SAMPLE_XOO_CONTENT = "Sample xoo\ncontent";
@ -66,6 +67,7 @@ public class ScmMediumTest {
.addFileData("com.foo.project", CHANGED_CONTENT_SCM_ON_SERVER_XOO, new FileData(DigestUtils.md5Hex(SAMPLE_XOO_CONTENT), null))
.addFileData("com.foo.project", SAME_CONTENT_NO_SCM_ON_SERVER_XOO, new FileData(DigestUtils.md5Hex(SAMPLE_XOO_CONTENT), null))
.addFileData("com.foo.project", SAME_CONTENT_SCM_ON_SERVER_XOO, new FileData(DigestUtils.md5Hex(SAMPLE_XOO_CONTENT), "1.1"))
.addFileData("com.foo.project", NO_BLAME_SCM_ON_SERVER_XOO, new FileData(DigestUtils.md5Hex(SAMPLE_XOO_CONTENT), "1.1"))
.build();
@Before
@ -205,6 +207,10 @@ public class ScmMediumTest {
FileUtils.write(sameContentScmOnServer, SAMPLE_XOO_CONTENT);
// No need to write .scm file since this file should not be blamed
File noBlameScmOnServer = new File(baseDir, NO_BLAME_SCM_ON_SERVER_XOO);
FileUtils.write(noBlameScmOnServer, SAMPLE_XOO_CONTENT + "\nchanged");
// No .scm file to emulate a failure during blame
File sameContentNoScmOnServer = new File(baseDir, SAME_CONTENT_NO_SCM_ON_SERVER_XOO);
FileUtils.write(sameContentNoScmOnServer, SAMPLE_XOO_CONTENT);
xooScmFile = new File(baseDir, SAME_CONTENT_NO_SCM_ON_SERVER_XOO + ".scm");
@ -228,14 +234,16 @@ public class ScmMediumTest {
assertThat(getChangesets(baseDir, "src/sample.xoo")).isNotNull();
assertThat(getChangesets(baseDir, CHANGED_CONTENT_SCM_ON_SERVER_XOO)).isNotNull();
assertThat(getChangesets(baseDir, CHANGED_CONTENT_SCM_ON_SERVER_XOO).getCopyFromPrevious()).isFalse();
assertThat(getChangesets(baseDir, SAME_CONTENT_SCM_ON_SERVER_XOO)).isNull();
assertThat(getChangesets(baseDir, SAME_CONTENT_SCM_ON_SERVER_XOO).getCopyFromPrevious()).isTrue();
assertThat(getChangesets(baseDir, SAME_CONTENT_NO_SCM_ON_SERVER_XOO)).isNotNull();
assertThat(getChangesets(baseDir, SAME_CONTENT_NO_SCM_ON_SERVER_XOO).getCopyFromPrevious()).isFalse();
assertThat(logTester.logs()).containsSubsequence("3 files to be analyzed", "3/3 files analyzed");
assertThat(logTester.logs()).doesNotContain(MISSING_BLAME_INFORMATION_FOR_THE_FOLLOWING_FILES);
assertThat(getChangesets(baseDir, NO_BLAME_SCM_ON_SERVER_XOO)).isNull();
assertThat(logTester.logs()).containsSubsequence("4 files to be analyzed", "3/4 files analyzed");
assertThat(logTester.logs()).containsSubsequence(MISSING_BLAME_INFORMATION_FOR_THE_FOLLOWING_FILES, " * " + noBlameScmOnServer.getPath().replaceAll("\\\\", "/"));
}
@Test

View File

@ -84,7 +84,7 @@ message Component {
// Only available on PROJECT and MODULE types
string version = 9;
// Only available on PROJECT and MODULE types
// TODO rename this property -> batchKey ? moduleKey ?
// TODO rename this property -> moduleKey ?
string key = 10;
// Only available on FILE type
int32 lines = 11;
@ -162,9 +162,11 @@ message Flow {
message Changesets {
int32 component_ref = 1;
repeated Changeset changeset = 2;
// If set to true then it means changeset attribute is empty and compute engine should copy data from previous analysis
bool copy_from_previous = 2;
repeated Changeset changeset = 3;
// if changesetIndexByLine[5] = 2 then it means that changeset[2] is the last one on line 6
repeated int32 changesetIndexByLine = 3 [packed = true];
repeated int32 changesetIndexByLine = 4 [packed = true];
message Changeset {
string revision = 1;