From 80f0a0e9ab86be120d6e3edf3499d7dce828198a Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Mon, 14 Oct 2019 15:28:36 -0500 Subject: [PATCH] SONAR-11245 Record a warning when blame information is missing on some files during analysis --- .../scan/filesystem/CharsetDetector.java | 2 +- .../sonar/scanner/scm/DefaultBlameOutput.java | 8 ++++- .../org/sonar/scanner/scm/ScmPublisher.java | 7 ++-- .../scanner/scm/DefaultBlameOutputTest.java | 34 +++++++++++++++---- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/CharsetDetector.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/CharsetDetector.java index 2fdc526e362..60056cc531a 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/CharsetDetector.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/CharsetDetector.java @@ -32,7 +32,7 @@ import org.apache.commons.io.IOUtils; public class CharsetDetector { private static final int BYTES_TO_DECODE = 4192; - private Path filePath; + private final Path filePath; private BufferedInputStream stream; private Charset detectedCharset; private Charset userEncoding; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java index fd64a9615fe..c701b54ecb9 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java @@ -32,6 +32,7 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.scm.BlameCommand.BlameOutput; import org.sonar.api.batch.scm.BlameLine; +import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.protocol.output.ScannerReport; @@ -46,13 +47,15 @@ class DefaultBlameOutput implements BlameOutput { private static final Logger LOG = Loggers.get(DefaultBlameOutput.class); private final ScannerReportWriter writer; + private AnalysisWarnings analysisWarnings; private final Set allFilesToBlame = new LinkedHashSet<>(); private ProgressReport progressReport; private int count; private int total; - DefaultBlameOutput(ScannerReportWriter writer, List filesToBlame) { + DefaultBlameOutput(ScannerReportWriter writer, AnalysisWarnings analysisWarnings, List filesToBlame) { this.writer = writer; + this.analysisWarnings = analysisWarnings; this.allFilesToBlame.addAll(filesToBlame); count = 0; total = filesToBlame.size(); @@ -131,6 +134,9 @@ class DefaultBlameOutput implements BlameOutput { LOG.warn(" * " + f); } LOG.warn("This may lead to missing/broken features in SonarQube"); + analysisWarnings.addUnique(String.format("Missing blame information for %d %s. This may lead to some features not working correctly. Please check the analysis logs.", + allFilesToBlame.size(), + allFilesToBlame.size() > 1 ? "files" : "file")); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java index 53d030f9f3b..57244da9b35 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java @@ -28,6 +28,7 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Status; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.scm.ScmProvider; +import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.protocol.output.ScannerReport; @@ -48,16 +49,18 @@ public final class ScmPublisher { private final InputComponentStore componentStore; private final FileSystem fs; private final ScannerReportWriter writer; + private AnalysisWarnings analysisWarnings; private final BranchConfiguration branchConfiguration; public ScmPublisher(ScmConfiguration configuration, ProjectRepositoriesSupplier projectRepositoriesSupplier, - InputComponentStore componentStore, FileSystem fs, ReportPublisher reportPublisher, BranchConfiguration branchConfiguration) { + InputComponentStore componentStore, FileSystem fs, ReportPublisher reportPublisher, BranchConfiguration branchConfiguration, AnalysisWarnings analysisWarnings) { this.configuration = configuration; this.projectRepositoriesSupplier = projectRepositoriesSupplier; this.componentStore = componentStore; this.fs = fs; this.branchConfiguration = branchConfiguration; this.writer = reportPublisher.getWriter(); + this.analysisWarnings = analysisWarnings; } public void publish() { @@ -76,7 +79,7 @@ public final class ScmPublisher { if (!filesToBlame.isEmpty()) { String key = provider.key(); LOG.info("SCM Publisher SCM provider for this project is: " + key); - DefaultBlameOutput output = new DefaultBlameOutput(writer, filesToBlame); + DefaultBlameOutput output = new DefaultBlameOutput(writer, analysisWarnings, filesToBlame); try { provider.blameCommand().blame(new DefaultBlameInput(fs, filesToBlame), output); } catch (Exception e) { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java index 78a9c53a4f3..4677916f3e0 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java @@ -20,6 +20,7 @@ package org.sonar.scanner.scm; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import org.junit.Rule; import org.junit.Test; @@ -27,17 +28,36 @@ import org.junit.rules.ExpectedException; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.scm.BlameLine; +import org.sonar.api.utils.System2; +import org.sonar.scanner.notifications.DefaultAnalysisWarnings; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; public class DefaultBlameOutputTest { @Rule public ExpectedException thrown = ExpectedException.none(); + private System2 system2 = mock(System2.class); + private DefaultAnalysisWarnings analysisWarnings = new DefaultAnalysisWarnings(system2); @Test public void shouldNotFailIfNotSameNumberOfLines() { InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(10).build(); - new DefaultBlameOutput(null, Arrays.asList(file)).blameResult(file, Arrays.asList(new BlameLine().revision("1").author("guy"))); + new DefaultBlameOutput(null, analysisWarnings, singletonList(file)).blameResult(file, singletonList(new BlameLine().revision("1").author("guy"))); + } + + @Test + public void addWarningIfFilesMissing() { + InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(10).build(); + + new DefaultBlameOutput(null, analysisWarnings, singletonList(file)).finish(true); + assertThat(analysisWarnings.warnings()).extracting(DefaultAnalysisWarnings.Message::getText) + .containsOnly("Missing blame information for 1 file. This may lead to some features not working correctly. Please check the analysis logs."); } @Test @@ -47,8 +67,8 @@ public class DefaultBlameOutputTest { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("It was not expected to blame file " + file); - new DefaultBlameOutput(null, Arrays.asList(new TestInputFileBuilder("foo", "src/main/java/Foo2.java").build())) - .blameResult(file, Arrays.asList(new BlameLine().revision("1").author("guy"))); + new DefaultBlameOutput(null, analysisWarnings, singletonList(new TestInputFileBuilder("foo", "src/main/java/Foo2.java").build())) + .blameResult(file, singletonList(new BlameLine().revision("1").author("guy"))); } @Test @@ -58,8 +78,8 @@ public class DefaultBlameOutputTest { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Blame date is null for file " + file + " at line 1"); - new DefaultBlameOutput(null, Arrays.asList(file)) - .blameResult(file, Arrays.asList(new BlameLine().revision("1").author("guy"))); + new DefaultBlameOutput(null, analysisWarnings, singletonList(file)) + .blameResult(file, singletonList(new BlameLine().revision("1").author("guy"))); } @Test @@ -69,8 +89,8 @@ public class DefaultBlameOutputTest { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Blame revision is blank for file " + file + " at line 1"); - new DefaultBlameOutput(null, Arrays.asList(file)) - .blameResult(file, Arrays.asList(new BlameLine().date(new Date()).author("guy"))); + new DefaultBlameOutput(null, analysisWarnings, singletonList(file)) + .blameResult(file, singletonList(new BlameLine().date(new Date()).author("guy"))); } } -- 2.39.5