aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuids.java136
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/MergeBranchComponentUuids.java88
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java8
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitor.java10
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/MergeBranchTrackerExecution.java6
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchOrPullRequestTrackerExecution.java41
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerMergeOrTargetBranchInputFactory.java (renamed from server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerMergeBranchInputFactory.java)52
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoader.java8
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java3
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuidsTest.java146
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/MergeBranchComponentUuidsTest.java79
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java14
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/MergeBranchTrackerExecutionTest.java4
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchOrPullRequestTrackerExecutionTest.java48
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoaderTest.java8
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java3
16 files changed, 423 insertions, 231 deletions
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuids.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuids.java
new file mode 100644
index 00000000000..a126933cc3c
--- /dev/null
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuids.java
@@ -0,0 +1,136 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.ce.task.projectanalysis.component;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import javax.annotation.CheckForNull;
+import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.BranchDto;
+import org.sonar.db.component.ComponentDto;
+
+import static com.google.common.base.Preconditions.checkState;
+import static org.sonar.db.component.ComponentDto.removeBranchAndPullRequestFromKey;
+
+/**
+ * Cache a map between component keys and uuids in the merge branch and optionally the target branch (for PR and SLB, and only if this target branch is analyzed)
+ */
+public class MergeAndTargetBranchComponentUuids {
+ private final AnalysisMetadataHolder analysisMetadataHolder;
+ private final DbClient dbClient;
+ private Map<String, String> mergeBranchComponentsUuidsByKey;
+ private Map<String, String> targetBranchComponentsUuidsByKey;
+ private String mergeBranchName;
+ private boolean hasMergeBranchAnalysis;
+ private boolean hasTargetBranchAnalysis;
+ @CheckForNull
+ private String targetBranchUuid;
+
+ public MergeAndTargetBranchComponentUuids(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient) {
+ this.analysisMetadataHolder = analysisMetadataHolder;
+ this.dbClient = dbClient;
+ }
+
+ private void lazyInit() {
+ if (mergeBranchComponentsUuidsByKey == null) {
+ String mergeBranchUuid = analysisMetadataHolder.getBranch().getMergeBranchUuid();
+
+ mergeBranchComponentsUuidsByKey = new HashMap<>();
+ targetBranchComponentsUuidsByKey = new HashMap<>();
+
+ try (DbSession dbSession = dbClient.openSession(false)) {
+
+ Optional<BranchDto> opt = dbClient.branchDao().selectByUuid(dbSession, mergeBranchUuid);
+ checkState(opt.isPresent(), "Merge branch '%s' does not exist", mergeBranchUuid);
+ mergeBranchName = opt.get().getKey();
+
+ initForMergeBranch(mergeBranchUuid, dbSession);
+
+ if (analysisMetadataHolder.isSLBorPR()) {
+ initForTargetBranch(mergeBranchUuid, dbSession);
+ } else {
+ hasTargetBranchAnalysis = false;
+ }
+ }
+ }
+ }
+
+ private void initForTargetBranch(String mergeBranchUuid, DbSession dbSession) {
+ Optional<BranchDto> branchDtoOpt = dbClient.branchDao().selectByBranchKey(dbSession, analysisMetadataHolder.getProject().getUuid(),
+ analysisMetadataHolder.getBranch().getTargetBranchName());
+ targetBranchUuid = branchDtoOpt.map(BranchDto::getUuid).orElse(null);
+ hasTargetBranchAnalysis = targetBranchUuid != null && dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, targetBranchUuid).isPresent();
+ if (hasTargetBranchAnalysis && !targetBranchUuid.equals(mergeBranchUuid)) {
+ List<ComponentDto> targetComponents = dbClient.componentDao().selectByProjectUuid(targetBranchUuid, dbSession);
+ for (ComponentDto dto : targetComponents) {
+ targetBranchComponentsUuidsByKey.put(dto.getKey(), dto.uuid());
+ }
+ }
+ }
+
+ private void initForMergeBranch(String mergeBranchUuid, DbSession dbSession) {
+ hasMergeBranchAnalysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, mergeBranchUuid).isPresent();
+
+ if (hasMergeBranchAnalysis) {
+ List<ComponentDto> components = dbClient.componentDao().selectByProjectUuid(mergeBranchUuid, dbSession);
+ for (ComponentDto dto : components) {
+ mergeBranchComponentsUuidsByKey.put(dto.getKey(), dto.uuid());
+ }
+ }
+ }
+
+ public boolean hasMergeBranchAnalysis() {
+ lazyInit();
+ return hasMergeBranchAnalysis;
+ }
+
+ public boolean hasTargetBranchAnalysis() {
+ lazyInit();
+ return hasTargetBranchAnalysis;
+ }
+
+ public String getMergeBranchName() {
+ lazyInit();
+ return mergeBranchName;
+ }
+
+ public boolean areTargetAndMergeBranchesDifferent() {
+ lazyInit();
+ return targetBranchUuid == null || !analysisMetadataHolder.getBranch().getMergeBranchUuid().equals(targetBranchUuid);
+ }
+
+ @CheckForNull
+ public String getMergeBranchComponentUuid(String dbKey) {
+ lazyInit();
+ String cleanComponentKey = removeBranchAndPullRequestFromKey(dbKey);
+ return mergeBranchComponentsUuidsByKey.get(cleanComponentKey);
+ }
+
+ @CheckForNull
+ public String getTargetBranchComponentUuid(String dbKey) {
+ lazyInit();
+ String cleanComponentKey = removeBranchAndPullRequestFromKey(dbKey);
+ return targetBranchComponentsUuidsByKey.get(cleanComponentKey);
+ }
+}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/MergeBranchComponentUuids.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/MergeBranchComponentUuids.java
deleted file mode 100644
index 888e0c181b1..00000000000
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/MergeBranchComponentUuids.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.ce.task.projectanalysis.component;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import javax.annotation.CheckForNull;
-import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.BranchDto;
-import org.sonar.db.component.ComponentDto;
-
-import static com.google.common.base.Preconditions.checkState;
-import static org.sonar.db.component.ComponentDto.removeBranchAndPullRequestFromKey;
-
-/**
- * Cache a map between component keys and uuids in the merge branch
- */
-public class MergeBranchComponentUuids {
- private final AnalysisMetadataHolder analysisMetadataHolder;
- private final DbClient dbClient;
- private Map<String, String> uuidsByKey;
- private String mergeBranchName;
- private boolean hasMergeBranchAnalysis;
-
- public MergeBranchComponentUuids(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient) {
- this.analysisMetadataHolder = analysisMetadataHolder;
- this.dbClient = dbClient;
- }
-
- private void lazyInit() {
- if (uuidsByKey == null) {
- String mergeBranchUuid = analysisMetadataHolder.getBranch().getMergeBranchUuid();
-
- uuidsByKey = new HashMap<>();
- try (DbSession dbSession = dbClient.openSession(false)) {
-
- List<ComponentDto> components = dbClient.componentDao().selectByProjectUuid(mergeBranchUuid, dbSession);
- for (ComponentDto dto : components) {
- uuidsByKey.put(dto.getKey(), dto.uuid());
- }
-
- Optional<BranchDto> opt = dbClient.branchDao().selectByUuid(dbSession, mergeBranchUuid);
- checkState(opt.isPresent(), "Merge branch '%s' does not exist", mergeBranchUuid);
- mergeBranchName = opt.get().getKey();
-
- hasMergeBranchAnalysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, mergeBranchUuid).isPresent();
- }
- }
- }
-
- public boolean hasMergeBranchAnalysis() {
- lazyInit();
- return hasMergeBranchAnalysis;
- }
-
- public String getMergeBranchName() {
- lazyInit();
- return mergeBranchName;
- }
-
- @CheckForNull
- public String getUuid(String dbKey) {
- lazyInit();
- String cleanComponentKey = removeBranchAndPullRequestFromKey(dbKey);
- return uuidsByKey.get(cleanComponentKey);
- }
-}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java
index 776e9d63b9a..99358168cc2 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java
@@ -34,7 +34,7 @@ import org.sonar.ce.task.projectanalysis.component.BranchPersisterImpl;
import org.sonar.ce.task.projectanalysis.component.ConfigurationRepositoryImpl;
import org.sonar.ce.task.projectanalysis.component.DbIdsRepositoryImpl;
import org.sonar.ce.task.projectanalysis.component.DisabledComponentsHolderImpl;
-import org.sonar.ce.task.projectanalysis.component.MergeBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.projectanalysis.component.SiblingComponentsWithOpenIssues;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderImpl;
@@ -82,7 +82,7 @@ import org.sonar.ce.task.projectanalysis.issue.SiblingsIssuesLoader;
import org.sonar.ce.task.projectanalysis.issue.ShortBranchOrPullRequestTrackerExecution;
import org.sonar.ce.task.projectanalysis.issue.TrackerBaseInputFactory;
import org.sonar.ce.task.projectanalysis.issue.TrackerExecution;
-import org.sonar.ce.task.projectanalysis.issue.TrackerMergeBranchInputFactory;
+import org.sonar.ce.task.projectanalysis.issue.TrackerMergeOrTargetBranchInputFactory;
import org.sonar.ce.task.projectanalysis.issue.TrackerRawInputFactory;
import org.sonar.ce.task.projectanalysis.issue.UpdateConflictResolver;
import org.sonar.ce.task.projectanalysis.issue.commonrule.BranchCoverageRule;
@@ -196,7 +196,7 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop
MeasureComputersHolderImpl.class,
MutableTaskResultHolderImpl.class,
BatchReportReaderImpl.class,
- MergeBranchComponentUuids.class,
+ MergeAndTargetBranchComponentUuids.class,
SiblingComponentsWithOpenIssues.class,
// repositories
@@ -271,7 +271,7 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop
UpdateConflictResolver.class,
TrackerBaseInputFactory.class,
TrackerRawInputFactory.class,
- TrackerMergeBranchInputFactory.class,
+ TrackerMergeOrTargetBranchInputFactory.class,
ClosedIssuesInputFactory.class,
Tracker.class,
TrackerExecution.class,
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitor.java
index b048a138b9f..2c51dff13ef 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitor.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitor.java
@@ -27,7 +27,7 @@ import org.sonar.api.rules.RuleType;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit;
-import org.sonar.ce.task.projectanalysis.component.MergeBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitorAdapter;
import org.sonar.ce.task.projectanalysis.util.cache.DiskCache;
import org.sonar.core.issue.DefaultIssue;
@@ -42,11 +42,11 @@ public class IntegrateIssuesVisitor extends TypeAwareVisitorAdapter {
private final IssueTrackingDelegator issueTracking;
private final SiblingsIssueMerger issueStatusCopier;
private final AnalysisMetadataHolder analysisMetadataHolder;
- private final MergeBranchComponentUuids mergeBranchComponentUuids;
+ private final MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids;
public IntegrateIssuesVisitor(IssueCache issueCache, IssueLifecycle issueLifecycle, IssueVisitors issueVisitors,
AnalysisMetadataHolder analysisMetadataHolder, IssueTrackingDelegator issueTracking, SiblingsIssueMerger issueStatusCopier,
- MergeBranchComponentUuids mergeBranchComponentUuids) {
+ MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids) {
super(CrawlerDepthLimit.FILE, POST_ORDER);
this.issueCache = issueCache;
this.issueLifecycle = issueLifecycle;
@@ -54,7 +54,7 @@ public class IntegrateIssuesVisitor extends TypeAwareVisitorAdapter {
this.analysisMetadataHolder = analysisMetadataHolder;
this.issueTracking = issueTracking;
this.issueStatusCopier = issueStatusCopier;
- this.mergeBranchComponentUuids = mergeBranchComponentUuids;
+ this.mergeAndTargetBranchComponentUuids = mergeAndTargetBranchComponentUuids;
}
@Override
@@ -97,7 +97,7 @@ public class IntegrateIssuesVisitor extends TypeAwareVisitorAdapter {
for (Map.Entry<DefaultIssue, DefaultIssue> entry : matched.entrySet()) {
DefaultIssue raw = entry.getKey();
DefaultIssue base = entry.getValue();
- issueLifecycle.copyExistingOpenIssueFromLongLivingBranch(raw, base, mergeBranchComponentUuids.getMergeBranchName());
+ issueLifecycle.copyExistingOpenIssueFromLongLivingBranch(raw, base, mergeAndTargetBranchComponentUuids.getMergeBranchName());
process(component, raw, cacheAppender);
}
}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/MergeBranchTrackerExecution.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/MergeBranchTrackerExecution.java
index 80daf00697a..26ff4b6f268 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/MergeBranchTrackerExecution.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/MergeBranchTrackerExecution.java
@@ -26,10 +26,10 @@ import org.sonar.core.issue.tracking.Tracking;
public class MergeBranchTrackerExecution {
private final TrackerRawInputFactory rawInputFactory;
- private final TrackerMergeBranchInputFactory mergeInputFactory;
+ private final TrackerMergeOrTargetBranchInputFactory mergeInputFactory;
private final Tracker<DefaultIssue, DefaultIssue> tracker;
- public MergeBranchTrackerExecution(TrackerRawInputFactory rawInputFactory, TrackerMergeBranchInputFactory mergeInputFactory,
+ public MergeBranchTrackerExecution(TrackerRawInputFactory rawInputFactory, TrackerMergeOrTargetBranchInputFactory mergeInputFactory,
Tracker<DefaultIssue, DefaultIssue> tracker) {
this.rawInputFactory = rawInputFactory;
this.mergeInputFactory = mergeInputFactory;
@@ -37,6 +37,6 @@ public class MergeBranchTrackerExecution {
}
public Tracking<DefaultIssue, DefaultIssue> track(Component component) {
- return tracker.trackNonClosed(rawInputFactory.create(component), mergeInputFactory.create(component));
+ return tracker.trackNonClosed(rawInputFactory.create(component), mergeInputFactory.createForMergeBranch(component));
}
}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchOrPullRequestTrackerExecution.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchOrPullRequestTrackerExecution.java
index 3bc412a5c5c..f5ef7f30671 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchOrPullRequestTrackerExecution.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchOrPullRequestTrackerExecution.java
@@ -36,13 +36,12 @@ import org.sonar.core.util.stream.MoreCollectors;
public class ShortBranchOrPullRequestTrackerExecution {
private final TrackerBaseInputFactory baseInputFactory;
private final TrackerRawInputFactory rawInputFactory;
- private final TrackerMergeBranchInputFactory mergeInputFactory;
+ private final TrackerMergeOrTargetBranchInputFactory mergeInputFactory;
private final Tracker<DefaultIssue, DefaultIssue> tracker;
private final NewLinesRepository newLinesRepository;
public ShortBranchOrPullRequestTrackerExecution(TrackerBaseInputFactory baseInputFactory, TrackerRawInputFactory rawInputFactory,
- TrackerMergeBranchInputFactory mergeInputFactory,
- Tracker<DefaultIssue, DefaultIssue> tracker, NewLinesRepository newLinesRepository) {
+ TrackerMergeOrTargetBranchInputFactory mergeInputFactory, Tracker<DefaultIssue, DefaultIssue> tracker, NewLinesRepository newLinesRepository) {
this.baseInputFactory = baseInputFactory;
this.rawInputFactory = rawInputFactory;
this.mergeInputFactory = mergeInputFactory;
@@ -52,21 +51,41 @@ public class ShortBranchOrPullRequestTrackerExecution {
public Tracking<DefaultIssue, DefaultIssue> track(Component component) {
Input<DefaultIssue> rawInput = rawInputFactory.create(component);
- Input<DefaultIssue> baseInput = baseInputFactory.create(component);
+ Input<DefaultIssue> previousAnalysisInput = baseInputFactory.create(component);
- Input<DefaultIssue> unmatchedRawInput;
+ // Step 1: track issues with merge branch (= long living)
+ Input<DefaultIssue> unmatchedRawsAfterMergeBranchTracking;
if (mergeInputFactory.hasMergeBranchAnalysis()) {
- Input<DefaultIssue> mergeInput = mergeInputFactory.create(component);
+ Input<DefaultIssue> mergeInput = mergeInputFactory.createForMergeBranch(component);
Tracking<DefaultIssue, DefaultIssue> mergeTracking = tracker.trackNonClosed(rawInput, mergeInput);
List<DefaultIssue> unmatchedRaws = mergeTracking.getUnmatchedRaws().collect(MoreCollectors.toList());
- unmatchedRawInput = new DefaultTrackingInput(unmatchedRaws, rawInput.getLineHashSequence(), rawInput.getBlockHashSequence());
+ unmatchedRawsAfterMergeBranchTracking = new DefaultTrackingInput(unmatchedRaws, rawInput.getLineHashSequence(), rawInput.getBlockHashSequence());
} else {
- List<DefaultIssue> filteredRaws = keepIssuesHavingAtLeastOneLocationOnChangedLines(component, rawInput.getIssues());
- unmatchedRawInput = new DefaultTrackingInput(filteredRaws, rawInput.getLineHashSequence(), rawInput.getBlockHashSequence());
+ unmatchedRawsAfterMergeBranchTracking = rawInput;
}
- // do second tracking with base branch using raws issues that are still unmatched
- return tracker.trackNonClosed(unmatchedRawInput, baseInput);
+ // Step 2: track remaining unmatched issues with target branch
+ Input<DefaultIssue> unmatchedRawsAfterTargetBranchTracking;
+ if (mergeInputFactory.hasTargetBranchAnalysis() && mergeInputFactory.areTargetAndMergeBranchesDifferent()) {
+ Input<DefaultIssue> targetInput = mergeInputFactory.createForTargetBranch(component);
+ Tracking<DefaultIssue, DefaultIssue> mergeTracking = tracker.trackNonClosed(unmatchedRawsAfterMergeBranchTracking, targetInput);
+ List<DefaultIssue> unmatchedRaws = mergeTracking.getUnmatchedRaws().collect(MoreCollectors.toList());
+ unmatchedRawsAfterTargetBranchTracking = new DefaultTrackingInput(unmatchedRaws, rawInput.getLineHashSequence(), rawInput.getBlockHashSequence());
+ } else {
+ unmatchedRawsAfterTargetBranchTracking = unmatchedRawsAfterMergeBranchTracking;
+ }
+
+ // Step 3: if there is no analysis or merge or target branch, keep only issues on changed lines
+ Input<DefaultIssue> unmatchedRawsAfterChangedLineFiltering;
+ if (!mergeInputFactory.hasTargetBranchAnalysis() || !mergeInputFactory.hasMergeBranchAnalysis()) {
+ List<DefaultIssue> filteredRaws = keepIssuesHavingAtLeastOneLocationOnChangedLines(component, unmatchedRawsAfterTargetBranchTracking.getIssues());
+ unmatchedRawsAfterChangedLineFiltering = new DefaultTrackingInput(filteredRaws, rawInput.getLineHashSequence(), rawInput.getBlockHashSequence());
+ } else {
+ unmatchedRawsAfterChangedLineFiltering = unmatchedRawsAfterTargetBranchTracking;
+ }
+
+ // Step 4: track issues of previous analysis of the current branch/PR
+ return tracker.trackNonClosed(unmatchedRawsAfterChangedLineFiltering, previousAnalysisInput);
}
private List<DefaultIssue> keepIssuesHavingAtLeastOneLocationOnChangedLines(Component component, Collection<DefaultIssue> issues) {
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerMergeBranchInputFactory.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerMergeOrTargetBranchInputFactory.java
index 8690f1bd8dd..94322468791 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerMergeBranchInputFactory.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerMergeOrTargetBranchInputFactory.java
@@ -23,7 +23,7 @@ import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.MergeBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.tracking.Input;
import org.sonar.core.issue.tracking.LazyInput;
@@ -31,46 +31,60 @@ import org.sonar.core.issue.tracking.LineHashSequence;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-public class TrackerMergeBranchInputFactory {
+public class TrackerMergeOrTargetBranchInputFactory {
private static final LineHashSequence EMPTY_LINE_HASH_SEQUENCE = new LineHashSequence(Collections.emptyList());
- private final ComponentIssuesLoader mergeIssuesLoader;
+ private final ComponentIssuesLoader componentIssuesLoader;
private final DbClient dbClient;
- private final MergeBranchComponentUuids mergeBranchComponentUuids;
+ private final MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids;
- public TrackerMergeBranchInputFactory(ComponentIssuesLoader mergeIssuesLoader, MergeBranchComponentUuids mergeBranchComponentUuids, DbClient dbClient) {
- this.mergeIssuesLoader = mergeIssuesLoader;
- this.mergeBranchComponentUuids = mergeBranchComponentUuids;
+ public TrackerMergeOrTargetBranchInputFactory(ComponentIssuesLoader componentIssuesLoader, MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids,
+ DbClient dbClient) {
+ this.componentIssuesLoader = componentIssuesLoader;
+ this.mergeAndTargetBranchComponentUuids = mergeAndTargetBranchComponentUuids;
this.dbClient = dbClient;
// TODO detect file moves?
}
public boolean hasMergeBranchAnalysis() {
- return mergeBranchComponentUuids.hasMergeBranchAnalysis();
+ return mergeAndTargetBranchComponentUuids.hasMergeBranchAnalysis();
}
- public Input<DefaultIssue> create(Component component) {
- String mergeBranchComponentUuid = mergeBranchComponentUuids.getUuid(component.getDbKey());
- return new MergeLazyInput(component.getType(), mergeBranchComponentUuid);
+ public boolean hasTargetBranchAnalysis() {
+ return mergeAndTargetBranchComponentUuids.hasTargetBranchAnalysis();
}
- private class MergeLazyInput extends LazyInput<DefaultIssue> {
+ public boolean areTargetAndMergeBranchesDifferent() {
+ return mergeAndTargetBranchComponentUuids.areTargetAndMergeBranchesDifferent();
+ }
+
+ public Input<DefaultIssue> createForMergeBranch(Component component) {
+ String mergeBranchComponentUuid = mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(component.getDbKey());
+ return new MergeOrTargetLazyInput(component.getType(), mergeBranchComponentUuid);
+ }
+
+ public Input<DefaultIssue> createForTargetBranch(Component component) {
+ String targetBranchComponentUuid = mergeAndTargetBranchComponentUuids.getTargetBranchComponentUuid(component.getDbKey());
+ return new MergeOrTargetLazyInput(component.getType(), targetBranchComponentUuid);
+ }
+
+ private class MergeOrTargetLazyInput extends LazyInput<DefaultIssue> {
private final Component.Type type;
- private final String mergeBranchComponentUuid;
+ private final String mergeOrTargetBranchComponentUuid;
- private MergeLazyInput(Component.Type type, @Nullable String mergeBranchComponentUuid) {
+ private MergeOrTargetLazyInput(Component.Type type, @Nullable String mergeOrTargetBranchComponentUuid) {
this.type = type;
- this.mergeBranchComponentUuid = mergeBranchComponentUuid;
+ this.mergeOrTargetBranchComponentUuid = mergeOrTargetBranchComponentUuid;
}
@Override
protected LineHashSequence loadLineHashSequence() {
- if (mergeBranchComponentUuid == null || type != Component.Type.FILE) {
+ if (mergeOrTargetBranchComponentUuid == null || type != Component.Type.FILE) {
return EMPTY_LINE_HASH_SEQUENCE;
}
try (DbSession session = dbClient.openSession(false)) {
- List<String> hashes = dbClient.fileSourceDao().selectLineHashes(session, mergeBranchComponentUuid);
+ List<String> hashes = dbClient.fileSourceDao().selectLineHashes(session, mergeOrTargetBranchComponentUuid);
if (hashes == null || hashes.isEmpty()) {
return EMPTY_LINE_HASH_SEQUENCE;
}
@@ -80,10 +94,10 @@ public class TrackerMergeBranchInputFactory {
@Override
protected List<DefaultIssue> loadIssues() {
- if (mergeBranchComponentUuid == null) {
+ if (mergeOrTargetBranchComponentUuid == null) {
return Collections.emptyList();
}
- return mergeIssuesLoader.loadOpenIssuesWithChanges(mergeBranchComponentUuid);
+ return componentIssuesLoader.loadOpenIssuesWithChanges(mergeOrTargetBranchComponentUuid);
}
}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoader.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoader.java
index e553e40f8a6..ba8a81f75bd 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoader.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoader.java
@@ -25,7 +25,7 @@ import org.sonar.api.utils.log.Loggers;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.analysis.Branch;
import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.MergeBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.source.FileSourceDto;
@@ -35,9 +35,9 @@ public class ScmInfoDbLoader {
private final AnalysisMetadataHolder analysisMetadataHolder;
private final DbClient dbClient;
- private final MergeBranchComponentUuids mergeBranchComponentUuid;
+ private final MergeAndTargetBranchComponentUuids mergeBranchComponentUuid;
- public ScmInfoDbLoader(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient, MergeBranchComponentUuids mergeBranchComponentUuid) {
+ public ScmInfoDbLoader(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient, MergeAndTargetBranchComponentUuids mergeBranchComponentUuid) {
this.analysisMetadataHolder = analysisMetadataHolder;
this.dbClient = dbClient;
this.mergeBranchComponentUuid = mergeBranchComponentUuid;
@@ -67,7 +67,7 @@ public class ScmInfoDbLoader {
// at this point, it's the first analysis but had copyFromPrevious flag true
Branch branch = analysisMetadataHolder.getBranch();
if (!branch.isMain()) {
- return Optional.ofNullable(mergeBranchComponentUuid.getUuid(file.getDbKey()));
+ return Optional.ofNullable(mergeBranchComponentUuid.getMergeBranchComponentUuid(file.getDbKey()));
}
return Optional.empty();
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java
index adc120665a2..954d14b1b3e 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java
@@ -307,7 +307,8 @@ public class PostProjectAnalysisTasksExecutorTest {
throw new UnsupportedOperationException();
}
- @Override public String getTargetBranchName() {
+ @Override
+ public String getTargetBranchName() {
throw new UnsupportedOperationException();
}
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuidsTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuidsTest.java
new file mode 100644
index 00000000000..02a4f40dabf
--- /dev/null
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuidsTest.java
@@ -0,0 +1,146 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.ce.task.projectanalysis.component;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
+import org.sonar.ce.task.projectanalysis.analysis.Branch;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.BranchType;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
+import org.sonar.server.project.Project;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.db.component.SnapshotTesting.newAnalysis;
+
+public class MergeAndTargetBranchComponentUuidsTest {
+ @Rule
+ public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
+
+ @Rule
+ public DbTester db = DbTester.create();
+
+ private MergeAndTargetBranchComponentUuids underTest;
+ private Branch branch = mock(Branch.class);
+
+ private ComponentDto longBranch1;
+ private ComponentDto longBranch1File;
+ private ComponentDto shortBranch1File;
+ private ComponentDto shortBranch2File;
+ private Project project;
+ private ComponentDto shortBranch1;
+ private ComponentDto shortBranch2;
+ private ComponentDto longBranch2;
+ private ComponentDto longBranch2File;
+
+ @Before
+ public void setUp() {
+ underTest = new MergeAndTargetBranchComponentUuids(analysisMetadataHolder, db.getDbClient());
+ project = mock(Project.class);
+ analysisMetadataHolder.setProject(project);
+ analysisMetadataHolder.setBranch(branch);
+
+ ComponentDto projectDto = db.components().insertMainBranch();
+ when(project.getUuid()).thenReturn(projectDto.uuid());
+ longBranch1 = db.components().insertProjectBranch(projectDto, b -> b.setKey("longBranch1"));
+ longBranch2 = db.components().insertProjectBranch(projectDto, b -> b.setKey("longBranch2"));
+ shortBranch1 = db.components().insertProjectBranch(projectDto, b -> b.setKey("shortBranch1").setBranchType(BranchType.SHORT).setMergeBranchUuid(longBranch1.uuid()));
+ shortBranch2 = db.components().insertProjectBranch(projectDto, b -> b.setKey("shortBranch2").setBranchType(BranchType.SHORT).setMergeBranchUuid(longBranch1.uuid()));
+ longBranch1File = ComponentTesting.newFileDto(longBranch1, null, "file").setUuid("long1File");
+ longBranch2File = ComponentTesting.newFileDto(longBranch2, null, "file").setUuid("long2File");
+ shortBranch1File = ComponentTesting.newFileDto(shortBranch1, null, "file").setUuid("file1");
+ shortBranch2File = ComponentTesting.newFileDto(shortBranch2, null, "file").setUuid("file2");
+ db.components().insertComponents(longBranch1File, shortBranch1File, shortBranch2File, longBranch2File);
+ }
+
+ @Test
+ public void should_support_db_key_when_looking_for_merge_component() {
+ when(branch.getMergeBranchUuid()).thenReturn(longBranch1.uuid());
+ when(branch.getType()).thenReturn(BranchType.SHORT);
+ when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
+ db.components().insertSnapshot(newAnalysis(longBranch1));
+ assertThat(underTest.getMergeBranchComponentUuid(shortBranch1File.getDbKey())).isEqualTo(longBranch1File.uuid());
+ assertThat(underTest.getTargetBranchComponentUuid(shortBranch1File.getDbKey())).isNull();
+ assertThat(underTest.hasMergeBranchAnalysis()).isTrue();
+ assertThat(underTest.hasTargetBranchAnalysis()).isFalse();
+ assertThat(underTest.areTargetAndMergeBranchesDifferent()).isTrue();
+ assertThat(underTest.getMergeBranchName()).isEqualTo("longBranch1");
+ }
+
+ @Test
+ public void should_support_db_key_when_looking_for_target_component() {
+ when(branch.getMergeBranchUuid()).thenReturn(longBranch1.uuid());
+ when(branch.getTargetBranchName()).thenReturn("shortBranch2");
+ when(branch.getType()).thenReturn(BranchType.SHORT);
+ db.components().insertSnapshot(newAnalysis(longBranch1));
+ db.components().insertSnapshot(newAnalysis(shortBranch2));
+ assertThat(underTest.getMergeBranchComponentUuid(shortBranch1File.getDbKey())).isEqualTo(longBranch1File.uuid());
+ assertThat(underTest.getTargetBranchComponentUuid(shortBranch1File.getDbKey())).isEqualTo(shortBranch2File.uuid());
+ assertThat(underTest.hasMergeBranchAnalysis()).isTrue();
+ assertThat(underTest.hasTargetBranchAnalysis()).isTrue();
+ assertThat(underTest.areTargetAndMergeBranchesDifferent()).isTrue();
+ }
+
+ @Test
+ public void should_support_key_when_looking_for_merge_component() {
+ when(branch.getMergeBranchUuid()).thenReturn(longBranch1.uuid());
+ when(branch.getType()).thenReturn(BranchType.SHORT);
+ when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
+ db.components().insertSnapshot(newAnalysis(longBranch1));
+ assertThat(underTest.getMergeBranchComponentUuid(shortBranch1File.getKey())).isEqualTo(longBranch1File.uuid());
+ }
+
+ @Test
+ public void return_null_if_file_doesnt_exist() {
+ when(branch.getMergeBranchUuid()).thenReturn(longBranch1.uuid());
+ when(branch.getType()).thenReturn(BranchType.SHORT);
+ when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
+ db.components().insertSnapshot(newAnalysis(longBranch1));
+ assertThat(underTest.getMergeBranchComponentUuid("doesnt exist")).isNull();
+ }
+
+ @Test
+ public void skip_init_if_no_merge_branch_analysis() {
+ when(branch.getMergeBranchUuid()).thenReturn(longBranch1.uuid());
+ when(branch.getType()).thenReturn(BranchType.SHORT);
+ when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
+ assertThat(underTest.getMergeBranchComponentUuid(shortBranch1File.getDbKey())).isNull();
+ }
+
+ @Test
+ public void should_skip_target_components_init_on_long_branches() {
+ when(branch.getMergeBranchUuid()).thenReturn(longBranch1.uuid());
+ when(branch.getType()).thenReturn(BranchType.LONG);
+ when(branch.getTargetBranchName()).thenThrow(new IllegalStateException("Unsupported on long branches"));
+ db.components().insertSnapshot(newAnalysis(longBranch1));
+
+ assertThat(underTest.getMergeBranchComponentUuid(longBranch2File.getDbKey())).isEqualTo(longBranch1File.uuid());
+ assertThat(underTest.getTargetBranchComponentUuid(longBranch2File.getDbKey())).isNull();
+ assertThat(underTest.hasMergeBranchAnalysis()).isTrue();
+ assertThat(underTest.hasTargetBranchAnalysis()).isFalse();
+ assertThat(underTest.areTargetAndMergeBranchesDifferent()).isTrue();
+ assertThat(underTest.getMergeBranchName()).isEqualTo("longBranch1");
+ }
+}
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/MergeBranchComponentUuidsTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/MergeBranchComponentUuidsTest.java
deleted file mode 100644
index a0409c6a56e..00000000000
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/MergeBranchComponentUuidsTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.ce.task.projectanalysis.component;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
-import org.sonar.ce.task.projectanalysis.analysis.Branch;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class MergeBranchComponentUuidsTest {
- @Rule
- public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
-
- @Rule
- public DbTester db = DbTester.create();
-
- private MergeBranchComponentUuids underTest;
- private Branch branch = mock(Branch.class);
-
- private ComponentDto mergeBranch;
- private ComponentDto mergeBranchFile;
- private ComponentDto branchFile;
-
- @Before
- public void setUp() {
- underTest = new MergeBranchComponentUuids(analysisMetadataHolder, db.getDbClient());
- analysisMetadataHolder.setBranch(branch);
-
- ComponentDto project = db.components().insertMainBranch();
- mergeBranch = db.components().insertProjectBranch(project, b -> b.setKey("mergeBranch"));
- ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("branch1"));
- mergeBranchFile = ComponentTesting.newFileDto(mergeBranch, null, "file").setUuid("mergeFile");
- branchFile = ComponentTesting.newFileDto(branch, null, "file").setUuid("file1");
- db.components().insertComponents(mergeBranchFile, branchFile);
- }
-
- @Test
- public void should_support_db_key() {
- when(branch.getMergeBranchUuid()).thenReturn(mergeBranch.uuid());
- assertThat(underTest.getUuid(branchFile.getDbKey())).isEqualTo(mergeBranchFile.uuid());
- }
-
- @Test
- public void should_support_key() {
- when(branch.getMergeBranchUuid()).thenReturn(mergeBranch.uuid());
- assertThat(underTest.getUuid(branchFile.getKey())).isEqualTo(mergeBranchFile.uuid());
- }
-
- @Test
- public void return_null_if_file_doesnt_exist() {
- when(branch.getMergeBranchUuid()).thenReturn(mergeBranch.uuid());
- assertThat(underTest.getUuid("doesnt exist")).isNull();
- }
-}
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java
index 55e56244c62..90853ca12bc 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java
@@ -36,7 +36,7 @@ import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.analysis.Branch;
import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.MergeBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
import org.sonar.ce.task.projectanalysis.component.ReportComponent;
import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
@@ -116,9 +116,9 @@ public class IntegrateIssuesVisitorTest {
private MovedFilesRepository movedFilesRepository = mock(MovedFilesRepository.class);
private IssueLifecycle issueLifecycle = mock(IssueLifecycle.class);
private IssueVisitor issueVisitor = mock(IssueVisitor.class);
- private MergeBranchComponentUuids mergeBranchComponentsUuids = mock(MergeBranchComponentUuids.class);
+ private MergeAndTargetBranchComponentUuids mergeBranchComponentsUuids = mock(MergeAndTargetBranchComponentUuids.class);
private SiblingsIssueMerger issueStatusCopier = mock(SiblingsIssueMerger.class);
- private MergeBranchComponentUuids mergeBranchComponentUuids = mock(MergeBranchComponentUuids.class);
+ private MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids = mock(MergeAndTargetBranchComponentUuids.class);
private SourceLinesHashRepository sourceLinesHash = mock(SourceLinesHashRepository.class);
private NewLinesRepository newLinesRepository = mock(NewLinesRepository.class);
@@ -145,7 +145,7 @@ public class IntegrateIssuesVisitorTest {
TrackerRawInputFactory rawInputFactory = new TrackerRawInputFactory(treeRootHolder, reportReader, sourceLinesHash, new CommonRuleEngineImpl(),
issueFilter, ruleRepositoryRule, activeRulesHolder);
TrackerBaseInputFactory baseInputFactory = new TrackerBaseInputFactory(issuesLoader, dbClient, movedFilesRepository, mock(ReportModulesPath.class), analysisMetadataHolder, new IssueFieldsSetter(), mock(ComponentsWithUnprocessedIssues.class));
- TrackerMergeBranchInputFactory mergeInputFactory = new TrackerMergeBranchInputFactory(issuesLoader, mergeBranchComponentsUuids, dbClient);
+ TrackerMergeOrTargetBranchInputFactory mergeInputFactory = new TrackerMergeOrTargetBranchInputFactory(issuesLoader, mergeBranchComponentsUuids, dbClient);
ClosedIssuesInputFactory closedIssuesInputFactory = new ClosedIssuesInputFactory(issuesLoader, dbClient, movedFilesRepository);
tracker = new TrackerExecution(baseInputFactory, rawInputFactory, closedIssuesInputFactory, new Tracker<>(), issuesLoader, analysisMetadataHolder);
shortBranchTracker = new ShortBranchOrPullRequestTrackerExecution(baseInputFactory, rawInputFactory, mergeInputFactory, new Tracker<>(), newLinesRepository);
@@ -155,7 +155,7 @@ public class IntegrateIssuesVisitorTest {
treeRootHolder.setRoot(PROJECT);
issueCache = new IssueCache(temp.newFile(), System2.INSTANCE);
when(issueFilter.accept(any(DefaultIssue.class), eq(FILE))).thenReturn(true);
- underTest = new IntegrateIssuesVisitor(issueCache, issueLifecycle, issueVisitors, analysisMetadataHolder, trackingDelegator, issueStatusCopier, mergeBranchComponentUuids);
+ underTest = new IntegrateIssuesVisitor(issueCache, issueLifecycle, issueVisitors, analysisMetadataHolder, trackingDelegator, issueStatusCopier, mergeAndTargetBranchComponentUuids);
}
@Test
@@ -262,8 +262,8 @@ public class IntegrateIssuesVisitorTest {
@Test
public void copy_issues_when_creating_new_long_living_branch() {
- when(mergeBranchComponentsUuids.getUuid(FILE_KEY)).thenReturn(FILE_UUID_ON_BRANCH);
- when(mergeBranchComponentUuids.getMergeBranchName()).thenReturn("master");
+ when(mergeBranchComponentsUuids.getMergeBranchComponentUuid(FILE_KEY)).thenReturn(FILE_UUID_ON_BRANCH);
+ when(mergeAndTargetBranchComponentUuids.getMergeBranchName()).thenReturn("master");
when(analysisMetadataHolder.isLongLivingBranch()).thenReturn(true);
when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(true);
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/MergeBranchTrackerExecutionTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/MergeBranchTrackerExecutionTest.java
index ab510b11471..6613d954249 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/MergeBranchTrackerExecutionTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/MergeBranchTrackerExecutionTest.java
@@ -37,7 +37,7 @@ public class MergeBranchTrackerExecutionTest {
@Mock
private TrackerRawInputFactory rawInputFactory;
@Mock
- private TrackerMergeBranchInputFactory mergeInputFactory;
+ private TrackerMergeOrTargetBranchInputFactory mergeInputFactory;
@Mock
private Tracker<DefaultIssue, DefaultIssue> tracker;
@Mock
@@ -57,7 +57,7 @@ public class MergeBranchTrackerExecutionTest {
Input<DefaultIssue> mergeInput = mock(Input.class);
NonClosedTracking<DefaultIssue, DefaultIssue> result = mock(NonClosedTracking.class);
when(rawInputFactory.create(component)).thenReturn(rawInput);
- when(mergeInputFactory.create(component)).thenReturn(mergeInput);
+ when(mergeInputFactory.createForMergeBranch(component)).thenReturn(mergeInput);
when(tracker.trackNonClosed(rawInput, mergeInput)).thenReturn(result);
assertThat(underTest.track(component)).isEqualTo(result);
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchOrPullRequestTrackerExecutionTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchOrPullRequestTrackerExecutionTest.java
index 94fc7b5334b..3e651ba26eb 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchOrPullRequestTrackerExecutionTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ShortBranchOrPullRequestTrackerExecutionTest.java
@@ -62,7 +62,7 @@ public class ShortBranchOrPullRequestTrackerExecutionTest {
@Mock
private TrackerBaseInputFactory baseFactory;
@Mock
- private TrackerMergeBranchInputFactory mergeFactory;
+ private TrackerMergeOrTargetBranchInputFactory mergeFactory;
@Mock
private NewLinesRepository newLinesRepository;
@@ -71,6 +71,7 @@ public class ShortBranchOrPullRequestTrackerExecutionTest {
private List<DefaultIssue> rawIssues = new ArrayList<>();
private List<DefaultIssue> baseIssues = new ArrayList<>();
private List<DefaultIssue> mergeBranchIssues = new ArrayList<>();
+ private List<DefaultIssue> targetBranchIssues = new ArrayList<>();
@Before
public void setUp() throws Exception {
@@ -78,7 +79,8 @@ public class ShortBranchOrPullRequestTrackerExecutionTest {
when(rawFactory.create(FILE)).thenReturn(createInput(rawIssues));
when(baseFactory.create(FILE)).thenReturn(createInput(baseIssues));
- when(mergeFactory.create(FILE)).thenReturn(createInput(mergeBranchIssues));
+ when(mergeFactory.createForMergeBranch(FILE)).thenReturn(createInput(mergeBranchIssues));
+ when(mergeFactory.createForTargetBranch(FILE)).thenReturn(createInput(targetBranchIssues));
Tracker<DefaultIssue, DefaultIssue> tracker = new Tracker<>();
underTest = new ShortBranchOrPullRequestTrackerExecution(baseFactory, rawFactory, mergeFactory, tracker, newLinesRepository);
@@ -95,6 +97,7 @@ public class ShortBranchOrPullRequestTrackerExecutionTest {
rawIssues.add(issue2);
when(mergeFactory.hasMergeBranchAnalysis()).thenReturn(false);
+ when(mergeFactory.hasTargetBranchAnalysis()).thenReturn(true);
when(newLinesRepository.getNewLines(FILE)).thenReturn(Optional.of(new HashSet<>(Arrays.asList(1, 3))));
Tracking<DefaultIssue, DefaultIssue> tracking = underTest.track(FILE);
@@ -132,6 +135,7 @@ public class ShortBranchOrPullRequestTrackerExecutionTest {
rawIssues.add(issueWithALocationOnADifferentFile);
when(mergeFactory.hasMergeBranchAnalysis()).thenReturn(false);
+ when(mergeFactory.hasTargetBranchAnalysis()).thenReturn(false);
when(newLinesRepository.getNewLines(FILE)).thenReturn(Optional.of(new HashSet<>(Arrays.asList(7, 10))));
Tracking<DefaultIssue, DefaultIssue> tracking = underTest.track(FILE);
@@ -142,12 +146,14 @@ public class ShortBranchOrPullRequestTrackerExecutionTest {
}
@Test
- public void tracking_with_all_results() {
+ public void track_and_ignore_issues_from_merge_branch() {
rawIssues.add(createIssue(1, RuleTesting.XOO_X1));
rawIssues.add(createIssue(2, RuleTesting.XOO_X2));
rawIssues.add(createIssue(3, RuleTesting.XOO_X3));
when(mergeFactory.hasMergeBranchAnalysis()).thenReturn(true);
+ when(mergeFactory.hasTargetBranchAnalysis()).thenReturn(true);
+ when(mergeFactory.areTargetAndMergeBranchesDifferent()).thenReturn(true);
mergeBranchIssues.add(rawIssues.get(0));
baseIssues.add(rawIssues.get(0));
@@ -158,6 +164,42 @@ public class ShortBranchOrPullRequestTrackerExecutionTest {
assertThat(tracking.getUnmatchedRaws()).containsOnly(rawIssues.get(2));
}
+ @Test
+ public void track_and_ignore_issues_from_target_branch() {
+ rawIssues.add(createIssue(1, RuleTesting.XOO_X1));
+ rawIssues.add(createIssue(2, RuleTesting.XOO_X2));
+ rawIssues.add(createIssue(3, RuleTesting.XOO_X3));
+
+ when(mergeFactory.hasMergeBranchAnalysis()).thenReturn(true);
+ when(mergeFactory.hasTargetBranchAnalysis()).thenReturn(true);
+ when(mergeFactory.areTargetAndMergeBranchesDifferent()).thenReturn(true);
+ targetBranchIssues.add(rawIssues.get(0));
+
+ baseIssues.add(rawIssues.get(0));
+ baseIssues.add(rawIssues.get(1));
+
+ Tracking<DefaultIssue, DefaultIssue> tracking = underTest.track(FILE);
+ assertThat(tracking.getMatchedRaws()).isEqualTo(Collections.singletonMap(rawIssues.get(1), rawIssues.get(1)));
+ assertThat(tracking.getUnmatchedRaws()).containsOnly(rawIssues.get(2));
+ }
+
+ @Test
+ public void track_and_ignore_issues_from_merge_and_target_branch() {
+ rawIssues.add(createIssue(1, RuleTesting.XOO_X1));
+ rawIssues.add(createIssue(2, RuleTesting.XOO_X2));
+ rawIssues.add(createIssue(3, RuleTesting.XOO_X3));
+
+ when(mergeFactory.hasMergeBranchAnalysis()).thenReturn(true);
+ when(mergeFactory.hasTargetBranchAnalysis()).thenReturn(true);
+ when(mergeFactory.areTargetAndMergeBranchesDifferent()).thenReturn(true);
+ mergeBranchIssues.add(rawIssues.get(0));
+ targetBranchIssues.add(rawIssues.get(1));
+
+ Tracking<DefaultIssue, DefaultIssue> tracking = underTest.track(FILE);
+ assertThat(tracking.getMatchedRaws()).isEmpty();
+ assertThat(tracking.getUnmatchedRaws()).containsOnly(rawIssues.get(2));
+ }
+
private DefaultIssue createIssue(int line, RuleKey ruleKey) {
DefaultIssue issue = new DefaultIssue()
.setRuleKey(ruleKey)
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoaderTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoaderTest.java
index 159f82d34bf..e560a364301 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoaderTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoaderTest.java
@@ -33,7 +33,7 @@ import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
import org.sonar.ce.task.projectanalysis.analysis.Branch;
import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.MergeBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
import org.sonar.core.hash.SourceHashComputer;
import org.sonar.db.DbTester;
import org.sonar.db.protobuf.DbFileSources;
@@ -67,9 +67,9 @@ public class ScmInfoDbLoaderTest {
public BatchReportReaderRule reportReader = new BatchReportReaderRule();
private Branch branch = mock(Branch.class);
- private MergeBranchComponentUuids mergeBranchComponentUuids = mock(MergeBranchComponentUuids.class);
+ private MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids = mock(MergeAndTargetBranchComponentUuids.class);
- private ScmInfoDbLoader underTest = new ScmInfoDbLoader(analysisMetadataHolder, dbTester.getDbClient(), mergeBranchComponentUuids);
+ private ScmInfoDbLoader underTest = new ScmInfoDbLoader(analysisMetadataHolder, dbTester.getDbClient(), mergeAndTargetBranchComponentUuids);
@Test
public void returns_ScmInfo_from_DB() {
@@ -95,7 +95,7 @@ public class ScmInfoDbLoaderTest {
String hash = computeSourceHash(1);
when(branch.getMergeBranchUuid()).thenReturn("mergeBranchUuid");
- when(mergeBranchComponentUuids.getUuid(FILE.getDbKey())).thenReturn(mergeFileUuid);
+ when(mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(FILE.getDbKey())).thenReturn(mergeFileUuid);
addFileSourceInDb("henry", DATE_1, "rev-1", hash, mergeFileUuid);
DbScmInfo scmInfo = underTest.getScmInfo(FILE).get();
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
index 548a477c7d0..d31dfe56c1b 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
@@ -304,7 +304,8 @@ public class ProjectScanContainer extends ComponentContainer {
BranchConfiguration branchConfig = getComponentByType(BranchConfiguration.class);
if (branchConfig.branchType() == BranchType.PULL_REQUEST) {
- LOG.info("Pull request {} for merge into {} from {}", branchConfig.pullRequestKey(), pullRequestBaseToDisplayName(branchConfig.targetBranchName()), branchConfig.branchName());
+ LOG.info("Pull request {} for merge into {} from {}", branchConfig.pullRequestKey(), pullRequestBaseToDisplayName(branchConfig.targetBranchName()),
+ branchConfig.branchName());
} else if (branchConfig.branchName() != null) {
LOG.info("Branch name: {}, type: {}", branchConfig.branchName(), branchTypeToDisplayName(branchConfig.branchType()));
}