Merge "Return list of reviewers as part of ChangeInfo"
This commit is contained in:
commit
7afd302052
@ -209,8 +209,8 @@ default. Optional fields are:
|
||||
--
|
||||
* `DETAILED_LABELS`: detailed label information, including numeric
|
||||
values of all existing approvals, recognized label values, values
|
||||
permitted to be set by the current user, and reviewers that may be
|
||||
removed by the current user.
|
||||
permitted to be set by the current user, all reviewers by state, and
|
||||
reviewers that may be removed by the current user.
|
||||
--
|
||||
|
||||
[[current-revision]]
|
||||
@ -641,6 +641,22 @@ REJECTED > APPROVED > DISLIKED > RECOMMENDED.
|
||||
"username": "jroe"
|
||||
}
|
||||
],
|
||||
"reviewers": {
|
||||
"REVIEWER": [
|
||||
{
|
||||
"_account_id": 1000096,
|
||||
"name": "John Doe",
|
||||
"email": "john.doe@example.com",
|
||||
"username": "jdoe"
|
||||
},
|
||||
{
|
||||
"_account_id": 1000097,
|
||||
"name": "Jane Roe",
|
||||
"email": "jane.roe@example.com",
|
||||
"username": "jroe"
|
||||
}
|
||||
]
|
||||
},
|
||||
"messages": [
|
||||
{
|
||||
"id": "YH-egE",
|
||||
@ -1204,6 +1220,13 @@ The list consists of:
|
||||
"_account_id": 1000000
|
||||
}
|
||||
],
|
||||
"reviewers": {
|
||||
"REVIEWER": [
|
||||
{
|
||||
"_account_id": 1000000
|
||||
}
|
||||
]
|
||||
},
|
||||
"current_revision": "9adb9f4c7b40eeee0646e235de818d09164d7379",
|
||||
"revisions": {
|
||||
"9adb9f4c7b40eeee0646e235de818d09164d7379": {
|
||||
@ -1315,6 +1338,13 @@ The list consists of:
|
||||
"_account_id": 1000000
|
||||
}
|
||||
],
|
||||
"reviewers": {
|
||||
"REVIEWER": [
|
||||
{
|
||||
"_account_id": 1000000
|
||||
}
|
||||
]
|
||||
},
|
||||
"current_revision": "1bd7c12a38854a2c6de426feec28800623f492c4",
|
||||
"revisions": {
|
||||
"1bd7c12a38854a2c6de426feec28800623f492c4": {
|
||||
@ -2447,6 +2477,20 @@ for the current patch set.
|
||||
"email": "jane.roe@example.com"
|
||||
}
|
||||
],
|
||||
"reviewers": {
|
||||
"REVIEWER": [
|
||||
{
|
||||
"_account_id": 1000096,
|
||||
"name": "John Doe",
|
||||
"email": "john.doe@example.com"
|
||||
},
|
||||
{
|
||||
"_account_id": 1000097,
|
||||
"name": "Jane Roe",
|
||||
"email": "jane.roe@example.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
"current_revision": "674ac754f91e64a0efb8087e59a176484bd534d1",
|
||||
"revisions": {
|
||||
"674ac754f91e64a0efb8087e59a176484bd534d1": {
|
||||
@ -3884,6 +3928,15 @@ Only set if link:#detailed-labels[detailed labels] are requested.
|
||||
The reviewers that can be removed by the calling user as a list of
|
||||
link:rest-api-accounts.html#account-info[AccountInfo] entities. +
|
||||
Only set if link:#detailed-labels[detailed labels] are requested.
|
||||
|`reviewers` ||
|
||||
The reviewers as a map that maps a reviewer state to a list of
|
||||
link:rest-api-accounts.html#account-info[AccountInfo] entities.
|
||||
Possible reviewer states are `REVIEWER`, `CC` and `REMOVED`. +
|
||||
`REVIEWER`: Users with at least one non-zero vote on the change. +
|
||||
`CC`: Users that were added to the change, but have not voted. +
|
||||
`REMOVED`: Users that were previously reviewers on the change, but have
|
||||
been removed. +
|
||||
Only set if link:#detailed-labels[detailed labels] are requested.
|
||||
|`messages`|optional|
|
||||
Messages associated with the change as a list of
|
||||
link:#change-message-info[ChangeMessageInfo] entities. +
|
||||
|
@ -17,15 +17,16 @@ package com.google.gerrit.acceptance.api.change;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
|
||||
import static com.google.gerrit.acceptance.PushOneCommit.SUBJECT;
|
||||
import static com.google.gerrit.extensions.client.ReviewerState.CC;
|
||||
import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER;
|
||||
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
|
||||
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
|
||||
import static com.google.gerrit.server.project.Util.blockLabel;
|
||||
import static com.google.gerrit.server.project.Util.category;
|
||||
import static com.google.gerrit.server.project.Util.value;
|
||||
import static com.google.gerrit.testutil.GerritServerTests.isNoteDbTestEnabled;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gerrit.acceptance.AbstractDaemonTest;
|
||||
import com.google.gerrit.acceptance.NoHttpd;
|
||||
import com.google.gerrit.acceptance.PushOneCommit;
|
||||
@ -38,6 +39,7 @@ import com.google.gerrit.extensions.api.changes.ReviewInput;
|
||||
import com.google.gerrit.extensions.api.changes.RevisionApi;
|
||||
import com.google.gerrit.extensions.client.ChangeStatus;
|
||||
import com.google.gerrit.extensions.client.ListChangesOption;
|
||||
import com.google.gerrit.extensions.common.AccountInfo;
|
||||
import com.google.gerrit.extensions.common.ApprovalInfo;
|
||||
import com.google.gerrit.extensions.common.ChangeInfo;
|
||||
import com.google.gerrit.extensions.common.ChangeMessageInfo;
|
||||
@ -45,7 +47,6 @@ import com.google.gerrit.extensions.common.GitPerson;
|
||||
import com.google.gerrit.extensions.common.LabelInfo;
|
||||
import com.google.gerrit.extensions.common.RevisionInfo;
|
||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
@ -58,9 +59,10 @@ import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@NoHttpd
|
||||
public class ChangeIT extends AbstractDaemonTest {
|
||||
@ -297,17 +299,6 @@ public class ChangeIT extends AbstractDaemonTest {
|
||||
.rebase(ri);
|
||||
}
|
||||
|
||||
private Set<Account.Id> getReviewers(String changeId) throws Exception {
|
||||
ChangeInfo ci = gApi.changes().id(changeId).get();
|
||||
Set<Account.Id> result = Sets.newHashSet();
|
||||
for (LabelInfo li : ci.labels.values()) {
|
||||
for (ApprovalInfo ai : li.all) {
|
||||
result.add(new Account.Id(ai._accountId));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addReviewer() throws Exception {
|
||||
PushOneCommit.Result r = createChange();
|
||||
@ -317,8 +308,20 @@ public class ChangeIT extends AbstractDaemonTest {
|
||||
.id(r.getChangeId())
|
||||
.addReviewer(in);
|
||||
|
||||
assertThat(getReviewers(r.getChangeId()))
|
||||
.containsExactlyElementsIn(ImmutableSet.of(user.id));
|
||||
ChangeInfo c = gApi.changes()
|
||||
.id(r.getChangeId())
|
||||
.get();
|
||||
|
||||
// When notedb is enabled adding a reviewer records that user as reviewer
|
||||
// in notedb. When notedb is disabled adding a reviewer results in a dummy 0
|
||||
// approval on the change which is treated as CC when the ChangeInfo is
|
||||
// created.
|
||||
Collection<AccountInfo> reviewers = isNoteDbTestEnabled()
|
||||
? c.reviewers.get(REVIEWER)
|
||||
: c.reviewers.get(CC);
|
||||
assertThat(reviewers).hasSize(1);
|
||||
assertThat(reviewers.iterator().next()._accountId)
|
||||
.isEqualTo(user.getId().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -333,16 +336,46 @@ public class ChangeIT extends AbstractDaemonTest {
|
||||
.revision(r.getCommit().name())
|
||||
.submit();
|
||||
|
||||
assertThat(getReviewers(r.getChangeId()))
|
||||
.containsExactlyElementsIn(ImmutableSet.of(admin.getId()));
|
||||
ChangeInfo c = gApi.changes()
|
||||
.id(r.getChangeId())
|
||||
.get();
|
||||
Collection<AccountInfo> reviewers = c.reviewers.get(REVIEWER);
|
||||
assertThat(reviewers).hasSize(1);
|
||||
assertThat(reviewers.iterator().next()._accountId)
|
||||
.isEqualTo(admin.getId().get());
|
||||
assertThat(c.reviewers).doesNotContainKey(CC);
|
||||
|
||||
AddReviewerInput in = new AddReviewerInput();
|
||||
in.reviewer = user.email;
|
||||
gApi.changes()
|
||||
.id(r.getChangeId())
|
||||
.addReviewer(in);
|
||||
assertThat(getReviewers(r.getChangeId()))
|
||||
.containsExactlyElementsIn(ImmutableSet.of(admin.getId(), user.id));
|
||||
|
||||
c = gApi.changes()
|
||||
.id(r.getChangeId())
|
||||
.get();
|
||||
reviewers = c.reviewers.get(REVIEWER);
|
||||
if (isNoteDbTestEnabled()) {
|
||||
// When notedb is enabled adding a reviewer records that user as reviewer
|
||||
// in notedb.
|
||||
assertThat(reviewers).hasSize(2);
|
||||
Iterator<AccountInfo> reviewerIt = reviewers.iterator();
|
||||
assertThat(reviewerIt.next()._accountId)
|
||||
.isEqualTo(admin.getId().get());
|
||||
assertThat(reviewerIt.next()._accountId)
|
||||
.isEqualTo(user.getId().get());
|
||||
assertThat(c.reviewers).doesNotContainKey(CC);
|
||||
} else {
|
||||
// When notedb is disabled adding a reviewer results in a dummy 0 approval
|
||||
// on the change which is treated as CC when the ChangeInfo is created.
|
||||
assertThat(reviewers).hasSize(1);
|
||||
assertThat(reviewers.iterator().next()._accountId)
|
||||
.isEqualTo(admin.getId().get());
|
||||
Collection<AccountInfo> ccs = c.reviewers.get(CC);
|
||||
assertThat(ccs).hasSize(1);
|
||||
assertThat(ccs.iterator().next()._accountId)
|
||||
.isEqualTo(user.getId().get());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
// Copyright (C) 2015 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -12,28 +12,15 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.notedb;
|
||||
package com.google.gerrit.extensions.client;
|
||||
|
||||
import org.eclipse.jgit.revwalk.FooterKey;
|
||||
|
||||
/** State of a reviewer on a change. */
|
||||
public enum ReviewerState {
|
||||
/** The user has contributed at least one nonzero vote on the change. */
|
||||
REVIEWER(new FooterKey("Reviewer")),
|
||||
REVIEWER,
|
||||
|
||||
/** The reviewer was added to the change, but has not voted. */
|
||||
CC(new FooterKey("CC")),
|
||||
CC,
|
||||
|
||||
/** The user was previously a reviewer on the change, but was removed. */
|
||||
REMOVED(new FooterKey("Removed"));
|
||||
|
||||
private final FooterKey footerKey;
|
||||
|
||||
private ReviewerState(FooterKey footerKey) {
|
||||
this.footerKey = footerKey;
|
||||
}
|
||||
|
||||
FooterKey getFooterKey() {
|
||||
return footerKey;
|
||||
}
|
||||
REMOVED;
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.extensions.common;
|
||||
|
||||
import com.google.gerrit.extensions.client.ChangeStatus;
|
||||
import com.google.gerrit.extensions.client.ReviewerState;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Collection;
|
||||
@ -48,6 +49,7 @@ public class ChangeInfo {
|
||||
public Map<String, LabelInfo> labels;
|
||||
public Map<String, Collection<String>> permittedLabels;
|
||||
public Collection<AccountInfo> removableReviewers;
|
||||
public Map<ReviewerState, Collection<AccountInfo>> reviewers;
|
||||
public Collection<ChangeMessageInfo> messages;
|
||||
|
||||
public String currentRevision;
|
||||
|
@ -15,6 +15,8 @@
|
||||
package com.google.gerrit.server;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
@ -44,7 +46,7 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.notedb.NotesMigration;
|
||||
import com.google.gerrit.server.notedb.ReviewerState;
|
||||
import com.google.gerrit.server.notedb.ReviewerStateInternal;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
@ -114,10 +116,10 @@ public class ApprovalsUtil {
|
||||
* @param notes change notes.
|
||||
* @return multimap of reviewers keyed by state, where each account appears
|
||||
* exactly once in {@link SetMultimap#values()}, and
|
||||
* {@link ReviewerState#REMOVED} is not present.
|
||||
* {@link ReviewerStateInternal#REMOVED} is not present.
|
||||
* @throws OrmException if reviewers for the change could not be read.
|
||||
*/
|
||||
public ImmutableSetMultimap<ReviewerState, Account.Id> getReviewers(
|
||||
public ImmutableSetMultimap<ReviewerStateInternal, Account.Id> getReviewers(
|
||||
ReviewDb db, ChangeNotes notes) throws OrmException {
|
||||
if (!migration.readChanges()) {
|
||||
return getReviewers(db.patchSetApprovals().byChange(notes.getChangeId()));
|
||||
@ -132,9 +134,9 @@ public class ApprovalsUtil {
|
||||
* change.
|
||||
* @return multimap of reviewers keyed by state, where each account appears
|
||||
* exactly once in {@link SetMultimap#values()}, and
|
||||
* {@link ReviewerState#REMOVED} is not present.
|
||||
* {@link ReviewerStateInternal#REMOVED} is not present.
|
||||
*/
|
||||
public ImmutableSetMultimap<ReviewerState, Account.Id> getReviewers(
|
||||
public ImmutableSetMultimap<ReviewerStateInternal, Account.Id> getReviewers(
|
||||
ChangeNotes notes, Iterable<PatchSetApproval> allApprovals)
|
||||
throws OrmException {
|
||||
if (!migration.readChanges()) {
|
||||
@ -143,10 +145,10 @@ public class ApprovalsUtil {
|
||||
return notes.load().getReviewers();
|
||||
}
|
||||
|
||||
private static ImmutableSetMultimap<ReviewerState, Account.Id> getReviewers(
|
||||
private static ImmutableSetMultimap<ReviewerStateInternal, Account.Id> getReviewers(
|
||||
Iterable<PatchSetApproval> allApprovals) {
|
||||
PatchSetApproval first = null;
|
||||
SetMultimap<ReviewerState, Account.Id> reviewers =
|
||||
SetMultimap<ReviewerStateInternal, Account.Id> reviewers =
|
||||
LinkedHashMultimap.create();
|
||||
for (PatchSetApproval psa : allApprovals) {
|
||||
if (first == null) {
|
||||
@ -159,10 +161,10 @@ public class ApprovalsUtil {
|
||||
}
|
||||
Account.Id id = psa.getAccountId();
|
||||
if (psa.getValue() != 0) {
|
||||
reviewers.put(ReviewerState.REVIEWER, id);
|
||||
reviewers.remove(ReviewerState.CC, id);
|
||||
} else if (!reviewers.containsEntry(ReviewerState.REVIEWER, id)) {
|
||||
reviewers.put(ReviewerState.CC, id);
|
||||
reviewers.put(REVIEWER, id);
|
||||
reviewers.remove(CC, id);
|
||||
} else if (!reviewers.containsEntry(REVIEWER, id)) {
|
||||
reviewers.put(CC, id);
|
||||
}
|
||||
}
|
||||
return ImmutableSetMultimap.copyOf(reviewers);
|
||||
@ -215,7 +217,7 @@ public class ApprovalsUtil {
|
||||
cells.add(new PatchSetApproval(
|
||||
new PatchSetApproval.Key(psId, account, labelId),
|
||||
(short) 0, TimeUtil.nowTs()));
|
||||
update.putReviewer(account, ReviewerState.REVIEWER);
|
||||
update.putReviewer(account, REVIEWER);
|
||||
}
|
||||
db.patchSetApprovals().insert(cells);
|
||||
return Collections.unmodifiableList(cells);
|
||||
|
@ -40,6 +40,7 @@ import com.google.common.base.Joiner;
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
@ -48,6 +49,7 @@ import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Table;
|
||||
@ -94,6 +96,7 @@ import com.google.gerrit.server.api.accounts.GpgApiAdapter;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.LabelNormalizer;
|
||||
import com.google.gerrit.server.git.MergeUtil;
|
||||
import com.google.gerrit.server.notedb.ReviewerStateInternal;
|
||||
import com.google.gerrit.server.patch.PatchListNotAvailableException;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gerrit.server.project.ProjectCache;
|
||||
@ -118,7 +121,9 @@ import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -437,6 +442,13 @@ public class ChangeJson {
|
||||
out.permittedLabels = permittedLabels(ctl, cd);
|
||||
}
|
||||
out.removableReviewers = removableReviewers(ctl, out.labels.values());
|
||||
|
||||
out.reviewers = new HashMap<>();
|
||||
for (Map.Entry<ReviewerStateInternal, Collection<Account.Id>> e
|
||||
: cd.reviewers().asMap().entrySet()) {
|
||||
out.reviewers.put(e.getKey().asReviewerState(),
|
||||
toAccountInfo(e.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
boolean needMessages = has(MESSAGES);
|
||||
@ -828,6 +840,27 @@ public class ChangeJson {
|
||||
return result;
|
||||
}
|
||||
|
||||
private Collection<AccountInfo> toAccountInfo(
|
||||
Collection<Account.Id> accounts) {
|
||||
return FluentIterable.from(accounts)
|
||||
.transform(new Function<Account.Id, AccountInfo>() {
|
||||
@Override
|
||||
public AccountInfo apply(Account.Id id) {
|
||||
return accountLoader.get(id);
|
||||
}
|
||||
})
|
||||
.toSortedList(new Comparator<AccountInfo>() {
|
||||
@Override
|
||||
public int compare(AccountInfo a, AccountInfo b) {
|
||||
return ComparisonChain.start()
|
||||
.compare(a.name, b.name, Ordering.natural().nullsFirst())
|
||||
.compare(a.email, b.email, Ordering.natural().nullsFirst())
|
||||
.compare(a._accountId, b._accountId,
|
||||
Ordering.natural().nullsFirst()).result();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Map<String, RevisionInfo> revisions(ChangeControl ctl,
|
||||
Map<PatchSet.Id, PatchSet> map) throws PatchListNotAvailableException,
|
||||
GpgException, OrmException, IOException {
|
||||
|
@ -17,6 +17,8 @@ package com.google.gerrit.server.change;
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
|
||||
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.gerrit.common.ChangeHooks;
|
||||
@ -42,7 +44,7 @@ import com.google.gerrit.server.git.GroupCollector;
|
||||
import com.google.gerrit.server.git.validators.CommitValidationException;
|
||||
import com.google.gerrit.server.git.validators.CommitValidators;
|
||||
import com.google.gerrit.server.mail.ReplacePatchSetSender;
|
||||
import com.google.gerrit.server.notedb.ReviewerState;
|
||||
import com.google.gerrit.server.notedb.ReviewerStateInternal;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gerrit.server.project.ChangeModifiedException;
|
||||
@ -106,7 +108,7 @@ public class PatchSetInserter extends BatchUpdate.Op {
|
||||
private PatchSet patchSet;
|
||||
private PatchSetInfo patchSetInfo;
|
||||
private ChangeMessage changeMessage;
|
||||
private SetMultimap<ReviewerState, Account.Id> oldReviewers;
|
||||
private SetMultimap<ReviewerStateInternal, Account.Id> oldReviewers;
|
||||
|
||||
@AssistedInject
|
||||
public PatchSetInserter(ChangeHooks hooks,
|
||||
@ -280,8 +282,8 @@ public class PatchSetInserter extends BatchUpdate.Op {
|
||||
cm.setFrom(ctx.getUser().getAccountId());
|
||||
cm.setPatchSet(patchSet, patchSetInfo);
|
||||
cm.setChangeMessage(changeMessage);
|
||||
cm.addReviewers(oldReviewers.get(ReviewerState.REVIEWER));
|
||||
cm.addExtraCC(oldReviewers.get(ReviewerState.CC));
|
||||
cm.addReviewers(oldReviewers.get(REVIEWER));
|
||||
cm.addExtraCC(oldReviewers.get(CC));
|
||||
cm.send();
|
||||
} catch (Exception err) {
|
||||
log.error("Cannot send email for new patch set on change "
|
||||
|
@ -17,6 +17,7 @@ package com.google.gerrit.server.change;
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.gerrit.server.PatchLineCommentsUtil.setCommentRevId;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
@ -64,7 +65,6 @@ import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
|
||||
import com.google.gerrit.server.git.BatchUpdate.Context;
|
||||
import com.google.gerrit.server.git.UpdateException;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.notedb.ReviewerState;
|
||||
import com.google.gerrit.server.patch.PatchListCache;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gerrit.server.query.change.ChangeData;
|
||||
@ -549,7 +549,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
|
||||
ups.add(c);
|
||||
addLabelDelta(normName, c.getValue());
|
||||
categories.put(normName, c.getValue());
|
||||
update.putReviewer(user.getAccountId(), ReviewerState.REVIEWER);
|
||||
update.putReviewer(user.getAccountId(), REVIEWER);
|
||||
update.putApproval(ent.getKey(), ent.getValue());
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.server.git;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
|
||||
import static org.eclipse.jgit.lib.RefDatabase.ALL;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
@ -61,7 +62,6 @@ import com.google.gerrit.server.git.validators.MergeValidators;
|
||||
import com.google.gerrit.server.index.ChangeIndexer;
|
||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.notedb.ReviewerState;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
@ -1053,7 +1053,7 @@ public class MergeOp {
|
||||
|
||||
logDebug("Add approval for " + cd + " from user " + user);
|
||||
ChangeUpdate update = updateFactory.create(control, timestamp);
|
||||
update.putReviewer(user.getAccountId(), ReviewerState.REVIEWER);
|
||||
update.putReviewer(user.getAccountId(), REVIEWER);
|
||||
List<SubmitRecord> record = records.get(cd.change().getId());
|
||||
if (record != null) {
|
||||
update.merge(record);
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
package com.google.gerrit.server.mail;
|
||||
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
|
||||
|
||||
import com.google.gerrit.common.errors.EmailException;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
@ -26,7 +28,6 @@ import com.google.gerrit.reviewdb.client.PatchSetInfo;
|
||||
import com.google.gerrit.reviewdb.client.StarredChange;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.mail.ProjectWatch.Watchers;
|
||||
import com.google.gerrit.server.notedb.ReviewerState;
|
||||
import com.google.gerrit.server.patch.PatchList;
|
||||
import com.google.gerrit.server.patch.PatchListEntry;
|
||||
import com.google.gerrit.server.patch.PatchListNotAvailableException;
|
||||
@ -329,7 +330,7 @@ public abstract class ChangeEmail extends NotificationEmail {
|
||||
/** Users who have non-zero approval codes on the change. */
|
||||
protected void ccExistingReviewers() {
|
||||
try {
|
||||
for (Account.Id id : changeData.reviewers().get(ReviewerState.REVIEWER)) {
|
||||
for (Account.Id id : changeData.reviewers().get(REVIEWER)) {
|
||||
add(RecipientType.CC, id);
|
||||
}
|
||||
} catch (OrmException err) {
|
||||
|
@ -14,13 +14,16 @@
|
||||
|
||||
package com.google.gerrit.server.mail;
|
||||
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.gerrit.common.FooterConstants;
|
||||
import com.google.gerrit.common.errors.NoSuchAccountException;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.server.account.AccountResolver;
|
||||
import com.google.gerrit.server.notedb.ReviewerState;
|
||||
import com.google.gerrit.server.notedb.ReviewerStateInternal;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
|
||||
import org.eclipse.jgit.revwalk.FooterKey;
|
||||
@ -56,10 +59,10 @@ public class MailUtil {
|
||||
}
|
||||
|
||||
public static MailRecipients getRecipientsFromReviewers(
|
||||
Multimap<ReviewerState, Account.Id> reviewers) {
|
||||
Multimap<ReviewerStateInternal, Account.Id> reviewers) {
|
||||
MailRecipients recipients = new MailRecipients();
|
||||
recipients.reviewers.addAll(reviewers.get(ReviewerState.REVIEWER));
|
||||
recipients.cc.addAll(reviewers.get(ReviewerState.CC));
|
||||
recipients.reviewers.addAll(reviewers.get(REVIEWER));
|
||||
recipients.cc.addAll(reviewers.get(CC));
|
||||
return recipients;
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
||||
|
||||
private final Change change;
|
||||
private ImmutableListMultimap<PatchSet.Id, PatchSetApproval> approvals;
|
||||
private ImmutableSetMultimap<ReviewerState, Account.Id> reviewers;
|
||||
private ImmutableSetMultimap<ReviewerStateInternal, Account.Id> reviewers;
|
||||
private ImmutableList<Account.Id> allPastReviewers;
|
||||
private ImmutableList<SubmitRecord> submitRecords;
|
||||
private ImmutableList<ChangeMessage> allChangeMessages;
|
||||
@ -144,7 +144,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
||||
return approvals;
|
||||
}
|
||||
|
||||
public ImmutableSetMultimap<ReviewerState, Account.Id> getReviewers() {
|
||||
public ImmutableSetMultimap<ReviewerStateInternal, Account.Id> getReviewers() {
|
||||
return reviewers;
|
||||
}
|
||||
|
||||
@ -270,9 +270,9 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
||||
} else {
|
||||
hashtags = ImmutableSet.of();
|
||||
}
|
||||
ImmutableSetMultimap.Builder<ReviewerState, Account.Id> reviewers =
|
||||
ImmutableSetMultimap.Builder<ReviewerStateInternal, Account.Id> reviewers =
|
||||
ImmutableSetMultimap.builder();
|
||||
for (Map.Entry<Account.Id, ReviewerState> e
|
||||
for (Map.Entry<Account.Id, ReviewerStateInternal> e
|
||||
: parser.reviewers.entrySet()) {
|
||||
reviewers.put(e.getValue(), e.getKey());
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
class ChangeNotesParser implements AutoCloseable {
|
||||
final Map<Account.Id, ReviewerState> reviewers;
|
||||
final Map<Account.Id, ReviewerStateInternal> reviewers;
|
||||
final List<Account.Id> allPastReviewers;
|
||||
final List<SubmitRecord> submitRecords;
|
||||
final Multimap<RevId, PatchLineComment> comments;
|
||||
@ -168,7 +168,7 @@ class ChangeNotesParser implements AutoCloseable {
|
||||
parseApproval(psId, accountId, commit, line);
|
||||
}
|
||||
|
||||
for (ReviewerState state : ReviewerState.values()) {
|
||||
for (ReviewerStateInternal state : ReviewerStateInternal.values()) {
|
||||
for (String line : commit.getFooterLines(state.getFooterKey())) {
|
||||
parseReviewer(state, line);
|
||||
}
|
||||
@ -394,7 +394,7 @@ class ChangeNotesParser implements AutoCloseable {
|
||||
GERRIT_PLACEHOLDER_HOST, email);
|
||||
}
|
||||
|
||||
private void parseReviewer(ReviewerState state, String line)
|
||||
private void parseReviewer(ReviewerStateInternal state, String line)
|
||||
throws ConfigInvalidException {
|
||||
PersonIdent ident = RawParseUtils.parsePersonIdent(line);
|
||||
if (ident == null) {
|
||||
@ -407,11 +407,11 @@ class ChangeNotesParser implements AutoCloseable {
|
||||
}
|
||||
|
||||
private void pruneReviewers() {
|
||||
Iterator<Map.Entry<Account.Id, ReviewerState>> rit =
|
||||
Iterator<Map.Entry<Account.Id, ReviewerStateInternal>> rit =
|
||||
reviewers.entrySet().iterator();
|
||||
while (rit.hasNext()) {
|
||||
Map.Entry<Account.Id, ReviewerState> e = rit.next();
|
||||
if (e.getValue() == ReviewerState.REMOVED) {
|
||||
Map.Entry<Account.Id, ReviewerStateInternal> e = rit.next();
|
||||
if (e.getValue() == ReviewerStateInternal.REMOVED) {
|
||||
rit.remove();
|
||||
for (Table<Account.Id, ?, ?> curr : approvals.values()) {
|
||||
curr.rowKeySet().remove(e.getKey());
|
||||
|
@ -86,7 +86,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
|
||||
|
||||
private final AccountCache accountCache;
|
||||
private final Map<String, Optional<Short>> approvals;
|
||||
private final Map<Account.Id, ReviewerState> reviewers;
|
||||
private final Map<Account.Id, ReviewerStateInternal> reviewers;
|
||||
private Change.Status status;
|
||||
private String subject;
|
||||
private List<SubmitRecord> submitRecords;
|
||||
@ -320,13 +320,13 @@ public class ChangeUpdate extends AbstractChangeUpdate {
|
||||
this.hashtags = hashtags;
|
||||
}
|
||||
|
||||
public void putReviewer(Account.Id reviewer, ReviewerState type) {
|
||||
checkArgument(type != ReviewerState.REMOVED, "invalid ReviewerType");
|
||||
public void putReviewer(Account.Id reviewer, ReviewerStateInternal type) {
|
||||
checkArgument(type != ReviewerStateInternal.REMOVED, "invalid ReviewerType");
|
||||
reviewers.put(reviewer, type);
|
||||
}
|
||||
|
||||
public void removeReviewer(Account.Id reviewer) {
|
||||
reviewers.put(reviewer, ReviewerState.REMOVED);
|
||||
reviewers.put(reviewer, ReviewerStateInternal.REMOVED);
|
||||
}
|
||||
|
||||
/** @return the tree id for the updated tree */
|
||||
@ -422,7 +422,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
|
||||
addFooter(msg, FOOTER_HASHTAGS, Joiner.on(",").join(hashtags));
|
||||
}
|
||||
|
||||
for (Map.Entry<Account.Id, ReviewerState> e : reviewers.entrySet()) {
|
||||
for (Map.Entry<Account.Id, ReviewerStateInternal> e : reviewers.entrySet()) {
|
||||
Account account = accountCache.get(e.getKey()).getAccount();
|
||||
PersonIdent ident = newIdent(account, when);
|
||||
addFooter(msg, e.getValue().getFooterKey())
|
||||
|
@ -0,0 +1,64 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.notedb;
|
||||
|
||||
import com.google.gerrit.extensions.client.ReviewerState;
|
||||
|
||||
import org.eclipse.jgit.revwalk.FooterKey;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/** State of a reviewer on a change. */
|
||||
public enum ReviewerStateInternal {
|
||||
/** The user has contributed at least one nonzero vote on the change. */
|
||||
REVIEWER(new FooterKey("Reviewer"), ReviewerState.REVIEWER),
|
||||
|
||||
/** The reviewer was added to the change, but has not voted. */
|
||||
CC(new FooterKey("CC"), ReviewerState.CC),
|
||||
|
||||
/** The user was previously a reviewer on the change, but was removed. */
|
||||
REMOVED(new FooterKey("Removed"), ReviewerState.REMOVED);
|
||||
|
||||
static {
|
||||
boolean ok = true;
|
||||
if (ReviewerStateInternal.values().length != ReviewerState.values().length) {
|
||||
ok = false;
|
||||
}
|
||||
for (ReviewerStateInternal s : ReviewerStateInternal.values()) {
|
||||
ok &= s.name().equals(s.state.name());
|
||||
}
|
||||
if (!ok) {
|
||||
throw new IllegalStateException("Mismatched reviewer state mapping: "
|
||||
+ Arrays.asList(ReviewerStateInternal.values()) + " != "
|
||||
+ Arrays.asList(ReviewerState.values()));
|
||||
}
|
||||
}
|
||||
|
||||
private final FooterKey footerKey;
|
||||
private final ReviewerState state;
|
||||
|
||||
private ReviewerStateInternal(FooterKey footerKey, ReviewerState state) {
|
||||
this.footerKey = footerKey;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
FooterKey getFooterKey() {
|
||||
return footerKey;
|
||||
}
|
||||
|
||||
public ReviewerState asReviewerState() {
|
||||
return state;
|
||||
}
|
||||
}
|
@ -45,7 +45,7 @@ import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.MergeUtil;
|
||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||
import com.google.gerrit.server.notedb.NotesMigration;
|
||||
import com.google.gerrit.server.notedb.ReviewerState;
|
||||
import com.google.gerrit.server.notedb.ReviewerStateInternal;
|
||||
import com.google.gerrit.server.patch.PatchList;
|
||||
import com.google.gerrit.server.patch.PatchListCache;
|
||||
import com.google.gerrit.server.patch.PatchListEntry;
|
||||
@ -707,7 +707,7 @@ public class ChangeData {
|
||||
return allApprovals;
|
||||
}
|
||||
|
||||
public SetMultimap<ReviewerState, Account.Id> reviewers()
|
||||
public SetMultimap<ReviewerStateInternal, Account.Id> reviewers()
|
||||
throws OrmException {
|
||||
return approvalsUtil.getReviewers(notes(), approvals().values());
|
||||
}
|
||||
|
@ -15,8 +15,8 @@
|
||||
package com.google.gerrit.server.notedb;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.gerrit.server.notedb.ReviewerState.CC;
|
||||
import static com.google.gerrit.server.notedb.ReviewerState.REVIEWER;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
|
||||
import static com.google.gerrit.testutil.TestChanges.incrementPatchSet;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
|
@ -15,8 +15,8 @@
|
||||
package com.google.gerrit.server.notedb;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.gerrit.server.notedb.ReviewerState.CC;
|
||||
import static com.google.gerrit.server.notedb.ReviewerState.REVIEWER;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC;
|
||||
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gerrit.common.TimeUtil;
|
||||
|
Loading…
Reference in New Issue
Block a user