boolean isCrossProjectDuplicationEnabled();
/**
- * Branch being analyzed. Can be of any type: long or short, main or not.
+ * Branch being analyzed.
*
* @throws IllegalStateException if branch has not been set
*/
String getName();
/**
- * Indicates the first LLB branch from which it was forked.
+ * Indicates the UUID of the branch used as reference
*
* @throws IllegalStateException for main branches or legacy branches.
*/
- String getMergeBranchUuid();
+ String getReferenceBranchUuid();
/**
* Whether the cross-project duplication tracker can be enabled
private static boolean hasBranchProperties(ScannerReport.Metadata metadata) {
return !metadata.getBranchName().isEmpty()
|| !metadata.getPullRequestKey().isEmpty()
- || !metadata.getMergeBranchName().isEmpty()
+ || !metadata.getReferenceBranchName().isEmpty()
|| metadata.getBranchType() != UNSET;
}
// merge branch is only present if it's not a main branch and not an application
if (!branch.isMain() && !Qualifiers.APP.equals(componentDto.qualifier())) {
- dto.setMergeBranchUuid(branch.getMergeBranchUuid());
+ dto.setMergeBranchUuid(branch.getReferenceBranchUuid());
}
if (branch.getType() == BranchType.PULL_REQUEST) {
}
@Override
- public String getMergeBranchUuid() {
+ public String getReferenceBranchUuid() {
throw new IllegalStateException("Not valid for the main branch");
}
+++ /dev/null
-/*
- * 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 PRs, 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.isPullRequest()) {
- 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);
- }
-}
public ProjectViewAttributes(String projectUuid, String originalKey, @Nullable Long analysisDate, @Nullable String branchName) {
this.projectUuid = requireNonNull(projectUuid, "projectUuid can't be null");
- this.originalKey = requireNonNull(originalKey, "projectKey can't be null");;
+ this.originalKey = requireNonNull(originalKey, "projectKey can't be null");
this.analysisDate = analysisDate;
this.branchName = branchName;
}
--- /dev/null
+/*
+ * 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 reference branch
+ */
+public class ReferenceBranchComponentUuids {
+ private final AnalysisMetadataHolder analysisMetadataHolder;
+ private final DbClient dbClient;
+ private Map<String, String> referenceBranchComponentsUuidsByKey;
+ private String referenceBranchName;
+ private boolean hasReferenceBranchAnalysis;
+
+ public ReferenceBranchComponentUuids(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient) {
+ this.analysisMetadataHolder = analysisMetadataHolder;
+ this.dbClient = dbClient;
+ }
+
+ private void lazyInit() {
+ if (referenceBranchComponentsUuidsByKey == null) {
+ String referenceBranchUuid = analysisMetadataHolder.getBranch().getReferenceBranchUuid();
+
+ referenceBranchComponentsUuidsByKey = new HashMap<>();
+
+ try (DbSession dbSession = dbClient.openSession(false)) {
+
+ Optional<BranchDto> opt = dbClient.branchDao().selectByUuid(dbSession, referenceBranchUuid);
+ checkState(opt.isPresent(), "Reference branch '%s' does not exist", referenceBranchUuid);
+ referenceBranchName = opt.get().getKey();
+
+ init(referenceBranchUuid, dbSession);
+ }
+ }
+ }
+
+ private void init(String referenceBranchUuid, DbSession dbSession) {
+ hasReferenceBranchAnalysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, referenceBranchUuid).isPresent();
+
+ if (hasReferenceBranchAnalysis) {
+ List<ComponentDto> components = dbClient.componentDao().selectByProjectUuid(referenceBranchUuid, dbSession);
+ for (ComponentDto dto : components) {
+ referenceBranchComponentsUuidsByKey.put(dto.getKey(), dto.uuid());
+ }
+ }
+ }
+
+ public boolean hasReferenceBranchAnalysis() {
+ lazyInit();
+ return hasReferenceBranchAnalysis;
+ }
+
+ public String getReferenceBranchName() {
+ lazyInit();
+ return referenceBranchName;
+ }
+
+ @CheckForNull
+ public String getComponentUuid(String dbKey) {
+ lazyInit();
+ String cleanComponentKey = removeBranchAndPullRequestFromKey(dbKey);
+ return referenceBranchComponentsUuidsByKey.get(cleanComponentKey);
+ }
+}
String referenceBranchUuid;
if (metadataHolder.isPullRequest()) {
- referenceBranchUuid = metadataHolder.getBranch().getMergeBranchUuid();
+ referenceBranchUuid = metadataHolder.getBranch().getReferenceBranchUuid();
} else {
referenceBranchUuid = currentBranchUuid;
}
uuidsByKey = new HashMap<>();
try (DbSession dbSession = dbClient.openSession(false)) {
- // for the time being it still tries to load from short living branches
List<KeyWithUuidDto> components = dbClient.componentDao().selectAllSiblingComponentKeysHavingOpenIssues(dbSession, referenceBranchUuid, currentBranchUuid);
for (KeyWithUuidDto dto : components) {
uuidsByKey.computeIfAbsent(removeBranchAndPullRequestFromKey(dto.key()), s -> new HashSet<>()).add(dto.uuid());
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.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids;
import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.projectanalysis.component.SiblingComponentsWithOpenIssues;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderImpl;
import org.sonar.ce.task.projectanalysis.issue.SiblingsIssuesLoader;
import org.sonar.ce.task.projectanalysis.issue.TrackerBaseInputFactory;
import org.sonar.ce.task.projectanalysis.issue.TrackerExecution;
-import org.sonar.ce.task.projectanalysis.issue.TrackerMergeOrTargetBranchInputFactory;
+import org.sonar.ce.task.projectanalysis.issue.TrackerReferenceBranchInputFactory;
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;
MeasureComputersHolderImpl.class,
MutableTaskResultHolderImpl.class,
BatchReportReaderImpl.class,
- MergeAndTargetBranchComponentUuids.class,
+ ReferenceBranchComponentUuids.class,
SiblingComponentsWithOpenIssues.class,
// repositories
UpdateConflictResolver.class,
TrackerBaseInputFactory.class,
TrackerRawInputFactory.class,
- TrackerMergeOrTargetBranchInputFactory.class,
+ TrackerReferenceBranchInputFactory.class,
ClosedIssuesInputFactory.class,
Tracker.class,
TrackerExecution.class,
import java.util.stream.Stream;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit;
-import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids;
import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitorAdapter;
import org.sonar.ce.task.projectanalysis.util.cache.DiskCache;
import org.sonar.core.issue.DefaultIssue;
private final IssueVisitors issueVisitors;
private final IssueTrackingDelegator issueTracking;
private final SiblingsIssueMerger issueStatusCopier;
- private final MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids;
+ private final ReferenceBranchComponentUuids referenceBranchComponentUuids;
public IntegrateIssuesVisitor(IssueCache issueCache, IssueLifecycle issueLifecycle, IssueVisitors issueVisitors, IssueTrackingDelegator issueTracking,
- SiblingsIssueMerger issueStatusCopier, MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids) {
+ SiblingsIssueMerger issueStatusCopier, ReferenceBranchComponentUuids referenceBranchComponentUuids) {
super(CrawlerDepthLimit.FILE, POST_ORDER);
this.issueCache = issueCache;
this.issueLifecycle = issueLifecycle;
this.issueVisitors = issueVisitors;
this.issueTracking = issueTracking;
this.issueStatusCopier = issueStatusCopier;
- this.mergeAndTargetBranchComponentUuids = mergeAndTargetBranchComponentUuids;
+ this.referenceBranchComponentUuids = referenceBranchComponentUuids;
}
@Override
for (Map.Entry<DefaultIssue, DefaultIssue> entry : matched.entrySet()) {
DefaultIssue raw = entry.getKey();
DefaultIssue base = entry.getValue();
- issueLifecycle.copyExistingOpenIssueFromLongLivingBranch(raw, base, mergeAndTargetBranchComponentUuids.getMergeBranchName());
+ issueLifecycle.copyExistingOpenIssueFromBranch(raw, base, referenceBranchComponentUuids.getReferenceBranchName());
process(component, raw, cacheAppender);
}
}
}
}
- public void copyExistingOpenIssueFromLongLivingBranch(DefaultIssue raw, DefaultIssue base, String fromLongBranchName) {
+ public void copyExistingOpenIssueFromBranch(DefaultIssue raw, DefaultIssue base, String branchName) {
raw.setKey(Uuids.create());
raw.setNew(false);
- copyAttributesOfIssueFromOtherBranch(raw, base);
- raw.setFieldChange(changeContext, IssueFieldsSetter.FROM_LONG_BRANCH, fromLongBranchName, analysisMetadataHolder.getBranch().getName());
+ copyAttributesOfIssueFromAnotherBranch(raw, base);
+ raw.setFieldChange(changeContext, IssueFieldsSetter.FROM_BRANCH, branchName, analysisMetadataHolder.getBranch().getName());
}
- public void mergeConfirmedOrResolvedFromShortLivingBranchOrPr(DefaultIssue raw, DefaultIssue base, KeyType branchType, String fromShortBranchNameOrPR) {
- copyAttributesOfIssueFromOtherBranch(raw, base);
- String from = (branchType == KeyType.PULL_REQUEST ? "#" : "") + fromShortBranchNameOrPR;
+ public void mergeConfirmedOrResolvedFromPr(DefaultIssue raw, DefaultIssue base, String pr) {
+ copyAttributesOfIssueFromAnotherBranch(raw, base);
+ String from = "#" + pr;
String to = analysisMetadataHolder.isPullRequest() ? ("#" + analysisMetadataHolder.getPullRequestKey()) : analysisMetadataHolder.getBranch().getName();
- raw.setFieldChange(changeContext, IssueFieldsSetter.FROM_SHORT_BRANCH, from, to);
+ raw.setFieldChange(changeContext, IssueFieldsSetter.FROM_BRANCH, from, to);
}
- private void copyAttributesOfIssueFromOtherBranch(DefaultIssue to, DefaultIssue from) {
+ private void copyAttributesOfIssueFromAnotherBranch(DefaultIssue to, DefaultIssue from) {
to.setCopied(true);
copyFields(to, from);
if (from.manualSeverity()) {
*/
package org.sonar.ce.task.projectanalysis.issue;
-import java.util.stream.Stream;
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.core.issue.DefaultIssue;
import org.sonar.core.issue.tracking.Tracking;
-import org.sonar.db.component.BranchType;
import static java.util.Collections.emptyMap;
+import static java.util.stream.Stream.empty;
public class IssueTrackingDelegator {
private final PullRequestTrackerExecution pullRequestTracker;
private final ReferenceBranchTrackerExecution referenceBranchTracker;
public IssueTrackingDelegator(PullRequestTrackerExecution pullRequestTracker, ReferenceBranchTrackerExecution referenceBranchTracker,
- TrackerExecution tracker, AnalysisMetadataHolder analysisMetadataHolder) {
+ TrackerExecution tracker, AnalysisMetadataHolder analysisMetadataHolder) {
this.pullRequestTracker = pullRequestTracker;
this.referenceBranchTracker = referenceBranchTracker;
this.tracker = tracker;
return standardResult(pullRequestTracker.track(component));
} else if (isFirstAnalysisSecondaryBranch()) {
Tracking<DefaultIssue, DefaultIssue> tracking = referenceBranchTracker.track(component);
- return new TrackingResult(tracking.getMatchedRaws(), emptyMap(), Stream.empty(), tracking.getUnmatchedRaws());
+ return new TrackingResult(tracking.getMatchedRaws(), emptyMap(), empty(), tracking.getUnmatchedRaws());
} else {
return standardResult(tracker.track(component));
}
}
/**
- * Special case where we want to do the issue tracking with the merge branch, and copy matched issue to the current branch.
+ * Special case where we want to do the issue tracking with the reference branch, and copy matched issue to the current branch.
*/
private boolean isFirstAnalysisSecondaryBranch() {
if (analysisMetadataHolder.isFirstAnalysis()) {
- Branch branch = analysisMetadataHolder.getBranch();
- return !branch.isMain();
+ return !analysisMetadataHolder.getBranch().isMain();
}
return false;
}
Input<DefaultIssue> rawInput = rawInputFactory.create(component);
Input<DefaultIssue> previousAnalysisInput = baseInputFactory.create(component);
- // Step 1: if there is no analysis or merge or target branch, keep only issues on changed lines
+ // Step 1: only keep issues on changed lines
List<DefaultIssue> filteredRaws = keepIssuesHavingAtLeastOneLocationOnChangedLines(component, rawInput.getIssues());
Input<DefaultIssue> unmatchedRawsAfterChangedLineFiltering = new DefaultTrackingInput(filteredRaws, rawInput.getLineHashSequence(), rawInput.getBlockHashSequence());
- // Step 2: track issues of previous analysis of the current PR
+ // Step 2: track issues with previous analysis of the current PR
return tracker.trackNonClosed(unmatchedRawsAfterChangedLineFiltering, previousAnalysisInput);
}
return Collections.emptyList();
}
final Set<Integer> newLines = newLinesOpt.get();
- return issues
- .stream()
+ return issues.stream()
.filter(i -> IssueLocations.allLinesFor(i, component.getUuid()).anyMatch(newLines::contains))
.collect(Collectors.toList());
}
public class ReferenceBranchTrackerExecution {
private final TrackerRawInputFactory rawInputFactory;
- private final TrackerMergeOrTargetBranchInputFactory mergeInputFactory;
+ private final TrackerReferenceBranchInputFactory referenceBranchInputFactory;
private final Tracker<DefaultIssue, DefaultIssue> tracker;
- public ReferenceBranchTrackerExecution(TrackerRawInputFactory rawInputFactory, TrackerMergeOrTargetBranchInputFactory mergeInputFactory,
+ public ReferenceBranchTrackerExecution(TrackerRawInputFactory rawInputFactory, TrackerReferenceBranchInputFactory referenceBranchInputFactory,
Tracker<DefaultIssue, DefaultIssue> tracker) {
this.rawInputFactory = rawInputFactory;
- this.mergeInputFactory = mergeInputFactory;
+ this.referenceBranchInputFactory = referenceBranchInputFactory;
this.tracker = tracker;
}
public Tracking<DefaultIssue, DefaultIssue> track(Component component) {
- return tracker.trackNonClosed(rawInputFactory.create(component), mergeInputFactory.createForMergeBranch(component));
+ return tracker.trackNonClosed(rawInputFactory.create(component), referenceBranchInputFactory.create(component));
}
}
import javax.annotation.concurrent.Immutable;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.issue.tracking.Trackable;
-import org.sonar.db.component.KeyType;
@Immutable
public class SiblingIssue implements Trackable {
private final String lineHash;
private final RuleKey ruleKey;
private final String status;
- private final String branchKey;
- private final KeyType branchType;
+ private final String prKey;
private final Date updateDate;
- public SiblingIssue(String key, @Nullable Integer line, String message, @Nullable String lineHash, RuleKey ruleKey, String status, String branchKey, KeyType branchType,
- Date updateDate) {
+ SiblingIssue(String key, @Nullable Integer line, @Nullable String message, @Nullable String lineHash, RuleKey ruleKey, String status, String prKey, Date updateDate) {
this.key = key;
this.line = line;
this.message = message;
this.lineHash = lineHash;
this.ruleKey = ruleKey;
this.status = status;
- this.branchKey = branchKey;
- this.branchType = branchType;
+ this.prKey = prKey;
this.updateDate = updateDate;
}
return line;
}
+ @CheckForNull
@Override
public String getMessage() {
return message;
return status;
}
- public String getBranchKey() {
- return branchKey;
- }
-
- public KeyType getBranchType() {
- return branchType;
+ public String getPrKey() {
+ return prKey;
}
@Override
}
/**
- * Look for all unclosed issues in branches/PR targeting the same long living branch, and run
+ * Look for all unclosed issues in PR targeting the same branch, and run
* a light issue tracking to find matches. Then merge issue attributes in the new issues.
*/
public void tryMerge(Component component, Collection<DefaultIssue> newIssues) {
for (Map.Entry<DefaultIssue, SiblingIssue> e : matchedRaws.entrySet()) {
SiblingIssue issue = e.getValue();
- issueLifecycle.mergeConfirmedOrResolvedFromShortLivingBranchOrPr(e.getKey(), defaultIssues.get(issue), issue.getBranchType(), issue.getBranchKey());
+ issueLifecycle.mergeConfirmedOrResolvedFromPr(e.getKey(), defaultIssues.get(issue), issue.getPrKey());
}
}
}
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
+import org.sonar.api.utils.Preconditions;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.SiblingComponentsWithOpenIssues;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.KeyType;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.issue.PrIssueDto;
private final ComponentIssuesLoader componentIssuesLoader;
public SiblingsIssuesLoader(SiblingComponentsWithOpenIssues siblingComponentsWithOpenIssues, DbClient dbClient,
- ComponentIssuesLoader componentIssuesLoader) {
+ ComponentIssuesLoader componentIssuesLoader) {
this.siblingComponentsWithOpenIssues = siblingComponentsWithOpenIssues;
this.dbClient = dbClient;
this.componentIssuesLoader = componentIssuesLoader;
}
private static SiblingIssue toSiblingIssue(PrIssueDto dto) {
- return new SiblingIssue(dto.getKey(), dto.getLine(), dto.getMessage(), dto.getChecksum(), dto.getRuleKey(), dto.getStatus(), dto.getBranchKey(), dto.getKeyType(),
+ Preconditions.checkState(dto.getKeyType().equals(KeyType.PULL_REQUEST), "Expected all issues to belong to P/Rs");
+ return new SiblingIssue(dto.getKey(), dto.getLine(), dto.getMessage(), dto.getChecksum(), dto.getRuleKey(), dto.getStatus(), dto.getBranchKey(),
longToDate(dto.getIssueUpdateDate()));
}
+++ /dev/null
-/*
- * 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.issue;
-
-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.MergeAndTargetBranchComponentUuids;
-import org.sonar.core.issue.DefaultIssue;
-import org.sonar.core.issue.tracking.Input;
-import org.sonar.core.issue.tracking.LazyInput;
-import org.sonar.core.issue.tracking.LineHashSequence;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-
-public class TrackerMergeOrTargetBranchInputFactory {
- private static final LineHashSequence EMPTY_LINE_HASH_SEQUENCE = new LineHashSequence(Collections.emptyList());
-
- private final ComponentIssuesLoader componentIssuesLoader;
- private final DbClient dbClient;
- private final MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids;
-
- 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 mergeAndTargetBranchComponentUuids.hasMergeBranchAnalysis();
- }
-
- public boolean hasTargetBranchAnalysis() {
- return mergeAndTargetBranchComponentUuids.hasTargetBranchAnalysis();
- }
-
- 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 mergeOrTargetBranchComponentUuid;
-
- private MergeOrTargetLazyInput(Component.Type type, @Nullable String mergeOrTargetBranchComponentUuid) {
- this.type = type;
- this.mergeOrTargetBranchComponentUuid = mergeOrTargetBranchComponentUuid;
- }
-
- @Override
- protected LineHashSequence loadLineHashSequence() {
- 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, mergeOrTargetBranchComponentUuid);
- if (hashes == null || hashes.isEmpty()) {
- return EMPTY_LINE_HASH_SEQUENCE;
- }
- return new LineHashSequence(hashes);
- }
- }
-
- @Override
- protected List<DefaultIssue> loadIssues() {
- if (mergeOrTargetBranchComponentUuid == null) {
- return Collections.emptyList();
- }
- return componentIssuesLoader.loadOpenIssuesWithChanges(mergeOrTargetBranchComponentUuid);
- }
- }
-
-}
private Optional<DbIssues.Location> convertLocation(ScannerReport.IssueLocation source) {
DbIssues.Location.Builder target = DbIssues.Location.newBuilder();
if (source.getComponentRef() != 0 && source.getComponentRef() != component.getReportAttributes().getRef()) {
- // SONAR-10781 Component might not exist because on short living branch and PR, only changed components are included in the report
+ // SONAR-10781 Component might not exist because on PR, only changed components are included in the report
Optional<Component> optionalComponent = treeRootHolder.getOptionalComponentByRef(source.getComponentRef());
if (!optionalComponent.isPresent()) {
return Optional.empty();
--- /dev/null
+/*
+ * 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.issue;
+
+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.ReferenceBranchComponentUuids;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.tracking.Input;
+import org.sonar.core.issue.tracking.LazyInput;
+import org.sonar.core.issue.tracking.LineHashSequence;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+
+public class TrackerReferenceBranchInputFactory {
+ private static final LineHashSequence EMPTY_LINE_HASH_SEQUENCE = new LineHashSequence(Collections.emptyList());
+
+ private final ComponentIssuesLoader componentIssuesLoader;
+ private final DbClient dbClient;
+ private final ReferenceBranchComponentUuids referenceBranchComponentUuids;
+
+ public TrackerReferenceBranchInputFactory(ComponentIssuesLoader componentIssuesLoader, ReferenceBranchComponentUuids referenceBranchComponentUuids, DbClient dbClient) {
+ this.componentIssuesLoader = componentIssuesLoader;
+ this.referenceBranchComponentUuids = referenceBranchComponentUuids;
+ this.dbClient = dbClient;
+ // TODO detect file moves?
+ }
+
+ public Input<DefaultIssue> create(Component component) {
+ String referenceBranchComponentUuid = referenceBranchComponentUuids.getComponentUuid(component.getDbKey());
+ return new ReferenceLazyInput(component.getType(), referenceBranchComponentUuid);
+ }
+
+ private class ReferenceLazyInput extends LazyInput<DefaultIssue> {
+ private final Component.Type type;
+ private final String referenceBranchComponentUuid;
+
+ private ReferenceLazyInput(Component.Type type, @Nullable String referenceBranchComponentUuid) {
+ this.type = type;
+ this.referenceBranchComponentUuid = referenceBranchComponentUuid;
+ }
+
+ @Override
+ protected LineHashSequence loadLineHashSequence() {
+ if (referenceBranchComponentUuid == null || type != Component.Type.FILE) {
+ return EMPTY_LINE_HASH_SEQUENCE;
+ }
+
+ try (DbSession session = dbClient.openSession(false)) {
+ List<String> hashes = dbClient.fileSourceDao().selectLineHashes(session, referenceBranchComponentUuid);
+ if (hashes == null || hashes.isEmpty()) {
+ return EMPTY_LINE_HASH_SEQUENCE;
+ }
+ return new LineHashSequence(hashes);
+ }
+ }
+
+ @Override
+ protected List<DefaultIssue> loadIssues() {
+ if (referenceBranchComponentUuid == null) {
+ return Collections.emptyList();
+ }
+ return componentIssuesLoader.loadOpenIssuesWithChanges(referenceBranchComponentUuid);
+ }
+ }
+
+}
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.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.source.FileSourceDto;
private final AnalysisMetadataHolder analysisMetadataHolder;
private final DbClient dbClient;
- private final MergeAndTargetBranchComponentUuids mergeBranchComponentUuid;
+ private final ReferenceBranchComponentUuids referenceBranchComponentUuid;
- public ScmInfoDbLoader(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient, MergeAndTargetBranchComponentUuids mergeBranchComponentUuid) {
+ public ScmInfoDbLoader(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient, ReferenceBranchComponentUuids referenceBranchComponentUuid) {
this.analysisMetadataHolder = analysisMetadataHolder;
this.dbClient = dbClient;
- this.mergeBranchComponentUuid = mergeBranchComponentUuid;
+ this.referenceBranchComponentUuid = referenceBranchComponentUuid;
}
public Optional<DbScmInfo> getScmInfo(Component file) {
// at this point, it's the first analysis of a branch with copyFromPrevious flag true or any analysis of a PR
Branch branch = analysisMetadataHolder.getBranch();
if (!branch.isMain()) {
- String uuid = mergeBranchComponentUuid.getTargetBranchComponentUuid(file.getDbKey());
- if (uuid == null) {
- uuid = mergeBranchComponentUuid.getMergeBranchComponentUuid(file.getDbKey());
- }
- return Optional.ofNullable(uuid);
+ return Optional.ofNullable(referenceBranchComponentUuid.getComponentUuid(file.getDbKey()));
}
return Optional.empty();
import java.util.List;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.source.FileSourceDao;
private final DbClient dbClient;
private final FileSourceDao fileSourceDao;
private final SourceLinesHashRepository sourceLinesHash;
- private final MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids;
+ private final ReferenceBranchComponentUuids referenceBranchComponentUuids;
private final AnalysisMetadataHolder analysisMetadataHolder;
public SourceLinesDiffImpl(DbClient dbClient, FileSourceDao fileSourceDao, SourceLinesHashRepository sourceLinesHash,
- MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids, AnalysisMetadataHolder analysisMetadataHolder) {
+ ReferenceBranchComponentUuids referenceBranchComponentUuids, AnalysisMetadataHolder analysisMetadataHolder) {
this.dbClient = dbClient;
this.fileSourceDao = fileSourceDao;
this.sourceLinesHash = sourceLinesHash;
- this.mergeAndTargetBranchComponentUuids = mergeAndTargetBranchComponentUuids;
+ this.referenceBranchComponentUuids = referenceBranchComponentUuids;
this.analysisMetadataHolder = analysisMetadataHolder;
}
try (DbSession dbSession = dbClient.openSession(false)) {
String uuid;
if (analysisMetadataHolder.isPullRequest()) {
- uuid = mergeAndTargetBranchComponentUuids.getTargetBranchComponentUuid(component.getDbKey());
- if (uuid == null) {
- uuid = mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(component.getDbKey());
- }
+ uuid = referenceBranchComponentUuids.getComponentUuid(component.getDbKey());
} else {
uuid = component.getUuid();
}
if (!analysisMetadataHolder.isPullRequest()) {
return;
}
- String mergeBranchUuid = analysisMetadataHolder.getBranch().getMergeBranchUuid();
- int moduleCount = dbClient.componentDao().countEnabledModulesByProjectUuid(session, mergeBranchUuid);
+ String referenceBranchUuid = analysisMetadataHolder.getBranch().getReferenceBranchUuid();
+ int moduleCount = dbClient.componentDao().countEnabledModulesByProjectUuid(session, referenceBranchUuid);
if (moduleCount > 0) {
- Optional<BranchDto> opt = dbClient.branchDao().selectByUuid(session, mergeBranchUuid);
- checkState(opt.isPresent(), "Merge branch '%s' does not exist", mergeBranchUuid);
+ Optional<BranchDto> opt = dbClient.branchDao().selectByUuid(session, referenceBranchUuid);
+ checkState(opt.isPresent(), "Reference branch '%s' does not exist", referenceBranchUuid);
throw MessageException.of(String.format(
"Due to an upgrade, you need first to re-analyze the target branch '%s' before analyzing this pull request.", opt.get().getKey()));
}
}
@Override
- public String getMergeBranchUuid() {
+ public String getReferenceBranchUuid() {
throw new UnsupportedOperationException();
}
when(branch.getType()).thenReturn(type);
when(branch.getName()).thenReturn(name);
when(branch.isMain()).thenReturn(isMain);
- when(branch.getMergeBranchUuid()).thenReturn(mergeBranchUuid);
+ when(branch.getReferenceBranchUuid()).thenReturn(mergeBranchUuid);
when(branch.getTargetBranchName()).thenReturn(mergeBranchUuid);
return branch;
}
+++ /dev/null
-/*
- * 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 branch1;
- private ComponentDto branch1File;
- private ComponentDto pr1File;
- private ComponentDto pr2File;
- private Project project;
- private ComponentDto pr1;
- private ComponentDto pr2;
- private ComponentDto branch2;
- private ComponentDto branch2File;
-
- @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());
- branch1 = db.components().insertProjectBranch(projectDto, b -> b.setKey("branch1"));
- branch2 = db.components().insertProjectBranch(projectDto, b -> b.setKey("branch2"));
- pr1 = db.components().insertProjectBranch(projectDto, b -> b.setKey("pr1").setBranchType(BranchType.PULL_REQUEST).setMergeBranchUuid(branch1.uuid()));
- pr2 = db.components().insertProjectBranch(projectDto, b -> b.setKey("pr2").setBranchType(BranchType.PULL_REQUEST).setMergeBranchUuid(branch1.uuid()));
- branch1File = ComponentTesting.newFileDto(branch1, null, "file").setUuid("branch1File");
- branch2File = ComponentTesting.newFileDto(branch2, null, "file").setUuid("branch2File");
- pr1File = ComponentTesting.newFileDto(pr1, null, "file").setUuid("file1");
- pr2File = ComponentTesting.newFileDto(pr2, null, "file").setUuid("file2");
- db.components().insertComponents(branch1File, pr1File, pr2File, branch2File);
- }
-
- @Test
- public void should_support_db_key_when_looking_for_merge_component() {
- when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid());
- when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
- when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
- db.components().insertSnapshot(newAnalysis(branch1));
- assertThat(underTest.getMergeBranchComponentUuid(pr1File.getDbKey())).isEqualTo(branch1File.uuid());
- assertThat(underTest.getTargetBranchComponentUuid(pr1File.getDbKey())).isNull();
- assertThat(underTest.hasMergeBranchAnalysis()).isTrue();
- assertThat(underTest.hasTargetBranchAnalysis()).isFalse();
- assertThat(underTest.areTargetAndMergeBranchesDifferent()).isTrue();
- assertThat(underTest.getMergeBranchName()).isEqualTo("branch1");
- }
-
- @Test
- public void should_support_db_key_when_looking_for_target_component() {
- when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid());
- when(branch.getTargetBranchName()).thenReturn("branch2");
- when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
- db.components().insertSnapshot(newAnalysis(branch1));
- db.components().insertSnapshot(newAnalysis(branch2));
- assertThat(underTest.getMergeBranchComponentUuid(pr1File.getDbKey())).isEqualTo(branch1File.uuid());
- assertThat(underTest.getTargetBranchComponentUuid(pr1File.getDbKey())).isEqualTo(branch2File.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(branch1.uuid());
- when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
- when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
- db.components().insertSnapshot(newAnalysis(branch1));
- assertThat(underTest.getMergeBranchComponentUuid(pr1File.getKey())).isEqualTo(branch1File.uuid());
- }
-
- @Test
- public void return_null_if_file_doesnt_exist() {
- when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid());
- when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
- when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
- db.components().insertSnapshot(newAnalysis(branch1));
- assertThat(underTest.getMergeBranchComponentUuid("doesnt exist")).isNull();
- }
-
- @Test
- public void skip_init_if_no_merge_branch_analysis() {
- when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid());
- when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
- when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
- assertThat(underTest.getMergeBranchComponentUuid(pr1File.getDbKey())).isNull();
- }
-
- @Test
- public void should_skip_target_components_init_on_branches() {
- when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid());
- when(branch.getType()).thenReturn(BranchType.BRANCH);
- when(branch.getTargetBranchName()).thenThrow(new IllegalStateException("Unsupported on branches"));
- db.components().insertSnapshot(newAnalysis(branch1));
-
- assertThat(underTest.getMergeBranchComponentUuid(branch2File.getDbKey())).isEqualTo(branch1File.uuid());
- assertThat(underTest.getTargetBranchComponentUuid(branch2File.getDbKey())).isNull();
- assertThat(underTest.hasMergeBranchAnalysis()).isTrue();
- assertThat(underTest.hasTargetBranchAnalysis()).isFalse();
- assertThat(underTest.areTargetAndMergeBranchesDifferent()).isTrue();
- assertThat(underTest.getMergeBranchName()).isEqualTo("branch1");
- }
-}
--- /dev/null
+/*
+ * 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 ReferenceBranchComponentUuidsTest {
+ @Rule
+ public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
+
+ @Rule
+ public DbTester db = DbTester.create();
+
+ private ReferenceBranchComponentUuids underTest;
+ private Branch branch = mock(Branch.class);
+
+ private ComponentDto branch1;
+ private ComponentDto branch1File;
+ private ComponentDto pr1File;
+ private ComponentDto pr2File;
+ private Project project;
+ private ComponentDto pr1;
+ private ComponentDto pr2;
+ private ComponentDto branch2;
+ private ComponentDto branch2File;
+
+ @Before
+ public void setUp() {
+ underTest = new ReferenceBranchComponentUuids(analysisMetadataHolder, db.getDbClient());
+ project = mock(Project.class);
+ analysisMetadataHolder.setProject(project);
+ analysisMetadataHolder.setBranch(branch);
+
+ ComponentDto projectDto = db.components().insertMainBranch();
+ when(project.getUuid()).thenReturn(projectDto.uuid());
+ branch1 = db.components().insertProjectBranch(projectDto, b -> b.setKey("branch1"));
+ branch2 = db.components().insertProjectBranch(projectDto, b -> b.setKey("branch2"));
+ pr1 = db.components().insertProjectBranch(projectDto, b -> b.setKey("pr1").setBranchType(BranchType.PULL_REQUEST).setMergeBranchUuid(branch1.uuid()));
+ pr2 = db.components().insertProjectBranch(projectDto, b -> b.setKey("pr2").setBranchType(BranchType.PULL_REQUEST).setMergeBranchUuid(branch1.uuid()));
+ branch1File = ComponentTesting.newFileDto(branch1, null, "file").setUuid("branch1File");
+ branch2File = ComponentTesting.newFileDto(branch2, null, "file").setUuid("branch2File");
+ pr1File = ComponentTesting.newFileDto(pr1, null, "file").setUuid("file1");
+ pr2File = ComponentTesting.newFileDto(pr2, null, "file").setUuid("file2");
+ db.components().insertComponents(branch1File, pr1File, pr2File, branch2File);
+ }
+
+ @Test
+ public void should_support_db_key_when_looking_for_reference_component() {
+ when(branch.getReferenceBranchUuid()).thenReturn(branch1.uuid());
+ when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
+ when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
+ db.components().insertSnapshot(newAnalysis(branch1));
+ assertThat(underTest.getComponentUuid(pr1File.getDbKey())).isEqualTo(branch1File.uuid());
+ assertThat(underTest.hasReferenceBranchAnalysis()).isTrue();
+ assertThat(underTest.getReferenceBranchName()).isEqualTo("branch1");
+ }
+
+ @Test
+ public void should_support_key_when_looking_for_reference_component() {
+ when(branch.getReferenceBranchUuid()).thenReturn(branch1.uuid());
+ when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
+ when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
+ db.components().insertSnapshot(newAnalysis(branch1));
+ assertThat(underTest.getComponentUuid(pr1File.getKey())).isEqualTo(branch1File.uuid());
+ }
+
+ @Test
+ public void return_null_if_file_doesnt_exist() {
+ when(branch.getReferenceBranchUuid()).thenReturn(branch1.uuid());
+ when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
+ when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
+ db.components().insertSnapshot(newAnalysis(branch1));
+ assertThat(underTest.getComponentUuid("doesnt exist")).isNull();
+ }
+
+ @Test
+ public void skip_init_if_no_reference_branch_analysis() {
+ when(branch.getReferenceBranchUuid()).thenReturn(branch1.uuid());
+ when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
+ when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch");
+ assertThat(underTest.getComponentUuid(pr1File.getDbKey())).isNull();
+ }
+}
import javax.annotation.Nullable;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
private SiblingComponentsWithOpenIssues underTest;
- private ComponentDto long1;
- private ComponentDto fileWithNoIssuesOnLong1;
- private ComponentDto fileWithOneOpenIssueOnLong1Short1;
- private ComponentDto fileWithOneResolvedIssueOnLong1Short1;
- private ComponentDto fileWithOneOpenTwoResolvedIssuesOnLong1Short1;
- private ComponentDto fileXWithOneResolvedIssueOnLong1Short1;
- private ComponentDto fileXWithOneResolvedIssueOnLong1Short2;
+ private ComponentDto branch1;
+ private ComponentDto fileWithNoIssuesOnBranch1;
+ private ComponentDto fileWithOneOpenIssueOnBranch1Pr1;
+ private ComponentDto fileWithOneResolvedIssueOnBranch1Pr1;
+ private ComponentDto fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1;
+ private ComponentDto fileXWithOneResolvedIssueOnBranch1Pr1;
+ private ComponentDto fileXWithOneResolvedIssueOnBranch1Pr2;
- private ComponentDto long2;
- private ComponentDto fileWithOneOpenIssueOnLong2Short1;
- private ComponentDto fileWithOneResolvedIssueOnLong2Short1;
- private ComponentDto long1short1;
+ private ComponentDto branch2;
+ private ComponentDto fileWithOneOpenIssueOnBranch2Pr1;
+ private ComponentDto fileWithOneResolvedIssueOnBranch2Pr1;
+ private ComponentDto branch1pr1;
@Before
public void setUp() {
ComponentDto project = db.components().insertMainBranch();
- long1 = db.components().insertProjectBranch(project, b -> b.setKey("long1"), b -> b.setBranchType(BranchType.BRANCH));
- long1short1 = db.components().insertProjectBranch(project,
- b -> b.setKey("long1short1"),
- b -> b.setBranchType(BranchType.SHORT),
- b -> b.setMergeBranchUuid(long1.uuid()));
- ComponentDto long1short2 = db.components().insertProjectBranch(project,
- b -> b.setKey("long1short2"),
- b -> b.setBranchType(BranchType.SHORT),
- b -> b.setMergeBranchUuid(long1.uuid()));
+ branch1 = db.components().insertProjectBranch(project, b -> b.setKey("branch1"), b -> b.setBranchType(BranchType.BRANCH));
+ branch1pr1 = db.components().insertProjectBranch(project,
+ b -> b.setKey("branch1pr1"),
+ b -> b.setBranchType(BranchType.PULL_REQUEST),
+ b -> b.setMergeBranchUuid(branch1.uuid()));
+ ComponentDto branch1pr2 = db.components().insertProjectBranch(project,
+ b -> b.setKey("branch1pr2"),
+ b -> b.setBranchType(BranchType.PULL_REQUEST),
+ b -> b.setMergeBranchUuid(branch1.uuid()));
- fileWithNoIssuesOnLong1 = db.components().insertComponent(ComponentTesting.newFileDto(long1, null));
+ fileWithNoIssuesOnBranch1 = db.components().insertComponent(ComponentTesting.newFileDto(branch1, null));
RuleDefinitionDto rule = db.rules().insert();
- fileWithOneOpenIssueOnLong1Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long1short1, null));
- db.issues().insertIssue(IssueTesting.newIssue(rule, long1short1, fileWithOneOpenIssueOnLong1Short1));
+ fileWithOneOpenIssueOnBranch1Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch1pr1, null));
+ db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr1, fileWithOneOpenIssueOnBranch1Pr1));
- fileWithOneResolvedIssueOnLong1Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long1short1, null));
- db.issues().insertIssue(IssueTesting.newIssue(rule, long1short1, fileWithOneResolvedIssueOnLong1Short1).setStatus("RESOLVED"));
+ fileWithOneResolvedIssueOnBranch1Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch1pr1, null));
+ db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr1, fileWithOneResolvedIssueOnBranch1Pr1).setStatus("RESOLVED"));
- fileWithOneOpenTwoResolvedIssuesOnLong1Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long1short1, null));
- db.issues().insertIssue(IssueTesting.newIssue(rule, long1short1, fileWithOneOpenTwoResolvedIssuesOnLong1Short1));
- db.issues().insertIssue(IssueTesting.newIssue(rule, long1short1, fileWithOneOpenTwoResolvedIssuesOnLong1Short1).setStatus("RESOLVED"));
+ fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch1pr1, null));
+ db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr1, fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1));
+ db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr1, fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1).setStatus("RESOLVED"));
String fileKey = "file-x";
- fileXWithOneResolvedIssueOnLong1Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long1short1, null)
- .setDbKey(fileKey + ":BRANCH:long1short1"));
- db.issues().insertIssue(IssueTesting.newIssue(rule, long1short1, fileXWithOneResolvedIssueOnLong1Short1).setStatus("RESOLVED"));
- fileXWithOneResolvedIssueOnLong1Short2 = db.components().insertComponent(ComponentTesting.newFileDto(long1short2, null)
- .setDbKey(fileKey + ":BRANCH:long1short2"));
- db.issues().insertIssue(IssueTesting.newIssue(rule, long1short2, fileXWithOneResolvedIssueOnLong1Short2).setStatus("RESOLVED"));
-
- long2 = db.components().insertProjectBranch(project, b -> b.setKey("long2"), b -> b.setBranchType(BranchType.BRANCH));
- ComponentDto long2short1 = db.components().insertProjectBranch(project,
- b -> b.setKey("long2short1"),
- b -> b.setBranchType(BranchType.SHORT),
- b -> b.setMergeBranchUuid(long2.uuid()));
-
- fileWithOneOpenIssueOnLong2Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long2short1, null));
- db.issues().insertIssue(IssueTesting.newIssue(rule, long2short1, fileWithOneOpenIssueOnLong2Short1));
-
- fileWithOneResolvedIssueOnLong2Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long2short1, null));
- db.issues().insertIssue(IssueTesting.newIssue(rule, long2short1, fileWithOneResolvedIssueOnLong2Short1).setStatus("RESOLVED"));
-
- setRoot(long1);
+ fileXWithOneResolvedIssueOnBranch1Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch1pr1, null)
+ .setDbKey(fileKey + ":BRANCH:branch1pr1"));
+ db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr1, fileXWithOneResolvedIssueOnBranch1Pr1).setStatus("RESOLVED"));
+ fileXWithOneResolvedIssueOnBranch1Pr2 = db.components().insertComponent(ComponentTesting.newFileDto(branch1pr2, null)
+ .setDbKey(fileKey + ":BRANCH:branch1pr2"));
+ db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr2, fileXWithOneResolvedIssueOnBranch1Pr2).setStatus("RESOLVED"));
+
+ branch2 = db.components().insertProjectBranch(project, b -> b.setKey("branch2"), b -> b.setBranchType(BranchType.BRANCH));
+ ComponentDto branch2pr1 = db.components().insertProjectBranch(project,
+ b -> b.setKey("branch2pr1"),
+ b -> b.setBranchType(BranchType.PULL_REQUEST),
+ b -> b.setMergeBranchUuid(branch2.uuid()));
+
+ fileWithOneOpenIssueOnBranch2Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch2pr1, null));
+ db.issues().insertIssue(IssueTesting.newIssue(rule, branch2pr1, fileWithOneOpenIssueOnBranch2Pr1));
+
+ fileWithOneResolvedIssueOnBranch2Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch2pr1, null));
+ db.issues().insertIssue(IssueTesting.newIssue(rule, branch2pr1, fileWithOneResolvedIssueOnBranch2Pr1).setStatus("RESOLVED"));
+
+ setRoot(branch1);
underTest = new SiblingComponentsWithOpenIssues(treeRootHolder, metadataHolder, db.getDbClient());
}
@Test
- public void should_find_sibling_components_with_open_issues_for_long1() {
- setRoot(long1);
+ public void should_find_sibling_components_with_open_issues_for_branch1() {
+ setRoot(branch1);
setBranch(BranchType.BRANCH);
- assertThat(underTest.getUuids(fileWithNoIssuesOnLong1.getKey())).isEmpty();
- assertThat(underTest.getUuids(fileWithOneOpenIssueOnLong1Short1.getKey())).containsOnly(fileWithOneOpenIssueOnLong1Short1.uuid());
- assertThat(underTest.getUuids(fileWithOneResolvedIssueOnLong1Short1.getKey())).containsOnly(fileWithOneResolvedIssueOnLong1Short1.uuid());
- assertThat(underTest.getUuids(fileWithOneOpenTwoResolvedIssuesOnLong1Short1.getKey())).containsOnly(fileWithOneOpenTwoResolvedIssuesOnLong1Short1.uuid());
-
- assertThat(fileXWithOneResolvedIssueOnLong1Short1.getKey()).isEqualTo(fileXWithOneResolvedIssueOnLong1Short2.getKey());
- assertThat(underTest.getUuids(fileXWithOneResolvedIssueOnLong1Short1.getKey())).containsOnly(
- fileXWithOneResolvedIssueOnLong1Short1.uuid(),
- fileXWithOneResolvedIssueOnLong1Short2.uuid());
- }
+ assertThat(underTest.getUuids(fileWithNoIssuesOnBranch1.getKey())).isEmpty();
+ assertThat(underTest.getUuids(fileWithOneOpenIssueOnBranch1Pr1.getKey())).containsOnly(fileWithOneOpenIssueOnBranch1Pr1.uuid());
+ assertThat(underTest.getUuids(fileWithOneResolvedIssueOnBranch1Pr1.getKey())).containsOnly(fileWithOneResolvedIssueOnBranch1Pr1.uuid());
+ assertThat(underTest.getUuids(fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1.getKey())).containsOnly(fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1.uuid());
- @Test
- @Ignore
- public void should_find_sibling_components_with_open_issues_for_short1() {
- // TODO fix this test class
- setRoot(long1short1);
- setBranch(BranchType.SHORT, long1.uuid());
-
- assertThat(underTest.getUuids(fileWithNoIssuesOnLong1.getKey())).isEmpty();
- assertThat(underTest.getUuids(fileWithOneOpenIssueOnLong1Short1.getKey())).isEmpty();
- assertThat(underTest.getUuids(fileWithOneResolvedIssueOnLong1Short1.getKey())).isEmpty();
- assertThat(underTest.getUuids(fileWithOneOpenTwoResolvedIssuesOnLong1Short1.getKey())).isEmpty();
-
- assertThat(underTest.getUuids(fileXWithOneResolvedIssueOnLong1Short1.getKey())).containsOnly(
- fileXWithOneResolvedIssueOnLong1Short2.uuid());
+ assertThat(fileXWithOneResolvedIssueOnBranch1Pr1.getKey()).isEqualTo(fileXWithOneResolvedIssueOnBranch1Pr2.getKey());
+ assertThat(underTest.getUuids(fileXWithOneResolvedIssueOnBranch1Pr1.getKey())).containsOnly(
+ fileXWithOneResolvedIssueOnBranch1Pr1.uuid(),
+ fileXWithOneResolvedIssueOnBranch1Pr2.uuid());
}
@Test
- public void should_find_sibling_components_with_open_issues_for_long2() {
- setRoot(long2);
- setBranch(BranchType.BRANCH);
+ public void should_find_sibling_components_with_open_issues_for_pr1() {
+ setRoot(branch1pr1);
+ setBranch(BranchType.PULL_REQUEST, branch1.uuid());
- underTest = new SiblingComponentsWithOpenIssues(treeRootHolder, metadataHolder, db.getDbClient());
+ assertThat(underTest.getUuids(fileWithNoIssuesOnBranch1.getKey())).isEmpty();
+ assertThat(underTest.getUuids(fileWithOneOpenIssueOnBranch1Pr1.getKey())).isEmpty();
+ assertThat(underTest.getUuids(fileWithOneResolvedIssueOnBranch1Pr1.getKey())).isEmpty();
+ assertThat(underTest.getUuids(fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1.getKey())).isEmpty();
- assertThat(underTest.getUuids(fileWithOneResolvedIssueOnLong1Short1.getKey())).isEmpty();
- assertThat(underTest.getUuids(fileWithOneResolvedIssueOnLong2Short1.getKey())).containsOnly(fileWithOneResolvedIssueOnLong2Short1.uuid());
- assertThat(underTest.getUuids(fileWithOneOpenIssueOnLong2Short1.getKey())).containsOnly(fileWithOneOpenIssueOnLong2Short1.uuid());
+ assertThat(underTest.getUuids(fileXWithOneResolvedIssueOnBranch1Pr1.getKey())).containsOnly(
+ fileXWithOneResolvedIssueOnBranch1Pr2.uuid());
}
@Test
- public void should_find_sibling_components_with_open_issues_from_short() {
- ComponentDto project = db.components().insertMainBranch();
- setRoot(project);
+ public void should_find_sibling_components_with_open_issues_for_branch2() {
+ setRoot(branch2);
setBranch(BranchType.BRANCH);
- ComponentDto branch = db.components().insertProjectBranch(project,
- b -> b.setBranchType(BranchType.SHORT),
- b -> b.setMergeBranchUuid(project.uuid()));
-
- RuleDefinitionDto rule = db.rules().insert();
-
- ComponentDto fileWithResolvedIssueOnShort = db.components().insertComponent(ComponentTesting.newFileDto(branch, null));
- db.issues().insertIssue(IssueTesting.newIssue(rule, branch, fileWithResolvedIssueOnShort).setStatus("RESOLVED"));
-
underTest = new SiblingComponentsWithOpenIssues(treeRootHolder, metadataHolder, db.getDbClient());
- assertThat(underTest.getUuids(fileWithResolvedIssueOnShort.getKey())).hasSize(1);
+ assertThat(underTest.getUuids(fileWithOneResolvedIssueOnBranch1Pr1.getKey())).isEmpty();
+ assertThat(underTest.getUuids(fileWithOneResolvedIssueOnBranch2Pr1.getKey())).containsOnly(fileWithOneResolvedIssueOnBranch2Pr1.uuid());
+ assertThat(underTest.getUuids(fileWithOneOpenIssueOnBranch2Pr1.getKey())).containsOnly(fileWithOneOpenIssueOnBranch2Pr1.uuid());
}
@Test
}
@Test
- public void should_not_find_sibling_components_on_derived_long() {
+ public void should_not_find_sibling_components_on_derived_branch() {
ComponentDto project = db.components().insertMainBranch();
setRoot(project);
setBranch(BranchType.BRANCH);
- ComponentDto derivedLongBranch = db.components().insertProjectBranch(project,
+ ComponentDto derivedBranch = db.components().insertProjectBranch(project,
b -> b.setBranchType(BranchType.BRANCH),
b -> b.setMergeBranchUuid(project.uuid()));
RuleDefinitionDto rule = db.rules().insert();
- ComponentDto fileWithResolvedIssueOnDerivedLongBranch = db.components().insertComponent(ComponentTesting.newFileDto(derivedLongBranch, null));
- db.issues().insertIssue(IssueTesting.newIssue(rule, derivedLongBranch, fileWithResolvedIssueOnDerivedLongBranch).setStatus("RESOLVED"));
+ ComponentDto fileWithResolvedIssueOnDerivedBranch = db.components().insertComponent(ComponentTesting.newFileDto(derivedBranch, null));
+ db.issues().insertIssue(IssueTesting.newIssue(rule, derivedBranch, fileWithResolvedIssueOnDerivedBranch).setStatus("RESOLVED"));
underTest = new SiblingComponentsWithOpenIssues(treeRootHolder, metadataHolder, db.getDbClient());
- assertThat(underTest.getUuids(fileWithResolvedIssueOnDerivedLongBranch.getKey())).isEmpty();
+ assertThat(underTest.getUuids(fileWithResolvedIssueOnDerivedBranch.getKey())).isEmpty();
}
private void setRoot(ComponentDto componentDto) {
private void setBranch(BranchType currentBranchType, @Nullable String mergeBranchUuid) {
Branch branch = mock(Branch.class);
when(branch.getType()).thenReturn(currentBranchType);
- when(branch.getMergeBranchUuid()).thenReturn(mergeBranchUuid);
+ when(branch.getReferenceBranchUuid()).thenReturn(mergeBranchUuid);
metadataHolder.setBranch(branch);
}
}
package org.sonar.ce.task.projectanalysis.issue;
import com.google.common.base.Optional;
-import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Rule;
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.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids;
import org.sonar.ce.task.projectanalysis.component.ReportComponent;
import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
private MovedFilesRepository movedFilesRepository = mock(MovedFilesRepository.class);
private IssueLifecycle issueLifecycle = mock(IssueLifecycle.class);
private IssueVisitor issueVisitor = mock(IssueVisitor.class);
- private MergeAndTargetBranchComponentUuids mergeBranchComponentsUuids = mock(MergeAndTargetBranchComponentUuids.class);
+ private ReferenceBranchComponentUuids mergeBranchComponentsUuids = mock(ReferenceBranchComponentUuids.class);
private SiblingsIssueMerger issueStatusCopier = mock(SiblingsIssueMerger.class);
- private MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids = mock(MergeAndTargetBranchComponentUuids.class);
+ private ReferenceBranchComponentUuids referenceBranchComponentUuids = mock(ReferenceBranchComponentUuids.class);
private SourceLinesHashRepository sourceLinesHash = mock(SourceLinesHashRepository.class);
private NewLinesRepository newLinesRepository = mock(NewLinesRepository.class);
private ArgumentCaptor<DefaultIssue> defaultIssueCaptor;
- private ComponentIssuesLoader issuesLoader = new ComponentIssuesLoader(dbTester.getDbClient(), ruleRepositoryRule, activeRulesHolderRule, new MapSettings().asConfig(), System2.INSTANCE);
+ private ComponentIssuesLoader issuesLoader = new ComponentIssuesLoader(dbTester.getDbClient(), ruleRepositoryRule, activeRulesHolderRule, new MapSettings().asConfig(),
+ System2.INSTANCE);
private IssueTrackingDelegator trackingDelegator;
private TrackerExecution tracker;
- private PullRequestTrackerExecution shortBranchTracker;
+ private PullRequestTrackerExecution prBranchTracker;
private ReferenceBranchTrackerExecution mergeBranchTracker;
private ActiveRulesHolder activeRulesHolder = new AlwaysActiveRulesHolderImpl();
private IssueCache issueCache;
DbClient dbClient = dbTester.getDbClient();
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));
- TrackerMergeOrTargetBranchInputFactory mergeInputFactory = new TrackerMergeOrTargetBranchInputFactory(issuesLoader, mergeBranchComponentsUuids, dbClient);
+ TrackerBaseInputFactory baseInputFactory = new TrackerBaseInputFactory(issuesLoader, dbClient, movedFilesRepository, mock(ReportModulesPath.class), analysisMetadataHolder,
+ new IssueFieldsSetter(), mock(ComponentsWithUnprocessedIssues.class));
+ TrackerReferenceBranchInputFactory mergeInputFactory = new TrackerReferenceBranchInputFactory(issuesLoader, mergeBranchComponentsUuids, dbClient);
ClosedIssuesInputFactory closedIssuesInputFactory = new ClosedIssuesInputFactory(issuesLoader, dbClient, movedFilesRepository);
tracker = new TrackerExecution(baseInputFactory, rawInputFactory, closedIssuesInputFactory, new Tracker<>(), issuesLoader, analysisMetadataHolder);
- shortBranchTracker = new PullRequestTrackerExecution(baseInputFactory, rawInputFactory, new Tracker<>(), newLinesRepository);
+ prBranchTracker = new PullRequestTrackerExecution(baseInputFactory, rawInputFactory, new Tracker<>(), newLinesRepository);
mergeBranchTracker = new ReferenceBranchTrackerExecution(rawInputFactory, mergeInputFactory, new Tracker<>());
- trackingDelegator = new IssueTrackingDelegator(shortBranchTracker, mergeBranchTracker, tracker, analysisMetadataHolder);
+ trackingDelegator = new IssueTrackingDelegator(prBranchTracker, mergeBranchTracker, tracker, analysisMetadataHolder);
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, trackingDelegator, issueStatusCopier, mergeAndTargetBranchComponentUuids);
+ underTest = new IntegrateIssuesVisitor(issueCache, issueLifecycle, issueVisitors, trackingDelegator, issueStatusCopier, referenceBranchComponentUuids);
}
@Test
DefaultIssue capturedIssue = defaultIssueCaptor.getValue();
assertThat(capturedIssue.ruleKey().rule()).isEqualTo("S001");
- verify(issueStatusCopier).tryMerge(FILE, Collections.singletonList(capturedIssue));
+ verify(issueStatusCopier).tryMerge(FILE, singletonList(capturedIssue));
verify(issueLifecycle).doAutomaticTransition(capturedIssue);
}
@Test
- public void copy_issues_when_creating_new_long_living_branch() {
+ public void copy_issues_when_creating_new_non_main_branch() {
- when(mergeBranchComponentsUuids.getMergeBranchComponentUuid(FILE_KEY)).thenReturn(FILE_UUID_ON_BRANCH);
- when(mergeAndTargetBranchComponentUuids.getMergeBranchName()).thenReturn("master");
+ when(mergeBranchComponentsUuids.getComponentUuid(FILE_KEY)).thenReturn(FILE_UUID_ON_BRANCH);
+ when(referenceBranchComponentUuids.getReferenceBranchName()).thenReturn("master");
when(analysisMetadataHolder.isBranch()).thenReturn(true);
when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(true);
.setRuleKey(ruleKey.rule())
.setSeverity(Constants.Severity.BLOCKER)
.build();
- reportReader.putIssues(FILE_REF, asList(reportIssue));
+ reportReader.putIssues(FILE_REF, singletonList(reportIssue));
fileSourceRepository.addLine(FILE_REF, "line1");
underTest.visitAny(FILE);
ArgumentCaptor<DefaultIssue> rawIssueCaptor = ArgumentCaptor.forClass(DefaultIssue.class);
ArgumentCaptor<DefaultIssue> baseIssueCaptor = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueLifecycle).copyExistingOpenIssueFromLongLivingBranch(rawIssueCaptor.capture(), baseIssueCaptor.capture(), eq("master"));
+ verify(issueLifecycle).copyExistingOpenIssueFromBranch(rawIssueCaptor.capture(), baseIssueCaptor.capture(), eq("master"));
assertThat(rawIssueCaptor.getValue().severity()).isEqualTo(Severity.BLOCKER);
assertThat(baseIssueCaptor.getValue().severity()).isEqualTo(Severity.MAJOR);
import org.sonar.core.issue.DefaultIssueComment;
import org.sonar.core.issue.FieldDiffs;
import org.sonar.core.issue.IssueChangeContext;
-import org.sonar.db.component.BranchType;
-import org.sonar.db.component.KeyType;
import org.sonar.db.protobuf.DbCommons;
import org.sonar.db.protobuf.DbIssues;
import org.sonar.server.issue.IssueFieldsSetter;
import static org.sonar.db.rule.RuleTesting.XOO_X1;
public class IssueLifecycleTest {
-
private static final Date DEFAULT_DATE = new Date();
-
private static final Duration DEFAULT_DURATION = Duration.create(10);
- DumbRule rule = new DumbRule(XOO_X1);
+ private DumbRule rule = new DumbRule(XOO_X1);
- @org.junit.Rule
+ @Rule
public RuleRepositoryRule ruleRepository = new RuleRepositoryRule().add(rule);
-
@Rule
public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
private IssueChangeContext issueChangeContext = IssueChangeContext.createUser(DEFAULT_DATE, "default_user_uuid");
-
private IssueWorkflow workflow = mock(IssueWorkflow.class);
-
private IssueFieldsSetter updater = mock(IssueFieldsSetter.class);
-
private DebtCalculator debtCalculator = mock(DebtCalculator.class);
-
private IssueLifecycle underTest = new IssueLifecycle(analysisMetadataHolder, issueChangeContext, workflow, updater, debtCalculator, ruleRepository);
@Test
}
@Test
- public void mergeIssueFromShortLivingBranchIntoLLB() {
- DefaultIssue raw = new DefaultIssue()
- .setKey("raw");
- DefaultIssue fromShort = new DefaultIssue()
- .setKey("short");
- fromShort.setResolution("resolution");
- fromShort.setStatus("status");
-
- Date commentDate = new Date();
- fromShort.addComment(new DefaultIssueComment()
- .setIssueKey("short")
- .setCreatedAt(commentDate)
- .setUserUuid("user_uuid")
- .setMarkdownText("A comment"));
-
- Date diffDate = new Date();
- // file diff alone
- fromShort.addChange(new FieldDiffs()
- .setCreationDate(diffDate)
- .setIssueKey("short")
- .setUserUuid("user_uuid")
- .setDiff("file", "uuidA1", "uuidB1"));
- // file diff with another field
- fromShort.addChange(new FieldDiffs()
- .setCreationDate(diffDate)
- .setIssueKey("short")
- .setUserUuid("user_uuid")
- .setDiff("severity", "MINOR", "MAJOR")
- .setDiff("file", "uuidA2", "uuidB2"));
-
- Branch branch = mock(Branch.class);
- when(branch.getName()).thenReturn("master");
- analysisMetadataHolder.setBranch(branch);
-
- underTest.mergeConfirmedOrResolvedFromShortLivingBranchOrPr(raw, fromShort, KeyType.BRANCH, "feature/foo");
-
- assertThat(raw.resolution()).isEqualTo("resolution");
- assertThat(raw.status()).isEqualTo("status");
- assertThat(raw.defaultIssueComments())
- .extracting(DefaultIssueComment::issueKey, DefaultIssueComment::createdAt, DefaultIssueComment::userUuid, DefaultIssueComment::markdownText)
- .containsOnly(tuple("raw", commentDate, "user_uuid", "A comment"));
- assertThat(raw.changes()).hasSize(2);
- assertThat(raw.changes().get(0).creationDate()).isEqualTo(diffDate);
- assertThat(raw.changes().get(0).userUuid()).isEqualTo("user_uuid");
- assertThat(raw.changes().get(0).issueKey()).isEqualTo("raw");
- assertThat(raw.changes().get(0).diffs()).containsOnlyKeys("severity");
- assertThat(raw.changes().get(1).userUuid()).isEqualTo("default_user_uuid");
- assertThat(raw.changes().get(1).diffs()).containsOnlyKeys(IssueFieldsSetter.FROM_SHORT_BRANCH);
- assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).oldValue()).isEqualTo("feature/foo");
- assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).newValue()).isEqualTo("master");
- }
-
- @Test
- public void mergeIssueFromShortLivingBranchIntoPR() {
- DefaultIssue raw = new DefaultIssue()
- .setKey("raw");
- DefaultIssue fromShort = new DefaultIssue()
- .setKey("short");
- fromShort.setResolution("resolution");
- fromShort.setStatus("status");
-
- Date commentDate = new Date();
- fromShort.addComment(new DefaultIssueComment()
- .setIssueKey("short")
- .setCreatedAt(commentDate)
- .setUserUuid("user_uuid")
- .setMarkdownText("A comment"));
-
- Date diffDate = new Date();
- // file diff alone
- fromShort.addChange(new FieldDiffs()
- .setCreationDate(diffDate)
- .setIssueKey("short")
- .setUserUuid("user_uuid")
- .setDiff("file", "uuidA1", "uuidB1"));
- // file diff with another field
- fromShort.addChange(new FieldDiffs()
- .setCreationDate(diffDate)
- .setIssueKey("short")
- .setUserUuid("user_uuid")
- .setDiff("severity", "MINOR", "MAJOR")
- .setDiff("file", "uuidA2", "uuidB2"));
-
- Branch branch = mock(Branch.class);
- when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
- analysisMetadataHolder.setBranch(branch);
- analysisMetadataHolder.setPullRequestKey("3");
-
- underTest.mergeConfirmedOrResolvedFromShortLivingBranchOrPr(raw, fromShort, KeyType.BRANCH, "feature/foo");
-
- assertThat(raw.resolution()).isEqualTo("resolution");
- assertThat(raw.status()).isEqualTo("status");
- assertThat(raw.defaultIssueComments())
- .extracting(DefaultIssueComment::issueKey, DefaultIssueComment::createdAt, DefaultIssueComment::userUuid, DefaultIssueComment::markdownText)
- .containsOnly(tuple("raw", commentDate, "user_uuid", "A comment"));
- assertThat(raw.changes()).hasSize(2);
- assertThat(raw.changes().get(0).creationDate()).isEqualTo(diffDate);
- assertThat(raw.changes().get(0).userUuid()).isEqualTo("user_uuid");
- assertThat(raw.changes().get(0).issueKey()).isEqualTo("raw");
- assertThat(raw.changes().get(0).diffs()).containsOnlyKeys("severity");
- assertThat(raw.changes().get(1).userUuid()).isEqualTo("default_user_uuid");
- assertThat(raw.changes().get(1).diffs()).containsOnlyKeys(IssueFieldsSetter.FROM_SHORT_BRANCH);
- assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).oldValue()).isEqualTo("feature/foo");
- assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).newValue()).isEqualTo("#3");
- }
-
- @Test
- public void mergeIssueFromPRIntoLLB() {
+ public void mergeIssueFromPRIntoBranch() {
DefaultIssue raw = new DefaultIssue()
.setKey("raw");
DefaultIssue fromShort = new DefaultIssue()
when(branch.getName()).thenReturn("master");
analysisMetadataHolder.setBranch(branch);
- underTest.mergeConfirmedOrResolvedFromShortLivingBranchOrPr(raw, fromShort, KeyType.PULL_REQUEST, "1");
+ underTest.mergeConfirmedOrResolvedFromPr(raw, fromShort, "2");
assertThat(raw.resolution()).isEqualTo("resolution");
assertThat(raw.status()).isEqualTo("status");
assertThat(raw.changes().get(0).issueKey()).isEqualTo("raw");
assertThat(raw.changes().get(0).diffs()).containsOnlyKeys("severity");
assertThat(raw.changes().get(1).userUuid()).isEqualTo("default_user_uuid");
- assertThat(raw.changes().get(1).diffs()).containsOnlyKeys(IssueFieldsSetter.FROM_SHORT_BRANCH);
- assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).oldValue()).isEqualTo("#1");
- assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).newValue()).isEqualTo("master");
+ assertThat(raw.changes().get(1).diffs()).containsOnlyKeys(IssueFieldsSetter.FROM_BRANCH);
+ assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_BRANCH).oldValue()).isEqualTo("#2");
+ assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_BRANCH).newValue()).isEqualTo("master");
}
@Test
when(branch.getName()).thenReturn("release-2.x");
analysisMetadataHolder.setBranch(branch);
- underTest.copyExistingOpenIssueFromLongLivingBranch(raw, base, "master");
+ underTest.copyExistingOpenIssueFromBranch(raw, base, "master");
assertThat(raw.isNew()).isFalse();
assertThat(raw.isCopied()).isTrue();
assertThat(raw.effort()).isEqualTo(DEFAULT_DURATION);
assertThat(raw.isOnDisabledRule()).isTrue();
assertThat(raw.selectedAt()).isEqualTo(1000L);
- assertThat(raw.changes().get(0).get(IssueFieldsSetter.FROM_LONG_BRANCH).oldValue()).isEqualTo("master");
- assertThat(raw.changes().get(0).get(IssueFieldsSetter.FROM_LONG_BRANCH).newValue()).isEqualTo("release-2.x");
+ assertThat(raw.changes().get(0).get(IssueFieldsSetter.FROM_BRANCH).oldValue()).isEqualTo("master");
+ assertThat(raw.changes().get(0).get(IssueFieldsSetter.FROM_BRANCH).newValue()).isEqualTo("release-2.x");
verifyZeroInteractions(updater);
}
public class IssueTrackingDelegatorTest {
@Mock
- private PullRequestTrackerExecution shortBranchTracker;
+ private PullRequestTrackerExecution prBranchTracker;
@Mock
private ReferenceBranchTrackerExecution mergeBranchTracker;
@Mock
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- underTest = new IssueTrackingDelegator(shortBranchTracker, mergeBranchTracker, tracker, analysisMetadataHolder);
+ underTest = new IssueTrackingDelegator(prBranchTracker, mergeBranchTracker, tracker, analysisMetadataHolder);
when(tracker.track(component)).thenReturn(trackingResult);
when(mergeBranchTracker.track(component)).thenReturn(trackingResult);
- when(shortBranchTracker.track(component)).thenReturn(trackingResult);
+ when(prBranchTracker.track(component)).thenReturn(trackingResult);
}
@Test
underTest.track(component);
verify(tracker).track(component);
- verifyZeroInteractions(shortBranchTracker);
+ verifyZeroInteractions(prBranchTracker);
verifyZeroInteractions(mergeBranchTracker);
}
verify(mergeBranchTracker).track(component);
verifyZeroInteractions(tracker);
- verifyZeroInteractions(shortBranchTracker);
+ verifyZeroInteractions(prBranchTracker);
}
underTest.track(component);
- verify(shortBranchTracker).track(component);
+ verify(prBranchTracker).track(component);
verifyZeroInteractions(tracker);
verifyZeroInteractions(mergeBranchTracker);
}
@Mock
private TrackerRawInputFactory rawInputFactory;
@Mock
- private TrackerMergeOrTargetBranchInputFactory mergeInputFactory;
+ private TrackerReferenceBranchInputFactory mergeInputFactory;
@Mock
private Tracker<DefaultIssue, DefaultIssue> tracker;
@Mock
Input<DefaultIssue> mergeInput = mock(Input.class);
NonClosedTracking<DefaultIssue, DefaultIssue> result = mock(NonClosedTracking.class);
when(rawInputFactory.create(component)).thenReturn(rawInput);
- when(mergeInputFactory.createForMergeBranch(component)).thenReturn(mergeInput);
+ when(mergeInputFactory.create(component)).thenReturn(mergeInput);
when(tracker.trackNonClosed(rawInput, mergeInput)).thenReturn(result);
assertThat(underTest.track(component)).isEqualTo(result);
import org.sonar.db.DbTester;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.KeyType;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.issue.IssueTesting;
import org.sonar.db.rule.RuleDefinitionDto;
issueLifecycle);
projectDto = db.components().insertMainBranch(p -> p.setDbKey(PROJECT_KEY).setUuid(PROJECT_UUID));
branch1Dto = db.components().insertProjectBranch(projectDto, b -> b.setKey("myBranch1")
- .setBranchType(BranchType.SHORT)
+ .setBranchType(BranchType.PULL_REQUEST)
.setMergeBranchUuid(projectDto.uuid()));
branch2Dto = db.components().insertProjectBranch(projectDto, b -> b.setKey("myBranch2")
- .setBranchType(BranchType.SHORT)
+ .setBranchType(BranchType.PULL_REQUEST)
.setMergeBranchUuid(projectDto.uuid()));
branch3Dto = db.components().insertProjectBranch(projectDto, b -> b.setKey("myBranch3")
- .setBranchType(BranchType.SHORT)
+ .setBranchType(BranchType.PULL_REQUEST)
.setMergeBranchUuid(projectDto.uuid()));
- fileOnBranch1Dto = db.components().insertComponent(newFileDto(branch1Dto).setDbKey(FILE_1_KEY + ":BRANCH:myBranch1"));
- fileOnBranch2Dto = db.components().insertComponent(newFileDto(branch2Dto).setDbKey(FILE_1_KEY + ":BRANCH:myBranch2"));
- fileOnBranch3Dto = db.components().insertComponent(newFileDto(branch3Dto).setDbKey(FILE_1_KEY + ":BRANCH:myBranch3"));
+ fileOnBranch1Dto = db.components().insertComponent(newFileDto(branch1Dto).setDbKey(FILE_1_KEY + ":PULL_REQUEST:myBranch1"));
+ fileOnBranch2Dto = db.components().insertComponent(newFileDto(branch2Dto).setDbKey(FILE_1_KEY + ":PULL_REQUEST:myBranch2"));
+ fileOnBranch3Dto = db.components().insertComponent(newFileDto(branch3Dto).setDbKey(FILE_1_KEY + ":PULL_REQUEST:myBranch3"));
rule = db.rules().insert();
- when(branch.getMergeBranchUuid()).thenReturn(projectDto.uuid());
+ when(branch.getReferenceBranchUuid()).thenReturn(projectDto.uuid());
metadataHolder.setBranch(branch);
}
copier.tryMerge(FILE_1, Collections.singleton(newIssue));
ArgumentCaptor<DefaultIssue> issueToMerge = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueLifecycle).mergeConfirmedOrResolvedFromShortLivingBranchOrPr(eq(newIssue), issueToMerge.capture(), eq(KeyType.BRANCH), eq("myBranch1"));
+ verify(issueLifecycle).mergeConfirmedOrResolvedFromPr(eq(newIssue), issueToMerge.capture(), eq("myBranch1"));
assertThat(issueToMerge.getValue().key()).isEqualTo("issue1");
}
copier.tryMerge(FILE_1, Collections.singleton(newIssue));
ArgumentCaptor<DefaultIssue> issueToMerge = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueLifecycle).mergeConfirmedOrResolvedFromShortLivingBranchOrPr(eq(newIssue), issueToMerge.capture(), eq(KeyType.BRANCH), eq("myBranch1"));
+ verify(issueLifecycle).mergeConfirmedOrResolvedFromPr(eq(newIssue), issueToMerge.capture(), eq("myBranch1"));
assertThat(issueToMerge.getValue().key()).isEqualTo("issue1");
}
copier.tryMerge(FILE_1, Collections.singleton(newIssue));
ArgumentCaptor<DefaultIssue> issueToMerge = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueLifecycle).mergeConfirmedOrResolvedFromShortLivingBranchOrPr(eq(newIssue), issueToMerge.capture(), eq(KeyType.BRANCH), eq("myBranch2"));
+ verify(issueLifecycle).mergeConfirmedOrResolvedFromPr(eq(newIssue), issueToMerge.capture(), eq("myBranch2"));
assertThat(issueToMerge.getValue().key()).isEqualTo("issue");
assertThat(issueToMerge.getValue().defaultIssueComments()).isNotEmpty();
--- /dev/null
+/*
+ * 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.issue;
+
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.ce.task.projectanalysis.component.Component;
+import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.tracking.Input;
+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 TrackerReferenceBranchInputFactoryTest {
+ private final static String COMPONENT_KEY = "file1";
+ private final static String COMPONENT_UUID = "uuid1";
+
+ @Rule
+ public DbTester db = DbTester.create();
+
+ private ComponentIssuesLoader componentIssuesLoader = mock(ComponentIssuesLoader.class);
+ private ReferenceBranchComponentUuids referenceBranchComponentUuids = mock(ReferenceBranchComponentUuids.class);
+ private TrackerReferenceBranchInputFactory underTest;
+
+ @Before
+ public void setUp() {
+ underTest = new TrackerReferenceBranchInputFactory(componentIssuesLoader, referenceBranchComponentUuids, db.getDbClient());
+ }
+
+ @Test
+ public void gets_issues_and_hashes_in_matching_component() {
+ DefaultIssue issue1 = new DefaultIssue();
+ when(referenceBranchComponentUuids.getComponentUuid(COMPONENT_KEY)).thenReturn(COMPONENT_UUID);
+ when(componentIssuesLoader.loadOpenIssuesWithChanges(COMPONENT_UUID)).thenReturn(Collections.singletonList(issue1));
+ ComponentDto fileDto = ComponentTesting.newFileDto(ComponentTesting.newPublicProjectDto(db.getDefaultOrganization())).setUuid(COMPONENT_UUID);
+ db.fileSources().insertFileSource(fileDto, 3);
+
+ Component component = mock(Component.class);
+ when(component.getDbKey()).thenReturn(COMPONENT_KEY);
+ when(component.getType()).thenReturn(Component.Type.FILE);
+ Input<DefaultIssue> input = underTest.create(component);
+
+ assertThat(input.getIssues()).containsOnly(issue1);
+ assertThat(input.getLineHashSequence().length()).isEqualTo(3);
+ }
+
+ @Test
+ public void gets_nothing_when_there_is_no_matching_component() {
+ Component component = mock(Component.class);
+ when(component.getDbKey()).thenReturn(COMPONENT_KEY);
+ when(component.getType()).thenReturn(Component.Type.FILE);
+ Input<DefaultIssue> input = underTest.create(component);
+
+ assertThat(input.getIssues()).isEmpty();
+ assertThat(input.getLineHashSequence().length()).isEqualTo(0);
+ }
+}
@Test
@UseDataProvider("noBranchNameBranches")
- public void newIssuesChangesNotification_creates_project_from_TreeRootHolder_and_branch_name_only_on_long_non_main_branches(Branch branch) {
+ public void newIssuesChangesNotification_creates_project_from_TreeRootHolder_and_branch_name_only_on_non_main_branches(Branch branch) {
RuleKey ruleKey = RuleKey.of("foo", "bar");
DefaultIssue issue = new DefaultIssue()
.setRuleKey(ruleKey)
ruleRepository.add(ruleKey);
treeRootHolder.setRoot(project);
analysisMetadata.setAnalysisDate(new Random().nextLong());
- analysisMetadata.setBranch(newBranch(BranchType.BRANCH, branchName));
+ analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, branchName));
IssuesChangesNotification expected = mock(IssuesChangesNotification.class);
when(issuesChangesSerializer.serialize(any(IssuesChangesNotificationBuilder.class))).thenReturn(expected);
ruleRepository.add(ruleKey);
treeRootHolder.setRoot(project);
analysisMetadata.setAnalysisDate(new Random().nextLong());
- analysisMetadata.setBranch(newBranch(BranchType.BRANCH, branchName));
+ analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, branchName));
IssuesChangesNotification expected = mock(IssuesChangesNotification.class);
when(issuesChangesSerializer.serialize(any(IssuesChangesNotificationBuilder.class))).thenReturn(expected);
ruleRepository.add(ruleKey);
treeRootHolder.setRoot(project);
analysisMetadata.setAnalysisDate(new Random().nextLong());
- analysisMetadata.setBranch(newBranch(BranchType.BRANCH, randomAlphabetic(12)));
+ analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, randomAlphabetic(12)));
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Can not find DTO for assignee uuid " + assigneeUuid);
ruleRepository.add(ruleKey);
treeRootHolder.setRoot(project);
analysisMetadata.setAnalysisDate(new Random().nextLong());
- analysisMetadata.setBranch(newBranch(BranchType.BRANCH, randomAlphabetic(12)));
+ analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, randomAlphabetic(12)));
IssuesChangesNotification expected = mock(IssuesChangesNotification.class);
when(issuesChangesSerializer.serialize(any(IssuesChangesNotificationBuilder.class))).thenReturn(expected);
ruleRepository.add(ruleKey);
treeRootHolder.setRoot(project);
analysisMetadata.setAnalysisDate(analysisDate);
- analysisMetadata.setBranch(newBranch(BranchType.BRANCH, randomAlphabetic(12)));
+ analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, randomAlphabetic(12)));
IssuesChangesNotification expected = mock(IssuesChangesNotification.class);
when(issuesChangesSerializer.serialize(any(IssuesChangesNotificationBuilder.class))).thenReturn(expected);
.forEach(ruleKey -> ruleRepository.add(ruleKey));
treeRootHolder.setRoot(project);
analysisMetadata.setAnalysisDate(analysisDate);
- analysisMetadata.setBranch(newBranch(BranchType.BRANCH, randomAlphabetic(12)));
+ analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, randomAlphabetic(12)));
IssuesChangesNotification expected = mock(IssuesChangesNotification.class);
when(issuesChangesSerializer.serialize(any(IssuesChangesNotificationBuilder.class))).thenReturn(expected);
return builderCaptor.getValue();
}
- private static Branch newBranch(BranchType branchType, String branchName) {
- Branch longBranch = mock(Branch.class);
- when(longBranch.isMain()).thenReturn(false);
- when(longBranch.getType()).thenReturn(branchType);
- when(longBranch.getName()).thenReturn(branchName);
- return longBranch;
+ private static Branch newNonMainBranch(BranchType branchType, String branchName) {
+ Branch nonMainBranch = mock(Branch.class);
+ when(nonMainBranch.isMain()).thenReturn(false);
+ when(nonMainBranch.getType()).thenReturn(branchType);
+ when(nonMainBranch.getName()).thenReturn(branchName);
+ return nonMainBranch;
}
private static Durations readDurationsField(NewIssuesNotification notification) {
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.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids;
import org.sonar.core.hash.SourceHashComputer;
import org.sonar.db.DbTester;
import org.sonar.db.component.BranchType;
public BatchReportReaderRule reportReader = new BatchReportReaderRule();
private Branch branch = mock(Branch.class);
- private MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids = mock(MergeAndTargetBranchComponentUuids.class);
+ private ReferenceBranchComponentUuids referenceBranchComponentUuids = mock(ReferenceBranchComponentUuids.class);
- private ScmInfoDbLoader underTest = new ScmInfoDbLoader(analysisMetadataHolder, dbTester.getDbClient(), mergeAndTargetBranchComponentUuids);
+ private ScmInfoDbLoader underTest = new ScmInfoDbLoader(analysisMetadataHolder, dbTester.getDbClient(), referenceBranchComponentUuids);
@Test
public void returns_ScmInfo_from_DB() {
}
@Test
- public void read_from_merge_branch_if_no_base() {
+ public void read_from_reference_branch_if_no_base() {
analysisMetadataHolder.setBaseAnalysis(null);
analysisMetadataHolder.setBranch(branch);
- String mergeFileUuid = "mergeFileUuid";
+ String referenceFileUuid = "referenceFileUuid";
String hash = computeSourceHash(1);
- when(mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(FILE.getDbKey())).thenReturn(mergeFileUuid);
- addFileSourceInDb("henry", DATE_1, "rev-1", hash, mergeFileUuid);
+ when(referenceBranchComponentUuids.getComponentUuid(FILE.getDbKey())).thenReturn(referenceFileUuid);
+ addFileSourceInDb("henry", DATE_1, "rev-1", hash, referenceFileUuid);
DbScmInfo scmInfo = underTest.getScmInfo(FILE).get();
assertThat(scmInfo.getAllChangesets()).hasSize(1);
assertThat(scmInfo.fileHash()).isEqualTo(hash);
- assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from DB for file 'mergeFileUuid'");
+ assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from DB for file 'referenceFileUuid'");
}
@Test
String targetBranchFileUuid = "targetBranchFileUuid";
String hash = computeSourceHash(1);
- when(mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(FILE.getDbKey())).thenReturn(targetBranchFileUuid);
+ when(referenceBranchComponentUuids.getComponentUuid(FILE.getDbKey())).thenReturn(targetBranchFileUuid);
addFileSourceInDb("henry", DATE_1, "rev-1", hash, targetBranchFileUuid);
DbScmInfo scmInfo = underTest.getScmInfo(FILE).get();
}
@Test
- public void do_not_read_from_db_on_first_analysis_if_there_is_no_merge_branch() {
+ public void do_not_read_from_db_on_first_analysis_if_there_is_no_reference_branch() {
Branch branch = mock(Branch.class);
when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
analysisMetadataHolder.setBaseAnalysis(null);
assertThat(logTester.logs(TRACE)).isEmpty();
}
- @Test
- public void do_not_read_from_db_on_pr_is_there_is_no_target_and_merge_branch() {
- analysisMetadataHolder.setBaseAnalysis(null);
- analysisMetadataHolder.setBranch(mock(Branch.class));
-
- assertThat(underTest.getScmInfo(FILE)).isEmpty();
- assertThat(logTester.logs(TRACE)).isEmpty();
-
- verify(mergeAndTargetBranchComponentUuids).getMergeBranchComponentUuid(FILE.getDbKey());
- verify(mergeAndTargetBranchComponentUuids).getTargetBranchComponentUuid(FILE.getDbKey());
- }
-
private static List<String> generateLines(int lineCount) {
ImmutableList.Builder<String> builder = ImmutableList.builder();
for (int i = 0; i < lineCount; i++) {
package org.sonar.ce.task.projectanalysis.source;
import java.util.Arrays;
-import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDao;
private FileSourceDao fileSourceDao = mock(FileSourceDao.class);
private SourceLinesHashRepository sourceLinesHash = mock(SourceLinesHashRepository.class);
private AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class);
- private MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids = mock(MergeAndTargetBranchComponentUuids.class);
+ private ReferenceBranchComponentUuids referenceBranchComponentUuids = mock(ReferenceBranchComponentUuids.class);
private SourceLinesDiffImpl underTest = new SourceLinesDiffImpl(dbClient, fileSourceDao, sourceLinesHash,
- mergeAndTargetBranchComponentUuids, analysisMetadataHolder);
+ referenceBranchComponentUuids, analysisMetadataHolder);
private static final int FILE_REF = 1;
}
@Test
- public void should_find_diff_with_target_branch_for_prs() {
+ public void should_find_diff_with_reference_branch_for_prs() {
Component component = fileComponent(FILE_REF);
- Component componentInTarget = fileComponent(2);
mockLineHashesInDb(2, CONTENT);
setLineHashesInReport(component, CONTENT);
when(analysisMetadataHolder.isPullRequest()).thenReturn(true);
- when(mergeAndTargetBranchComponentUuids.getTargetBranchComponentUuid(component.getKey())).thenReturn("uuid_2");
-
- assertThat(underTest.computeMatchingLines(component)).containsExactly(1, 2, 3, 4, 5, 6, 7);
- }
-
- @Test
- public void should_find_diff_with_merge_branch_for_prs_if_not_found_in_target() {
- Component component = fileComponent(FILE_REF);
- Component componentInTarget = fileComponent(2);
-
- mockLineHashesInDb(2, CONTENT);
- setLineHashesInReport(component, CONTENT);
-
- when(analysisMetadataHolder.isPullRequest()).thenReturn(true);
- when(mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(component.getKey())).thenReturn("uuid_2");
+ when(referenceBranchComponentUuids.getComponentUuid(component.getKey())).thenReturn("uuid_2");
assertThat(underTest.computeMatchingLines(component)).containsExactly(1, 2, 3, 4, 5, 6, 7);
}
assertThat(underTest.computeMatchingLines(component)).containsExactly(1, 2, 3, 4, 5, 6, 7);
}
- private void mockLineHashesInDb(int ref, @Nullable String[] lineHashes) {
+ private void mockLineHashesInDb(int ref, String[] lineHashes) {
when(fileSourceDao.selectLineHashes(dbSession, componentUuidOf(String.valueOf(ref))))
.thenReturn(Arrays.asList(lineHashes));
}
}
@Override
- public String getMergeBranchUuid() {
+ public String getReferenceBranchUuid() {
throw new UnsupportedOperationException();
}
private void setBranch(BranchType type, @Nullable String mergeBranchUuid) {
Branch branch = mock(Branch.class);
when(branch.getType()).thenReturn(type);
- when(branch.getMergeBranchUuid()).thenReturn(mergeBranchUuid);
+ when(branch.getReferenceBranchUuid()).thenReturn(mergeBranchUuid);
analysisMetadataHolder.setBranch(branch);
}
package org.sonar.db.component;
public enum BranchType {
-
- /**
- * Short-lived branch
- */
- SHORT,
-
BRANCH,
-
- /**
- * Pull request
- */
PULL_REQUEST
}
}
/**
- * Returns components with open issues from branches that use a certain long living branch as reference (merge branch).
+ * Returns components with open issues from P/Rs that use a certain branch as reference (reference branch).
* Excludes components from the current branch.
*/
public List<KeyWithUuidDto> selectAllSiblingComponentKeysHavingOpenIssues(DbSession dbSession, String referenceBranchUuid, String currentBranchUuid) {
}
/**
- * Branch name for SLB, PR key for PR
+ * Branch name for BRANCH, PR key for PR
*/
public String getBranchKey() {
return branchKey;
* If Main Branch = 100 LOCs and the "largest branch" is 120 LOCs, I'm expecting to consider the value 120.
* If Main Branch = 100 LOCs and the "largest branch" is 80 LOCs, I'm expecting to consider the value 100.
*/
- public long sumNclocOfBiggestLongLivingBranch(DbSession dbSession, SumNclocDbQuery dbQuery) {
- Long ncloc = mapper(dbSession).sumNclocOfBiggestLongLivingBranch(
+ public long sumNclocOfBiggestBranch(DbSession dbSession, SumNclocDbQuery dbQuery) {
+ Long ncloc = mapper(dbSession).sumNclocOfBiggestBranch(
NCLOC_KEY, KeyType.BRANCH, BranchType.BRANCH, dbQuery.getOrganizationUuid(), dbQuery.getOnlyPrivateProjects(), dbQuery.getProjectUuidToExclude());
return ncloc == null ? 0L : ncloc;
}
@Param("baseUuidPath") String baseUuidPath,
ResultHandler<LiveMeasureDto> resultHandler);
- Long sumNclocOfBiggestLongLivingBranch(
+ Long sumNclocOfBiggestBranch(
@Param("ncloc") String nclocKey,
@Param("branch") KeyType branchOrPullRequest,
@Param("branchType") BranchType branchType,
ON p.uuid = i.component_uuid
JOIN project_branches b
ON i.project_uuid = b.uuid
- AND (b.branch_type = 'SHORT' OR b.branch_type = 'PULL_REQUEST')
+ AND b.branch_type = 'PULL_REQUEST'
AND b.merge_branch_uuid = #{referenceBranchUuid,jdbcType=VARCHAR}
AND b.uuid != #{currentBranchUuid,jdbcType=VARCHAR}
AND i.status != 'CLOSED'
and lm.component_uuid = #{componentUuid, jdbcType=VARCHAR}
</select>
- <select id="sumNclocOfBiggestLongLivingBranch" parameterType="map" resultType="long">
+ <select id="sumNclocOfBiggestBranch" parameterType="map" resultType="long">
select sum(sumncloc.maxncloc) from (
select b.project_uuid as projectUuid, max(lm.value) as maxncloc
from live_measures lm
ComponentDto simpleProject = db.components().insertMainBranch(organization);
db.measures().insertLiveMeasure(simpleProject, ncloc, m -> m.setValue(10d));
- ComponentDto projectWithBiggerLongLivingBranch = db.components().insertMainBranch(organization);
- ComponentDto bigBranch = db.components().insertProjectBranch(projectWithBiggerLongLivingBranch, b -> b.setBranchType(BranchType.BRANCH));
- db.measures().insertLiveMeasure(projectWithBiggerLongLivingBranch, ncloc, m -> m.setValue(100d));
+ ComponentDto projectWithBiggerBranch = db.components().insertMainBranch(organization);
+ ComponentDto bigBranch = db.components().insertProjectBranch(projectWithBiggerBranch, b -> b.setBranchType(BranchType.BRANCH));
+ db.measures().insertLiveMeasure(projectWithBiggerBranch, ncloc, m -> m.setValue(100d));
db.measures().insertLiveMeasure(bigBranch, ncloc, m -> m.setValue(200d));
ComponentDto projectWithLinesButNoLoc = db.components().insertMainBranch(organization);
.setOnlyPrivateProjects(false)
.setOrganizationUuid(organization.getUuid())
.build();
- long result = underTest.sumNclocOfBiggestLongLivingBranch(db.getSession(), query);
+ long result = underTest.sumNclocOfBiggestBranch(db.getSession(), query);
assertThat(result).isEqualTo(10L + 200L);
}
.setOnlyPrivateProjects(false)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build();
- long result = underTest.sumNclocOfBiggestLongLivingBranch(db.getSession(), query);
+ long result = underTest.sumNclocOfBiggestBranch(db.getSession(), query);
assertThat(result).isEqualTo(0L);
}
ComponentDto simpleProject = db.components().insertMainBranch(organization);
db.measures().insertLiveMeasure(simpleProject, ncloc, m -> m.setValue(10d));
- ComponentDto projectWithBiggerLongLivingBranch = db.components().insertMainBranch(organization);
- ComponentDto bigBranch = db.components().insertProjectBranch(projectWithBiggerLongLivingBranch, b -> b.setBranchType(BranchType.BRANCH));
- db.measures().insertLiveMeasure(projectWithBiggerLongLivingBranch, ncloc, m -> m.setValue(100d));
+ ComponentDto projectWithBiggerBranch = db.components().insertMainBranch(organization);
+ ComponentDto bigBranch = db.components().insertProjectBranch(projectWithBiggerBranch, b -> b.setBranchType(BranchType.BRANCH));
+ db.measures().insertLiveMeasure(projectWithBiggerBranch, ncloc, m -> m.setValue(100d));
db.measures().insertLiveMeasure(bigBranch, ncloc, m -> m.setValue(200d));
ComponentDto projectToExclude = db.components().insertMainBranch(organization);
.setProjectUuidToExclude(projectToExclude.uuid())
.setOnlyPrivateProjects(false)
.build();
- long result = underTest.sumNclocOfBiggestLongLivingBranch(db.getSession(), query);
+ long result = underTest.sumNclocOfBiggestBranch(db.getSession(), query);
assertThat(result).isEqualTo(10L + 200L);
}
when(system2.now()).thenReturn(new Date().getTime());
RuleDefinitionDto rule = db.rules().insert();
ComponentDto project = db.components().insertMainBranch();
- ComponentDto longBranch = db.components().insertProjectBranch(project);
+ ComponentDto nonMainBranch = db.components().insertProjectBranch(project);
ComponentDto recentPullRequest = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST));
// pull request with other components and issues, updated 31 days ago
underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler());
dbSession.commit();
- assertThat(uuidsIn("projects")).containsOnly(project.uuid(), longBranch.uuid(), recentPullRequest.uuid());
+ assertThat(uuidsIn("projects")).containsOnly(project.uuid(), nonMainBranch.uuid(), recentPullRequest.uuid());
}
@Test
when(system2.now()).thenReturn(new Date().getTime());
RuleDefinitionDto rule = db.rules().insert();
ComponentDto project = db.components().insertMainBranch();
- ComponentDto longBranch = db.components().insertProjectBranch(project);
+ ComponentDto nonMainBranch = db.components().insertProjectBranch(project);
when(system2.now()).thenReturn(DateUtils.addDays(new Date(), -31).getTime());
dbSession.commit();
// branch1 wasn't deleted since it was being analyzed!
- assertThat(uuidsIn("projects")).containsOnly(project.uuid(), longBranch.uuid(), branch1.uuid());
+ assertThat(uuidsIn("projects")).containsOnly(project.uuid(), nonMainBranch.uuid(), branch1.uuid());
}
@Test
+++ /dev/null
-CREATE TABLE PROJECT_BRANCHES(
- UUID VARCHAR(50) NOT NULL,
- PROJECT_UUID VARCHAR(50) NOT NULL,
- KEE VARCHAR(255) NOT NULL,
- BRANCH_TYPE VARCHAR(12),
- MERGE_BRANCH_UUID VARCHAR(50),
- KEY_TYPE VARCHAR(12) NOT NULL,
- PULL_REQUEST_BINARY BLOB,
- MANUAL_BASELINE_ANALYSIS_UUID VARCHAR(40),
- CREATED_AT BIGINT NOT NULL,
- UPDATED_AT BIGINT NOT NULL,
- EXCLUDE_FROM_PURGE BOOLEAN
-);
public static final String STATUS = "status";
public static final String AUTHOR = "author";
public static final String FILE = "file";
- public static final String FROM_LONG_BRANCH = "from_long_branch";
- public static final String FROM_SHORT_BRANCH = "from_short_branch";
+ public static final String FROM_BRANCH = "from_branch";
/**
* It should be renamed to 'effort', but it hasn't been done to prevent a massive update in database
}
public enum Type {
- LONG, SHORT, PULL_REQUEST, BRANCH
+ PULL_REQUEST, BRANCH
}
@Override
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, null, null, qualityGate, 1L, properties));
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, new Analysis("foo", 1_500L, "sha1"), null, qualityGate, 1L, properties));
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, null, qualityGate, 1L, properties));
- assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, new Branch(false, "B", Branch.Type.LONG), qualityGate, 1L, properties));
+ assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, new Branch(false, "B", Branch.Type.BRANCH), qualityGate, 1L, properties));
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, branch, null, 1L, properties));
EvaluatedQualityGate otherQualityGate = EvaluatedQualityGate.newBuilder()
.setQualityGate(new QualityGate("A", "B", emptySet()))
assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(project, ceTask, new Analysis("foo", 1_500L, "sha1"), null, qualityGate, 1L, properties).hashCode());
assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, null, qualityGate, 1L, properties).hashCode());
assertThat(underTest.hashCode())
- .isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, new Branch(false, "B", Branch.Type.SHORT), qualityGate, 1L, properties).hashCode());
+ .isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, new Branch(false, "B", Branch.Type.BRANCH), qualityGate, 1L, properties).hashCode());
assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, branch, null, 1L, properties).hashCode());
EvaluatedQualityGate otherQualityGate = EvaluatedQualityGate.newBuilder()
.setQualityGate(new QualityGate("A", "B", emptySet()))
.setOnlyPrivateProjects(false)
.setOrganizationUuid(defaultOrganizationProvider.get().getUuid())
.build();
- data.setNcloc(dbClient.liveMeasureDao().sumNclocOfBiggestLongLivingBranch(dbSession, query));
+ data.setNcloc(dbClient.liveMeasureDao().sumNclocOfBiggestBranch(dbSession, query));
}
Optional<String> installationDateProperty = internalProperties.read(InternalProperties.INSTALLATION_DATE);
public void onIssueChangesCallsWebhookOnBranch(BranchType branchType) {
OrganizationDto organization = dbTester.organizations().insert();
ComponentAndBranch mainBranch = insertMainBranch(organization);
- ComponentAndBranch longBranch = insertProjectBranch(mainBranch.component, branchType, "foo");
- SnapshotDto analysis = insertAnalysisTask(longBranch);
+ ComponentAndBranch nonMainBranch = insertProjectBranch(mainBranch.component, branchType, "foo");
+ SnapshotDto analysis = insertAnalysisTask(nonMainBranch);
Configuration configuration = mock(Configuration.class);
- QGChangeEvent qualityGateEvent = newQGChangeEvent(longBranch, analysis, configuration, null);
+ QGChangeEvent qualityGateEvent = newQGChangeEvent(nonMainBranch, analysis, configuration, null);
mockWebhookEnabled(qualityGateEvent.getProject());
underTest.onIssueChanges(qualityGateEvent, CHANGED_ISSUES_ARE_IGNORED);
- verifyWebhookCalled(longBranch, analysis, qualityGateEvent.getProject());
+ verifyWebhookCalled(nonMainBranch, analysis, qualityGateEvent.getProject());
}
@DataProvider
issue.updateDate() == null
// name of rule is displayed in notification, rule must therefor be present
|| !rule.isPresent()
- // notification are not supported on PRs and short lived branches
+ // notification are not supported on PRs
|| !hasNotificationSupport(branchDto)) {
return issueDto;
}
@Override
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction("list")
- .setDescription("List the New Code Periods for all long lived branches in a project.<br>" +
+ .setDescription("List the New Code Periods for all branches in a project.<br>" +
"Requires the permission to browse the project")
.setSince("8.0")
.setResponseExample(getClass().getResource("list-example.json"))
@Override
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction("set_baseline")
- .setDescription("Set an analysis as the baseline of the New Code Period on a project or a long-lived branch.<br/>" +
+ .setDescription("Set an analysis as the baseline of the New Code Period on a project or a branch.<br/>" +
"This manually set baseline.<br/>" +
"Requires one of the following permissions:" +
"<ul>" +
@Override
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction("unset_baseline")
- .setDescription("Unset any manually-set New Code Period baseline on a project or a long-lived branch.<br/>" +
+ .setDescription("Unset any manually-set New Code Period baseline on a project or a branch.<br/>" +
"Unsetting a manual baseline restores the use of the default new code period setting.<br/>" +
"Requires one of the following permissions:" +
"<ul>" +
OrganizationDto org = componentFinder.getOrganization(session, component);
Optional<SnapshotDto> analysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(session, component.projectUuid());
- JsonWriter json = response.newJsonWriter();
- json.beginObject();
- writeComponent(json, session, component, org, analysis.orElse(null));
- writeAlmDetails(json, session, rootProject);
- writeProfiles(json, session, component);
- writeQualityGate(json, session, org, rootProject);
- if (userSession.hasComponentPermission(ADMIN, component) ||
- userSession.hasPermission(ADMINISTER_QUALITY_PROFILES, org) ||
- userSession.hasPermission(ADMINISTER_QUALITY_GATES, org)) {
- writeConfiguration(json, component, org);
+ try (JsonWriter json = response.newJsonWriter()) {
+ json.beginObject();
+ writeComponent(json, session, component, org, analysis.orElse(null));
+ writeAlmDetails(json, session, rootProject);
+ writeProfiles(json, session, component);
+ writeQualityGate(json, session, org, rootProject);
+ if (userSession.hasComponentPermission(ADMIN, component) ||
+ userSession.hasPermission(ADMINISTER_QUALITY_PROFILES, org) ||
+ userSession.hasPermission(ADMINISTER_QUALITY_GATES, org)) {
+ writeConfiguration(json, component, org);
+ }
+ writeBreadCrumbs(json, session, component);
+ json.endObject().close();
}
- writeBreadCrumbs(json, session, component);
- json.endObject().close();
}
}
.setOnlyPrivateProjects(false)
.setOrganizationUuid(defaultOrganizationProvider.get().getUuid())
.build();
- return dbClient.liveMeasureDao().sumNclocOfBiggestLongLivingBranch(dbSession, query);
+ return dbClient.liveMeasureDao().sumNclocOfBiggestBranch(dbSession, query);
}
}
}
}
@Test
- public void measure_on_long_living_branch() {
+ public void measure_on_non_main_branch() {
ComponentDto project = db.components().insertMainBranch(p -> p.setPrivate(false));
userSession.registerComponents(project);
MetricDto metric = db.measures().insertMetric(m -> m.setKey(BUGS_KEY).setValueType(INT.name()));
public void pull_requests() {
ComponentDto project = db.components().insertMainBranch();
userSession.logIn().addProjectPermission(UserRole.USER, project);
- ComponentDto longLivingBranch = db.components().insertProjectBranch(project,
- b -> b.setKey("long").setBranchType(BranchType.BRANCH));
- ComponentDto pullRequestOnLong = db.components().insertProjectBranch(project,
- b -> b.setKey("pull_request_on_long")
+ ComponentDto nonMainBranch = db.components().insertProjectBranch(project,
+ b -> b.setKey("branch1").setBranchType(BranchType.BRANCH));
+ ComponentDto pullRequestOnNonMainBranch = db.components().insertProjectBranch(project,
+ b -> b.setKey("pull_request_on_branch1")
.setBranchType(PULL_REQUEST)
- .setMergeBranchUuid(longLivingBranch.uuid())
+ .setMergeBranchUuid(nonMainBranch.uuid())
.setPullRequestData(DbProjectBranches.PullRequestData.newBuilder().setBranch("feature/bar").build()));
ComponentDto pullRequestOnMaster = db.components().insertProjectBranch(project,
b -> b.setKey("pull_request_on_master")
assertThat(response.getPullRequestsList())
.extracting(PullRequest::getKey, PullRequest::getBase)
.containsExactlyInAnyOrder(
- tuple(pullRequestOnLong.getPullRequest(), longLivingBranch.getBranch()),
+ tuple(pullRequestOnNonMainBranch.getPullRequest(), nonMainBranch.getBranch()),
tuple(pullRequestOnMaster.getPullRequest(), "master"));
}
public void status_on_pull_requests() {
ComponentDto project = db.components().insertMainBranch();
userSession.logIn().addProjectPermission(UserRole.USER, project);
- ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
+ ComponentDto nonMainBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
ComponentDto pullRequest = db.components().insertProjectBranch(project,
b -> b.setKey("pr-123")
.setBranchType(PULL_REQUEST)
- .setMergeBranchUuid(longLivingBranch.uuid())
+ .setMergeBranchUuid(nonMainBranch.uuid())
.setPullRequestData(DbProjectBranches.PullRequestData.newBuilder().setBranch("feature/bar").build()));
db.measures().insertLiveMeasure(pullRequest, qualityGateStatus, m -> m.setData("ERROR"));
RuleDefinitionDto rule = db.rules().insert();
public void status_on_pull_request_with_no_issue() {
ComponentDto project = db.components().insertMainBranch();
userSession.logIn().addProjectPermission(UserRole.USER, project);
- ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
+ ComponentDto nonMainBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
db.components().insertProjectBranch(project,
b -> b.setKey("pr-123")
.setBranchType(PULL_REQUEST)
- .setMergeBranchUuid(longLivingBranch.uuid())
+ .setMergeBranchUuid(nonMainBranch.uuid())
.setPullRequestData(DbProjectBranches.PullRequestData.newBuilder().setBranch("feature/bar").build()));
issueIndexer.indexOnStartup(emptySet());
permissionIndexerTester.allowOnlyAnyone(project);
@Test
public void response_contains_date_of_last_analysis() {
- Long lastAnalysisLongLivingBranch = dateToLong(parseDateTime("2017-04-01T00:00:00+0100"));
+ Long lastAnalysisNonMainBranch = dateToLong(parseDateTime("2017-04-01T00:00:00+0100"));
Long previousAnalysisPullRequest = dateToLong(parseDateTime("2017-04-02T00:00:00+0100"));
Long lastAnalysisPullRequest = dateToLong(parseDateTime("2017-04-03T00:00:00+0100"));
.setMergeBranchUuid(project.uuid())
.setPullRequestData(DbProjectBranches.PullRequestData.newBuilder().setBranch("feature/pr1").build()));
- ComponentDto longLivingBranch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
+ ComponentDto nonMainBranch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
ComponentDto pullRequest2 = db.components().insertProjectBranch(project,
b -> b.setKey("pr2")
.setBranchType(PULL_REQUEST)
- .setMergeBranchUuid(longLivingBranch2.uuid())
+ .setMergeBranchUuid(nonMainBranch2.uuid())
.setPullRequestData(DbProjectBranches.PullRequestData.newBuilder().setBranch("feature/pr2").build()));
db.getDbClient().snapshotDao().insert(db.getSession(),
- newAnalysis(longLivingBranch2).setCreatedAt(lastAnalysisLongLivingBranch));
+ newAnalysis(nonMainBranch2).setCreatedAt(lastAnalysisNonMainBranch));
db.getDbClient().snapshotDao().insert(db.getSession(),
newAnalysis(pullRequest2).setCreatedAt(previousAnalysisPullRequest).setLast(false));
db.getDbClient().snapshotDao().insert(db.getSession(),
}
@Test
- public void set_baseline_on_long_living_branch() {
+ public void set_baseline_on_non_main_branch() {
ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.BRANCH);
db.components().insertProjectBranch(project, branch);
}
@Test
- public void does_not_fail_and_has_no_effect_when_there_is_no_baseline_on_long_living_branch() {
+ public void does_not_fail_and_has_no_effect_when_there_is_no_baseline_on_non_main_branch() {
ComponentDto project = db.components().insertMainBranch(db.organizations().insert());
ComponentDto branch = db.components().insertProjectBranch(project);
SnapshotDto analysis = db.components().insertSnapshot(project);
}
@Test
- public void unset_baseline_when_it_is_set_long_living_branch() {
+ public void unset_baseline_when_it_is_set_non_main_branch() {
ComponentDto project = db.components().insertMainBranch(db.organizations().insert());
ComponentDto branch = db.components().insertProjectBranch(project);
- SnapshotDto projectAnalysis = db.components().insertSnapshot(branch);
+ db.components().insertSnapshot(branch);
SnapshotDto branchAnalysis = db.components().insertSnapshot(project);
db.newCodePeriods().insert(project.projectUuid(), branch.uuid(), NewCodePeriodType.SPECIFIC_ANALYSIS, branchAnalysis.getUuid());
// Check the size of the archive
zip.doLast {
def minLength = 202000000
- def maxLength = 210000000
+ def maxLength = 211000000
def length = archiveFile.get().asFile.length()
if (length < minLength)
throw new GradleException("$archiveName size ($length) too small. Min is $minLength")
// all changes
// -- contains only current change (if any) on CE side unless reopening a closed issue or copying issue from base branch
- // when analyzing a long living branch from the first time
+ // when analyzing a branch from the first time
private List<FieldDiffs> changes = null;
// true if the issue did not exist in the previous scan.
/**
* Trimmed message of issue
*/
+ @CheckForNull
String getMessage();
@CheckForNull
quality_gates.conditions.new_code.description=Conditions on New Code apply to all branches and to Pull Requests.
quality_gates.conditions.overall_code=On Overall Code
quality_gates.conditions.overall_code.long=Conditions on Overall Code
-quality_gates.conditions.overall_code.description=Conditions on Overall Code apply to long living branches only.
+quality_gates.conditions.overall_code.description=Conditions on Overall Code apply to branches only.
quality_gates.conditions.operator=Operator
quality_gates.conditions.warning=Warning
quality_gates.conditions.warning.tooltip=Warning status is deprecated and will disappear with the next update of the Quality Gate.
public interface Branch {
enum Type {
- LONG, SHORT, BRANCH, PULL_REQUEST
+ BRANCH, PULL_REQUEST
}
boolean isMain();
builder.setBranchType(branchType);
String referenceBranch = branchConfiguration.referenceBranchName();
if (referenceBranch != null) {
- builder.setMergeBranchName(referenceBranch);
+ builder.setReferenceBranchName(referenceBranch);
}
String targetBranchName = branchConfiguration.targetBranchName();
if (targetBranchName != null) {
/**
* The branch from which we should load project settings/quality profiles/compare changed files/...
- * For branches, it's the to default branch in case of first analysis, otherwise it's the branch itself.
- * For PR, we look at sonar.pullrequest.base (default to default branch). If it exists but is a short living branch or PR, we will
+ * For branches, it's the default branch in case of first analysis, otherwise it's the branch itself.
+ * For PR, we look at sonar.pullrequest.base (default to default branch). If it exists and is not a PR we use it. If it exists but is a PR, we will
* transitively use its own target. If base is not analyzed, we will use default branch.
*
* @return null if the branch feature is not available or no branch was specified.
private BranchType branchType = BranchType.BRANCH;
private String branchName = null;
private String branchTarget = null;
- private String longLivingSonarReferenceBranch = null;
+ private String referenceBranchName = null;
@Override
public BranchType branchType() {
@CheckForNull
@Override
public String referenceBranchName() {
- return longLivingSonarReferenceBranch;
+ return referenceBranchName;
}
@Override
return this;
}
- public ScannerMediumTester setLongLivingSonarReferenceBranch(String longLivingSonarReferenceBranch) {
- this.branchConfiguration.longLivingSonarReferenceBranch = longLivingSonarReferenceBranch;
+ public ScannerMediumTester setReferenceBranchName(String referenceBranchNam) {
+ this.branchConfiguration.referenceBranchName = referenceBranchNam;
return this;
}
AnalysisResult result = getResult(tester
.setBranchName(branchName)
.setBranchTarget(branchTarget)
- .setLongLivingSonarReferenceBranch(branchTarget)
+ .setReferenceBranchName(branchTarget)
.setBranchType(BranchType.BRANCH));
ScannerReport.Metadata metadata = result.getReportReader().readMetadata();
assertThat(metadata.getBranchName()).isEqualTo(branchName);
assertThat(metadata.getBranchType()).isEqualTo(ScannerReport.Metadata.BranchType.BRANCH);
- assertThat(metadata.getMergeBranchName()).isEqualTo(branchTarget);
+ assertThat(metadata.getReferenceBranchName()).isEqualTo(branchTarget);
}
private AnalysisResult getResult(ScannerMediumTester tester) {
ScannerReport.Metadata metadata = reader.readMetadata();
assertThat(metadata.getBranchName()).isEqualTo(branchName);
assertThat(metadata.getBranchType()).isEqualTo(ScannerReport.Metadata.BranchType.BRANCH);
- assertThat(metadata.getMergeBranchName()).isEmpty();
+ assertThat(metadata.getReferenceBranchName()).isEmpty();
assertThat(metadata.getTargetBranchName()).isEqualTo(targetName);
}
string branch_name = 9;
BranchType branch_type = 10;
- string merge_branch_name = 11;
+ string reference_branch_name = 11;
string relative_path_from_scm_root = 12;
string scm_revision_id = 13;
enum BranchType {
UNSET = 0;
BRANCH = 1;
- PULL_REQUEST = 3;
+ PULL_REQUEST = 2;
}
}
}
enum BranchType {
- // Zero is required in order to not get LONG as default value
- // See http://androiddevblog.com/protocol-buffers-pitfall-adding-enum-values/
- UNKNOWN_BRANCH_TYPE = 0;
+ reserved 1, 2;
- LONG = 1;
- SHORT = 2;
+ UNKNOWN_BRANCH_TYPE = 0;
PULL_REQUEST = 3;
BRANCH = 4;
}