diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2016-05-09 14:28:20 +0200 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-05-11 17:01:48 +0200 |
commit | d66fed5a96daccc1e8e6e7c78ba1206c63dcbd66 (patch) | |
tree | 7466a95fc1eae3a7286b67e908099822c9b329d8 | |
parent | 78d5368a7d2344fd758278c9c69971bfbe7f4f3d (diff) | |
download | sonarqube-d66fed5a96daccc1e8e6e7c78ba1206c63dcbd66.tar.gz sonarqube-d66fed5a96daccc1e8e6e7c78ba1206c63dcbd66.zip |
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.
3 files changed, 35 insertions, 12 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/batch/scm/ScmSensor.java b/sonar-scanner-engine/src/main/java/org/sonar/batch/scm/ScmSensor.java index d6880f11fb3..1fdae7db5ce 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/batch/scm/ScmSensor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/batch/scm/ScmSensor.java @@ -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); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java index 8481c17d3ff..2f045e2adfb 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java @@ -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).getCopyFromPrevious()).isTrue(); - assertThat(getChangesets(baseDir, SAME_CONTENT_SCM_ON_SERVER_XOO)).isNull(); + assertThat(getChangesets(baseDir, SAME_CONTENT_NO_SCM_ON_SERVER_XOO).getCopyFromPrevious()).isFalse(); - assertThat(getChangesets(baseDir, SAME_CONTENT_NO_SCM_ON_SERVER_XOO)).isNotNull(); + assertThat(getChangesets(baseDir, NO_BLAME_SCM_ON_SERVER_XOO)).isNull(); - 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(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 diff --git a/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto b/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto index f7ef467f06b..d58fc8d4518 100644 --- a/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto +++ b/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto @@ -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; |