Browse Source

SONAR-11778 Measure 'new lines' doesn't match 'lines' if the file ends with new line

tags/8.0
Duarte Meneses 4 years ago
parent
commit
d95a02b5fc

+ 1
- 1
sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java View File

@@ -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];
}


+ 9
- 3
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java View File

@@ -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());
}

+ 37
- 6
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java View File

@@ -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();

Loading…
Cancel
Save