use of com.google.gerrit.entities.PatchSetApproval in project gerrit by GerritCodeReview.
the class ChangeNotesParser method backFillMissingCopiedApprovalsFromSubmitRecords.
/**
* Returns patch-set approvals that do not exist on the latest patch-set but for which a submit
* record exists in NoteDb when the change was merged.
*/
private List<PatchSetApproval> backFillMissingCopiedApprovalsFromSubmitRecords(ListMultimap<PatchSet.Id, PatchSetApproval> allApprovals, @Nullable PatchSet.Id latestPs) {
List<PatchSetApproval> copiedApprovals = new ArrayList<>();
if (latestPs == null) {
return copiedApprovals;
}
List<PatchSetApproval> approvalsOnLatestPs = allApprovals.get(latestPs);
ListMultimap<Account.Id, PatchSetApproval> approvalsByUser = getApprovalsByUser(allApprovals);
List<SubmitRecord.Label> submitRecordLabels = submitRecords.stream().filter(r -> r.labels != null).flatMap(r -> r.labels.stream()).filter(label -> Status.OK.equals(label.status) || Status.MAY.equals(label.status)).collect(Collectors.toList());
for (SubmitRecord.Label recordLabel : submitRecordLabels) {
String labelName = recordLabel.label;
Account.Id appliedBy = recordLabel.appliedBy;
if (appliedBy == null || labelName == null) {
continue;
}
boolean existsAtLatestPs = approvalsOnLatestPs.stream().anyMatch(a -> a.accountId().equals(appliedBy) && a.label().equals(labelName));
if (existsAtLatestPs) {
continue;
}
// Search for an approval for this label on the max previous patch-set and copy the approval.
Collection<PatchSetApproval> userApprovals = approvalsByUser.get(appliedBy).stream().filter(approval -> approval.label().equals(labelName)).collect(Collectors.toList());
if (userApprovals.isEmpty()) {
continue;
}
PatchSetApproval lastApproved = Collections.max(userApprovals, comparingInt(a -> a.patchSetId().get()));
copiedApprovals.add(lastApproved.copyWithPatchSet(latestPs));
}
return copiedApprovals;
}
use of com.google.gerrit.entities.PatchSetApproval in project gerrit by GerritCodeReview.
the class ChangeUpdate method applyImpl.
@Override
protected CommitBuilder applyImpl(RevWalk rw, ObjectInserter ins, ObjectId curr) throws IOException {
checkState(deleteCommentRewriter == null && deleteChangeMessageRewriter == null, "cannot update and rewrite ref in one BatchUpdate");
PatchSet.Id patchSetId = psId != null ? psId : getChange().currentPatchSetId();
StringBuilder msg = new StringBuilder();
if (commitSubject != null) {
msg.append(commitSubject);
} else {
msg.append("Update patch set ").append(patchSetId.get());
}
msg.append("\n\n");
if (changeMessage != null) {
msg.append(changeMessage);
msg.append("\n\n");
}
addPatchSetFooter(msg, patchSetId);
if (currentPatchSet) {
addFooter(msg, FOOTER_CURRENT, Boolean.TRUE);
}
if (psDescription != null) {
addFooter(msg, FOOTER_PATCH_SET_DESCRIPTION, psDescription);
}
if (changeId != null) {
addFooter(msg, FOOTER_CHANGE_ID, changeId);
}
if (subject != null) {
addFooter(msg, FOOTER_SUBJECT, subject);
}
if (branch != null) {
addFooter(msg, FOOTER_BRANCH, branch);
}
if (status != null) {
addFooter(msg, FOOTER_STATUS, status.name().toLowerCase());
if (status.equals(Change.Status.ABANDONED)) {
clearAttentionSet("Change was abandoned");
}
if (status.equals(Change.Status.MERGED)) {
clearAttentionSet("Change was submitted");
}
}
if (topic != null) {
addFooter(msg, FOOTER_TOPIC, topic);
}
if (commit != null) {
addFooter(msg, FOOTER_COMMIT, commit);
}
if (assignee != null) {
if (assignee.isPresent()) {
addFooter(msg, FOOTER_ASSIGNEE);
noteUtil.appendAccountIdIdentString(msg, assignee.get()).append('\n');
} else {
addFooter(msg, FOOTER_ASSIGNEE).append('\n');
}
}
Joiner comma = Joiner.on(',');
if (hashtags != null) {
addFooter(msg, FOOTER_HASHTAGS, comma.join(hashtags));
}
if (tag != null) {
addFooter(msg, FOOTER_TAG, tag);
}
if (groups != null) {
addFooter(msg, FOOTER_GROUPS, comma.join(groups));
}
for (Map.Entry<Account.Id, ReviewerStateInternal> e : reviewers.entrySet()) {
addFooter(msg, e.getValue().getFooterKey());
noteUtil.appendAccountIdIdentString(msg, e.getKey()).append('\n');
}
applyReviewerUpdatesToAttentionSet();
for (Map.Entry<Address, ReviewerStateInternal> e : reviewersByEmail.entrySet()) {
addFooter(msg, e.getValue().getByEmailFooterKey(), e.getKey().toString());
}
for (Table.Cell<String, Account.Id, Optional<Short>> c : approvals.cellSet()) {
addLabelFooter(msg, c, patchSetId);
}
for (PatchSetApproval patchSetApproval : copiedApprovals) {
addCopiedLabelFooter(msg, patchSetApproval);
}
if (submissionId != null) {
addFooter(msg, FOOTER_SUBMISSION_ID, submissionId);
}
if (submitRecords != null) {
for (SubmitRecord rec : submitRecords) {
addFooter(msg, FOOTER_SUBMITTED_WITH).append(rec.status);
if (rec.errorMessage != null) {
msg.append(' ').append(sanitizeFooter(rec.errorMessage));
}
msg.append('\n');
if (rec.ruleName != null) {
addFooter(msg, FOOTER_SUBMITTED_WITH).append("Rule-Name: ").append(rec.ruleName);
msg.append('\n');
}
if (rec.labels != null) {
for (SubmitRecord.Label label : rec.labels) {
// Label names/values are safe to append without sanitizing.
addFooter(msg, FOOTER_SUBMITTED_WITH).append(label.status).append(": ").append(label.label);
if (label.appliedBy != null) {
msg.append(": ");
noteUtil.appendAccountIdIdentString(msg, label.appliedBy);
}
msg.append('\n');
}
}
}
}
if (!Objects.equals(accountId, realAccountId)) {
addFooter(msg, FOOTER_REAL_USER);
noteUtil.appendAccountIdIdentString(msg, realAccountId).append('\n');
}
if (isPrivate != null) {
addFooter(msg, FOOTER_PRIVATE, isPrivate);
}
if (workInProgress != null) {
addFooter(msg, FOOTER_WORK_IN_PROGRESS, workInProgress);
if (workInProgress) {
clearAttentionSet("Change was marked work in progress");
} else {
addAllReviewersToAttentionSet();
}
}
if (revertOf != null) {
addFooter(msg, FOOTER_REVERT_OF, revertOf);
}
if (cherryPickOf != null) {
if (cherryPickOf.isPresent()) {
addFooter(msg, FOOTER_CHERRY_PICK_OF, cherryPickOf.get());
} else {
// Update cherryPickOf with an empty value.
addFooter(msg, FOOTER_CHERRY_PICK_OF).append('\n');
}
}
updateAttentionSet(msg);
CommitBuilder cb = new CommitBuilder();
cb.setMessage(msg.toString());
try {
ObjectId treeId = storeRevisionNotes(rw, ins, curr);
if (treeId != null) {
cb.setTreeId(treeId);
}
} catch (ConfigInvalidException e) {
throw new StorageException(e);
}
return cb;
}
use of com.google.gerrit.entities.PatchSetApproval in project gerrit by GerritCodeReview.
the class SubmitWithStickyApprovalDiff method getLatestApprovedPatchsetId.
private PatchSet.Id getLatestApprovedPatchsetId(ChangeNotes notes) {
ProjectState projectState = projectCache.get(notes.getProjectName()).orElseThrow(illegalState(notes.getProjectName()));
PatchSet.Id maxPatchSetId = PatchSet.id(notes.getChangeId(), 1);
for (PatchSetApproval patchSetApproval : notes.getApprovals().values()) {
if (!patchSetApproval.label().equals(LabelId.CODE_REVIEW)) {
continue;
}
Optional<LabelType> lt = projectState.getLabelTypes(notes).byLabel(patchSetApproval.labelId());
if (!lt.isPresent() || !lt.get().isMaxPositive(patchSetApproval)) {
continue;
}
if (patchSetApproval.patchSetId().get() > maxPatchSetId.get()) {
maxPatchSetId = patchSetApproval.patchSetId();
}
}
return maxPatchSetId;
}
use of com.google.gerrit.entities.PatchSetApproval in project gerrit by GerritCodeReview.
the class StickyApprovalsIT method stickyVoteStoredOnUploadWithRealAccount.
@Test
public void stickyVoteStoredOnUploadWithRealAccount() throws Exception {
// Give "user" permission to vote on behalf of other users.
projectOperations.project(project).forUpdate().add(allowLabel(TestLabels.codeReview().getName()).impersonation(true).ref("refs/heads/*").group(REGISTERED_USERS).range(-1, 1)).update();
// Code-Review will be sticky.
String label = LabelId.CODE_REVIEW;
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().updateLabelType(label, b -> b.setCopyAnyScore(true));
u.save();
}
PushOneCommit.Result r = createChange();
// Add a new vote as user
requestScopeOperations.setApiUser(user.id());
ReviewInput input = new ReviewInput().label(LabelId.CODE_REVIEW, 1);
input.onBehalfOf = admin.email();
gApi.changes().id(r.getChangeId()).current().review(input);
// Make a new patchset, keeping the Code-Review +1 vote.
amendChange(r.getChangeId());
List<PatchSetApproval> patchSetApprovals = r.getChange().notes().getApprovalsWithCopied().values().stream().sorted(comparing(a -> a.patchSetId().get())).collect(toImmutableList());
PatchSetApproval nonCopied = patchSetApprovals.get(0);
assertThat(nonCopied.patchSetId().get()).isEqualTo(1);
assertThat(nonCopied.accountId().get()).isEqualTo(admin.id().get());
assertThat(nonCopied.realAccountId().get()).isEqualTo(user.id().get());
assertThat(nonCopied.label()).isEqualTo(LabelId.CODE_REVIEW);
assertThat(nonCopied.value()).isEqualTo((short) 1);
assertThat(nonCopied.copied()).isFalse();
PatchSetApproval copied = patchSetApprovals.get(1);
assertThat(copied.patchSetId().get()).isEqualTo(2);
assertThat(copied.accountId().get()).isEqualTo(admin.id().get());
assertThat(copied.realAccountId().get()).isEqualTo(user.id().get());
assertThat(copied.label()).isEqualTo(LabelId.CODE_REVIEW);
assertThat(copied.value()).isEqualTo((short) 1);
assertThat(copied.copied()).isTrue();
}
use of com.google.gerrit.entities.PatchSetApproval in project gerrit by GerritCodeReview.
the class StickyApprovalsIT method stickyVoteStoredOnRebase.
@Test
public void stickyVoteStoredOnRebase() throws Exception {
// Code-Review will be sticky.
String label = LabelId.CODE_REVIEW;
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().updateLabelType(label, b -> b.setCopyAnyScore(true));
u.save();
}
// Create two changes both with the same parent
PushOneCommit.Result r = createChange();
testRepo.reset("HEAD~1");
PushOneCommit.Result r2 = createChange();
// Approve and submit the first change
RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
revision.review(ReviewInput.approve().label(LabelId.VERIFIED, 1));
revision.submit();
// Add an approval whose score should be copied.
gApi.changes().id(r2.getChangeId()).current().review(ReviewInput.recommend());
// Rebase the second change
gApi.changes().id(r2.getChangeId()).rebase();
List<PatchSetApproval> patchSetApprovals = r2.getChange().notes().getApprovalsWithCopied().values().stream().sorted(comparing(a -> a.patchSetId().get())).collect(toImmutableList());
PatchSetApproval nonCopied = patchSetApprovals.get(0);
PatchSetApproval copied = patchSetApprovals.get(1);
assertCopied(nonCopied, 1, LabelId.CODE_REVIEW, (short) 1, /* copied= */
false);
assertCopied(copied, 2, LabelId.CODE_REVIEW, (short) 1, /* copied= */
true);
}
Aggregations