aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java12
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java43
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();