diff options
3 files changed, 47 insertions, 10 deletions
diff --git a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java index 4a48bf9a896..0d019a6d29c 100644 --- a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java +++ b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java @@ -340,7 +340,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile "%s is not a valid line offset for %s. File %s has %s character(s) at line %s", pointer.lineOffset(), owner, this, lineLength, pointer.line()); } - private int lineLength(int line) { + public int lineLength(int line) { return originalLineEndOffsets()[line - 1] - originalLineStartOffsets()[line - 1]; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java index 7da793fdf8d..981ab317066 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java @@ -25,18 +25,18 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.scm.ScmProvider; +import org.sonar.api.impl.utils.ScannerUtils; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.filesystem.InputComponentStore; import org.sonar.scanner.scm.ScmConfiguration; -import org.sonar.api.impl.utils.ScannerUtils; public class ChangedLinesPublisher implements ReportPublisherStep { private static final Logger LOG = Loggers.get(ChangedLinesPublisher.class); @@ -88,8 +88,14 @@ public class ChangedLinesPublisher implements ReportPublisherStep { } for (Map.Entry<Path, DefaultInputFile> e : changedFiles.entrySet()) { + DefaultInputFile inputFile = e.getValue(); Set<Integer> changedLines = pathSetMap.getOrDefault(e.getKey(), Collections.emptySet()); + // detect unchanged last empty line + if (changedLines.size() + 1 == inputFile.lines() && inputFile.lineLength(inputFile.lines()) == 0) { + changedLines.add(inputFile.lines()); + } + if (changedLines.isEmpty()) { LOG.warn("File '{}' was detected as changed but without having changed lines", e.getKey().toAbsolutePath()); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java index d06e33f6111..76d4f2285e7 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java @@ -30,11 +30,11 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.api.batch.scm.ScmProvider; +import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.scan.branch.BranchConfiguration; @@ -113,8 +113,8 @@ public class ChangedLinesPublisherTest { @Test public void write_changed_files() { - DefaultInputFile fileWithChangedLines = createInputFile("path1"); - DefaultInputFile fileWithoutChangedLines = createInputFile("path2"); + DefaultInputFile fileWithChangedLines = createInputFile("path1", "l1\nl2\nl3\n"); + DefaultInputFile fileWithoutChangedLines = createInputFile("path2", "l1\nl2\nl3\n"); Set<Path> paths = new HashSet<>(Arrays.asList(BASE_DIR.resolve("path1"), BASE_DIR.resolve("path2"))); Set<Integer> lines = new HashSet<>(Arrays.asList(1, 10)); when(provider.branchChangedLines(TARGET_BRANCH, BASE_DIR, paths)).thenReturn(Collections.singletonMap(BASE_DIR.resolve("path1"), lines)); @@ -122,12 +122,43 @@ public class ChangedLinesPublisherTest { publisher.publish(writer); - assertPublished(fileWithChangedLines, lines); + assertPublished(fileWithChangedLines, new HashSet<>(Arrays.asList(1, 10))); + assertPublished(fileWithoutChangedLines, Collections.emptySet()); + } + + @Test + public void write_last_line_as_changed_if_all_other_lines_are_changed_and_last_line_is_empty() { + DefaultInputFile fileWithChangedLines = createInputFile("path1", "l1\nl2\nl3\n"); + DefaultInputFile fileWithoutChangedLines = createInputFile("path2", "l1\nl2\nl3\n"); + Set<Path> paths = new HashSet<>(Arrays.asList(BASE_DIR.resolve("path1"), BASE_DIR.resolve("path2"))); + Set<Integer> lines = new HashSet<>(Arrays.asList(1, 2, 3)); + when(provider.branchChangedLines(TARGET_BRANCH, BASE_DIR, paths)).thenReturn(Collections.singletonMap(BASE_DIR.resolve("path1"), lines)); + when(inputComponentStore.allChangedFilesToPublish()).thenReturn(Arrays.asList(fileWithChangedLines, fileWithoutChangedLines)); + + publisher.publish(writer); + + assertPublished(fileWithChangedLines, new HashSet<>(Arrays.asList(1, 2, 3, 4))); + assertPublished(fileWithoutChangedLines, Collections.emptySet()); + } + + @Test + public void dont_write_last_line_as_changed_if_its_not_empty() { + DefaultInputFile fileWithChangedLines = createInputFile("path1", "l1\nl2\nl3\nl4"); + DefaultInputFile fileWithoutChangedLines = createInputFile("path2", "l1\nl2\nl3\nl4"); + Set<Path> paths = new HashSet<>(Arrays.asList(BASE_DIR.resolve("path1"), BASE_DIR.resolve("path2"))); + Set<Integer> lines = new HashSet<>(Arrays.asList(1, 2, 3)); + when(provider.branchChangedLines(TARGET_BRANCH, BASE_DIR, paths)).thenReturn(Collections.singletonMap(BASE_DIR.resolve("path1"), lines)); + when(inputComponentStore.allChangedFilesToPublish()).thenReturn(Arrays.asList(fileWithChangedLines, fileWithoutChangedLines)); + + publisher.publish(writer); + + assertPublished(fileWithChangedLines, new HashSet<>(Arrays.asList(1, 2, 3))); assertPublished(fileWithoutChangedLines, Collections.emptySet()); } - private DefaultInputFile createInputFile(String path) { + private DefaultInputFile createInputFile(String path, String contents) { return new TestInputFileBuilder("module", path) + .setContents(contents) .setProjectBaseDir(BASE_DIR) .setModuleBaseDir(BASE_DIR) .build(); |