Merge "Merge branch 'stable-2.15' into stable-2.16" into stable-2.16

This commit is contained in:
David Pursehouse
2019-02-08 01:44:40 +00:00
committed by Gerrit Code Review
8 changed files with 129 additions and 6 deletions

View File

@@ -12,6 +12,7 @@ Bruce Zu <bruce.zu.run10@gmail.com>
Carlos Eduardo Baldacin <carloseduardo.baldacin@sonyericsson.com> carloseduardo.baldacin <carloseduardo.baldacin@sonyericsson.com> Carlos Eduardo Baldacin <carloseduardo.baldacin@sonyericsson.com> carloseduardo.baldacin <carloseduardo.baldacin@sonyericsson.com>
Changcheng Xiao <xchangcheng@google.com> xchangcheng Changcheng Xiao <xchangcheng@google.com> xchangcheng
Dariusz Luksza <dluksza@collab.net> <dariusz@luksza.org> Dariusz Luksza <dluksza@collab.net> <dariusz@luksza.org>
Darrien Glasser <darrien@arista.com> darrien <darrien@arista.com>
Dave Borowitz <dborowitz@google.com> <dborowitz@google.com> Dave Borowitz <dborowitz@google.com> <dborowitz@google.com>
David Ostrovsky <david@ostrovsky.org> <d.ostrovsky@gmx.de> David Ostrovsky <david@ostrovsky.org> <d.ostrovsky@gmx.de>
David Ostrovsky <david@ostrovsky.org> <david.ostrovsky@gmail.com> David Ostrovsky <david@ostrovsky.org> <david.ostrovsky@gmail.com>

View File

@@ -21,7 +21,7 @@ _ssh_ -p <port> <host> _gerrit review_
[--verified <N>] [--code-review <N>] [--verified <N>] [--code-review <N>]
[--label Label-Name=<N>] [--label Label-Name=<N>]
[--tag TAG] [--tag TAG]
{COMMIT | CHANGEID,PATCHSET}... {COMMIT | CHANGENUMBER,PATCHSET}...
-- --
== DESCRIPTION == DESCRIPTION
@@ -147,16 +147,21 @@ Approve the change with commit c0ff33 as "Verified +1"
$ ssh -p 29418 review.example.com gerrit review --verified +1 c0ff33 $ ssh -p 29418 review.example.com gerrit review --verified +1 c0ff33
---- ----
Approve the change with change number 8242 and patch set 2 as "Code-Review +2"
----
$ ssh -p 29418 review.example.com gerrit review --code-review +2 8242,2
----
Vote on the project specific label "mylabel": Vote on the project specific label "mylabel":
---- ----
$ ssh -p 29418 review.example.com gerrit review --label mylabel=+1 c0ff33 $ ssh -p 29418 review.example.com gerrit review --label mylabel=+1 8242,2
---- ----
Append the message "Build Successful". Notice two levels of quoting is Append the message "Build Successful". Notice two levels of quoting is
required, one for the local shell, and another for the argument parser required, one for the local shell, and another for the argument parser
inside the Gerrit server: inside the Gerrit server:
---- ----
$ ssh -p 29418 review.example.com gerrit review -m '"Build Successful"' c0ff33 $ ssh -p 29418 review.example.com gerrit review -m '"Build Successful"' 8242,2
---- ----
Mark the unmerged commits both "Verified +1" and "Code-Review +2" and Mark the unmerged commits both "Verified +1" and "Code-Review +2" and
@@ -172,7 +177,7 @@ $ ssh -p 29418 review.example.com gerrit review \
Abandon an active change: Abandon an active change:
---- ----
$ ssh -p 29418 review.example.com gerrit review --abandon c0ff33 $ ssh -p 29418 review.example.com gerrit review --abandon 8242,2
---- ----
== SEE ALSO == SEE ALSO

View File

@@ -14,8 +14,10 @@
package com.google.gerrit.extensions.api.changes; package com.google.gerrit.extensions.api.changes;
import com.google.common.collect.ListMultimap;
import com.google.gerrit.extensions.client.SubmitType; import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.ActionInfo; import com.google.gerrit.extensions.common.ActionInfo;
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.CherryPickChangeInfo; import com.google.gerrit.extensions.common.CherryPickChangeInfo;
import com.google.gerrit.extensions.common.CommentInfo; import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.CommitInfo; import com.google.gerrit.extensions.common.CommitInfo;
@@ -135,6 +137,9 @@ public interface RevisionApi {
RelatedChangesInfo related() throws RestApiException; RelatedChangesInfo related() throws RestApiException;
/** Returns votes on the revision. */
ListMultimap<String, ApprovalInfo> votes() throws RestApiException;
abstract class MergeListRequest { abstract class MergeListRequest {
private boolean addLinks; private boolean addLinks;
private int uninterestingParent = 1; private int uninterestingParent = 1;
@@ -377,6 +382,11 @@ public interface RevisionApi {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@Override
public ListMultimap<String, ApprovalInfo> votes() throws RestApiException {
throw new NotImplementedException();
}
@Override @Override
public void description(String description) throws RestApiException { public void description(String description) throws RestApiException {
throw new NotImplementedException(); throw new NotImplementedException();

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.extensions.common; package com.google.gerrit.extensions.common;
import com.google.gerrit.common.Nullable;
import java.sql.Timestamp; import java.sql.Timestamp;
public class ApprovalInfo extends AccountInfo { public class ApprovalInfo extends AccountInfo {
@@ -28,7 +29,11 @@ public class ApprovalInfo extends AccountInfo {
} }
public ApprovalInfo( public ApprovalInfo(
Integer id, Integer value, VotingRangeInfo permittedVotingRange, String tag, Timestamp date) { Integer id,
Integer value,
@Nullable VotingRangeInfo permittedVotingRange,
@Nullable String tag,
Timestamp date) {
super(id); super(id);
this.value = value; this.value = value;
this.permittedVotingRange = permittedVotingRange; this.permittedVotingRange = permittedVotingRange;

View File

@@ -14,11 +14,13 @@
package com.google.gerrit.pgm; package com.google.gerrit.pgm;
import static com.google.gerrit.common.Version.getVersion;
import static com.google.gerrit.server.schema.DataSourceProvider.Context.MULTI_USER; import static com.google.gerrit.server.schema.DataSourceProvider.Context.MULTI_USER;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable; import com.google.gerrit.common.Nullable;
@@ -388,7 +390,15 @@ public class Daemon extends SiteProgram {
} }
private String myVersion() { private String myVersion() {
return com.google.gerrit.common.Version.getVersion(); List<String> versionParts = new ArrayList<>();
if (slave) {
versionParts.add("[slave]");
}
if (headless) {
versionParts.add("[headless]");
}
versionParts.add(getVersion());
return Joiner.on(" ").join(versionParts);
} }
private Injector createCfgInjector() { private Injector createCfgInjector() {

View File

@@ -18,6 +18,8 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.gerrit.server.api.ApiUtil.asRestApiException; import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.MultimapBuilder.ListMultimapBuilder;
import com.google.gerrit.extensions.api.changes.ChangeApi; import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.Changes; import com.google.gerrit.extensions.api.changes.Changes;
import com.google.gerrit.extensions.api.changes.CherryPickInput; import com.google.gerrit.extensions.api.changes.CherryPickInput;
@@ -35,6 +37,7 @@ import com.google.gerrit.extensions.api.changes.RobotCommentApi;
import com.google.gerrit.extensions.api.changes.SubmitInput; import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.client.SubmitType; import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.ActionInfo; import com.google.gerrit.extensions.common.ActionInfo;
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.CherryPickChangeInfo; import com.google.gerrit.extensions.common.CherryPickChangeInfo;
import com.google.gerrit.extensions.common.CommentInfo; import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.CommitInfo; import com.google.gerrit.extensions.common.CommitInfo;
@@ -50,6 +53,11 @@ import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.IdString; import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView; import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.account.AccountDirectory.FillOptions;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.change.FileResource; import com.google.gerrit.server.change.FileResource;
import com.google.gerrit.server.change.RebaseUtil; import com.google.gerrit.server.change.RebaseUtil;
import com.google.gerrit.server.change.RevisionResource; import com.google.gerrit.server.change.RevisionResource;
@@ -84,6 +92,7 @@ import com.google.gerrit.server.restapi.change.TestSubmitType;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -134,6 +143,9 @@ class RevisionApiImpl implements RevisionApi {
private final GetRelated getRelated; private final GetRelated getRelated;
private final PutDescription putDescription; private final PutDescription putDescription;
private final GetDescription getDescription; private final GetDescription getDescription;
private final ApprovalsUtil approvalsUtil;
private final Provider<ReviewDb> db;
private final AccountLoader.Factory accountLoaderFactory;
@Inject @Inject
RevisionApiImpl( RevisionApiImpl(
@@ -175,6 +187,9 @@ class RevisionApiImpl implements RevisionApi {
GetRelated getRelated, GetRelated getRelated,
PutDescription putDescription, PutDescription putDescription,
GetDescription getDescription, GetDescription getDescription,
ApprovalsUtil approvalsUtil,
Provider<ReviewDb> db,
AccountLoader.Factory accountLoaderFactory,
@Assisted RevisionResource r) { @Assisted RevisionResource r) {
this.repoManager = repoManager; this.repoManager = repoManager;
this.changes = changes; this.changes = changes;
@@ -214,6 +229,9 @@ class RevisionApiImpl implements RevisionApi {
this.getRelated = getRelated; this.getRelated = getRelated;
this.putDescription = putDescription; this.putDescription = putDescription;
this.getDescription = getDescription; this.getDescription = getDescription;
this.approvalsUtil = approvalsUtil;
this.db = db;
this.accountLoaderFactory = accountLoaderFactory;
this.revision = r; this.revision = r;
} }
@@ -603,6 +621,37 @@ class RevisionApiImpl implements RevisionApi {
} }
} }
@Override
public ListMultimap<String, ApprovalInfo> votes() throws RestApiException {
ListMultimap<String, ApprovalInfo> result =
ListMultimapBuilder.treeKeys().arrayListValues().build();
try {
Iterable<PatchSetApproval> approvals =
approvalsUtil.byPatchSet(
db.get(), revision.getNotes(), revision.getPatchSet().getId(), null, null);
AccountLoader accountLoader =
accountLoaderFactory.create(
EnumSet.of(
FillOptions.ID, FillOptions.NAME, FillOptions.EMAIL, FillOptions.USERNAME));
for (PatchSetApproval approval : approvals) {
String label = approval.getLabel();
ApprovalInfo info =
new ApprovalInfo(
approval.getAccountId().get(),
Integer.valueOf(approval.getValue()),
null,
approval.getTag(),
approval.getGranted());
accountLoader.put(info);
result.get(label).add(info);
}
accountLoader.fill();
} catch (Exception e) {
throw asRestApiException("Cannot get votes", e);
}
return result;
}
@Override @Override
public void description(String description) throws RestApiException { public void description(String description) throws RestApiException {
DescriptionInput in = new DescriptionInput(); DescriptionInput in = new DescriptionInput();

View File

@@ -35,6 +35,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators; import com.google.common.collect.Iterators;
import com.google.common.collect.ListMultimap;
import com.google.gerrit.acceptance.AbstractDaemonTest; import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit; import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse; import com.google.gerrit.acceptance.RestResponse;
@@ -1475,6 +1476,47 @@ public class RevisionIT extends AbstractDaemonTest {
.containsExactlyElementsIn(ImmutableSet.of(admin.getId(), user.getId())); .containsExactlyElementsIn(ImmutableSet.of(admin.getId(), user.getId()));
} }
@Test
public void listVotesByRevision() throws Exception {
// Create patch set 1 and vote on it
String changeId = createChange().getChangeId();
ListMultimap<String, ApprovalInfo> votes = gApi.changes().id(changeId).current().votes();
assertThat(votes).isEmpty();
recommend(changeId);
votes = gApi.changes().id(changeId).current().votes();
assertThat(votes.keySet()).containsExactly("Code-Review");
List<ApprovalInfo> approvals = votes.get("Code-Review");
assertThat(approvals).hasSize(1);
ApprovalInfo approval = approvals.get(0);
assertThat(approval._accountId).isEqualTo(admin.id.get());
assertThat(approval.email).isEqualTo(admin.email);
assertThat(approval.username).isEqualTo(admin.username);
// Also vote on it with another user
setApiUser(user);
gApi.changes().id(changeId).current().review(ReviewInput.dislike());
// Patch set 1 has 2 votes on Code-Review
setApiUser(admin);
votes = gApi.changes().id(changeId).current().votes();
assertThat(votes.keySet()).containsExactly("Code-Review");
approvals = votes.get("Code-Review");
assertThat(approvals).hasSize(2);
assertThat(approvals.stream().map(a -> a._accountId))
.containsExactlyElementsIn(ImmutableList.of(admin.id.get(), user.id.get()));
// Create a new patch set which does not have any votes
amendChange(changeId);
votes = gApi.changes().id(changeId).current().votes();
assertThat(votes).isEmpty();
// Votes are still returned for ps 1
votes = gApi.changes().id(changeId).revision(1).votes();
assertThat(votes.keySet()).containsExactly("Code-Review");
approvals = votes.get("Code-Review");
assertThat(approvals).hasSize(2);
}
private static void assertCherryPickResult( private static void assertCherryPickResult(
ChangeInfo changeInfo, CherryPickInput input, String srcChangeId) throws Exception { ChangeInfo changeInfo, CherryPickInput input, String srcChangeId) throws Exception {
assertThat(changeInfo.changeId).isEqualTo(srcChangeId); assertThat(changeInfo.changeId).isEqualTo(srcChangeId);

View File

@@ -63,6 +63,7 @@
"object-shorthand": ["error", "always"], "object-shorthand": ["error", "always"],
"prefer-arrow-callback": "error", "prefer-arrow-callback": "error",
"prefer-const": "error", "prefer-const": "error",
"prefer-promise-reject-errors": "off",
"prefer-spread": "error", "prefer-spread": "error",
"quote-props": ["error", "consistent-as-needed"], "quote-props": ["error", "consistent-as-needed"],
"require-jsdoc": "off", "require-jsdoc": "off",