}
private int writeChangedLines(ScmProvider provider, ScannerReportWriter writer) {
+ String targetBranchName = branchConfiguration.branchTarget();
+ if (targetBranchName == null) {
+ return 0;
+ }
+
Path rootBaseDir = inputModuleHierarchy.root().getBaseDir();
- Map<Path, DefaultInputFile> allPublishedFiles = StreamSupport.stream(inputComponentStore.allFilesToPublish().spliterator(), false)
+ Map<Path, DefaultInputFile> changedFiles = StreamSupport.stream(inputComponentStore.allChangedFilesToPublish().spliterator(), false)
.collect(Collectors.toMap(DefaultInputFile::path, f -> f));
- Map<Path, Set<Integer>> pathSetMap = provider.branchChangedLines(branchConfiguration.branchTarget(), rootBaseDir, allPublishedFiles.keySet());
+
+ Map<Path, Set<Integer>> pathSetMap = provider.branchChangedLines(targetBranchName, rootBaseDir, changedFiles.keySet());
int count = 0;
if (pathSetMap == null) {
return count;
}
- for (Map.Entry<Path, DefaultInputFile> e : allPublishedFiles.entrySet()) {
+ for (Map.Entry<Path, DefaultInputFile> e : changedFiles.entrySet()) {
Set<Integer> changedLines = pathSetMap.getOrDefault(e.getKey(), Collections.emptySet());
if (changedLines.isEmpty()) {
} else if (component instanceof DefaultInputFile) {
// skip files not marked for publishing
DefaultInputFile inputFile = (DefaultInputFile) component;
- return !inputFile.isPublished() || (branchConfiguration.isShortOrPullRequest() && inputFile.status() == Status.SAME);
+ return !inputFile.isPublished();
}
return false;
}
@Override
public void publish(ScannerReportWriter writer) {
- for (final DefaultInputFile inputFile : componentCache.allFilesToPublish()) {
+ for (final DefaultInputFile inputFile : componentCache.allChangedFilesToPublish()) {
File iofile = writer.getSourceFile(inputFile.batchId());
try (OutputStream output = new BufferedOutputStream(new FileOutputStream(iofile));
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.stream.Stream;
import javax.annotation.CheckForNull;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.InputFile.Status;
import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.DefaultInputDir;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
return inputComponents.values();
}
- public Iterable<DefaultInputFile> allFilesToPublish() {
+ private Stream<DefaultInputFile> allFilesToPublishStream() {
return inputFileCache.values().stream()
.map(f -> (DefaultInputFile) f)
- .filter(DefaultInputFile::isPublished)
- .filter(f -> !branchConfiguration.isShortOrPullRequest() || f.status() != Status.SAME)
+ .filter(DefaultInputFile::isPublished);
+ }
+
+ public Iterable<DefaultInputFile> allFilesToPublish() {
+ return allFilesToPublishStream()::iterator;
+ }
+
+ public Iterable<DefaultInputFile> allChangedFilesToPublish() {
+ return allFilesToPublishStream()
+ .filter(f -> !branchConfiguration.isShortOrPullRequest() || f.status() != InputFile.Status.SAME)
::iterator;
}
public void store(Measure newMeasure) {
if (newMeasure.inputComponent() instanceof DefaultInputFile) {
DefaultInputFile defaultInputFile = (DefaultInputFile) newMeasure.inputComponent();
- if (shouldSkipStorage(defaultInputFile)) {
- return;
- }
defaultInputFile.setPublished(true);
}
saveMeasure(newMeasure.inputComponent(), (DefaultMeasure<?>) newMeasure);
private void saveMeasure(InputComponent component, DefaultMeasure<?> measure) {
if (component.isFile()) {
DefaultInputFile defaultInputFile = (DefaultInputFile) component;
- if (shouldSkipStorage(defaultInputFile)) {
- return;
- }
defaultInputFile.setPublished(true);
}
@Override
public void store(DefaultCoverage defaultCoverage) {
DefaultInputFile inputFile = (DefaultInputFile) defaultCoverage.inputFile();
- if (shouldSkipStorage(inputFile)) {
- return;
- }
inputFile.setPublished(true);
if (defaultCoverage.linesToCover() > 0) {
saveCoverageMetricInternal(inputFile, LINES_TO_COVER, new DefaultMeasure<Integer>().forMetric(LINES_TO_COVER).withValue(defaultCoverage.linesToCover()));
}
@Test
- public void should_skip_report_for_unchanged_files_in_short_branch() {
+ public void should_not_skip_report_for_unchanged_files_in_short_branch() {
// sanity check, normally report gets generated
TaskResult result = getResult(tester);
assertThat(getResult(tester).getReportComponent(result.inputFile(FILE_PATH).key())).isNotNull();
assertThat(result.getReportReader().hasCoverage(fileId)).isTrue();
assertThat(result.getReportReader().readFileSource(fileId)).isNotNull();
- // file is skipped for short branches (no report, no coverage, no duplications)
+ // file is not skipped for short branches (need coverage, duplications coming soon)
TaskResult result2 = getResult(tester.setBranchType(BranchType.SHORT));
- assertThat(result2.getReportComponent(result2.inputFile(FILE_PATH).key())).isNull();
+ assertThat(result2.getReportComponent(result2.inputFile(FILE_PATH).key())).isNotNull();
assertThat(result2.getReportReader().readChangesets(fileId)).isNull();
- assertThat(result2.getReportReader().hasCoverage(fileId)).isFalse();
- assertThat(result.getReportReader().readFileSource(fileId)).isNull();
+ assertThat(result2.getReportReader().hasCoverage(fileId)).isTrue();
+ assertThat(result2.getReportReader().readFileSource(fileId)).isNull();
}
@Test
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));
- when(inputComponentStore.allFilesToPublish()).thenReturn(Arrays.asList(fileWithChangedLines, fileWithoutChangedLines));
+ when(inputComponentStore.allChangedFilesToPublish()).thenReturn(Arrays.asList(fileWithChangedLines, fileWithoutChangedLines));
publisher.publish(writer);
}
@Test
- public void skip_unchanged_components_in_short_branches() throws IOException {
+ public void do_not_skip_unchanged_components_in_short_branches() throws IOException {
when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
when(projectAnalysisInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 4)).isTrue();
assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 5)).isTrue();
- assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isFalse();
- assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isFalse();
- assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isFalse();
+ // do not skip, needed for computing overall coverage
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isTrue();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isTrue();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isTrue();
}
@Test
- public void skip_unchanged_components_in_pull_requests() throws IOException {
+ public void do_not_skip_unchanged_components_in_pull_requests() throws IOException {
when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
when(projectAnalysisInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 4)).isTrue();
assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 5)).isTrue();
- assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isFalse();
- assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isFalse();
- assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isFalse();
+ // do not skip, needed for computing overall coverage
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isTrue();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isTrue();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isTrue();
}
@Test
MetricFinder metricFinder = mock(MetricFinder.class);
when(metricFinder.<Integer>findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC);
when(metricFinder.<String>findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION);
+ when(metricFinder.<Integer>findByKey(CoreMetrics.LINES_TO_COVER_KEY)).thenReturn(CoreMetrics.LINES_TO_COVER);
settings = new MapSettings();
moduleIssues = mock(ModuleIssues.class);
}
@Test
- public void should_skip_file_measure_on_short_branch_when_file_status_is_SAME() {
- InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").setStatus(InputFile.Status.SAME).build();
- when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
-
- underTest.store(new DefaultMeasure()
- .on(file)
- .forMetric(CoreMetrics.NCLOC)
- .withValue(10));
-
- verifyZeroInteractions(measureCache);
- }
-
- @Test
- public void should_skip_file_measure_on_pull_request_when_file_status_is_SAME() {
+ public void should_not_skip_file_measures_on_short_lived_branch_or_pull_request_when_file_status_is_SAME() {
InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").setStatus(InputFile.Status.SAME).build();
when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
+ ArgumentCaptor<DefaultMeasure> argumentCaptor = ArgumentCaptor.forClass(DefaultMeasure.class);
+ when(measureCache.put(eq(file.key()), eq(CoreMetrics.LINES_TO_COVER_KEY), argumentCaptor.capture())).thenReturn(null);
underTest.store(new DefaultMeasure()
.on(file)
- .forMetric(CoreMetrics.NCLOC)
+ .forMetric(CoreMetrics.LINES_TO_COVER)
.withValue(10));
- verifyZeroInteractions(measureCache);
+ DefaultMeasure m = argumentCaptor.getValue();
+ assertThat(m.value()).isEqualTo(10);
+ assertThat(m.metric()).isEqualTo(CoreMetrics.LINES_TO_COVER);
}
@Test