Add --json option to review SSH command
Add --json option to review SSH command for posting code review, message and inline comments via SSH. Command reads the review input from text file in JSON format, that corresponds to REST's ReviewInput entity: $ cat review.json | ssh host gerrit review --json <SHA1> Bug: Issue 602 Change-Id: I7e6f84b878b835cb7ea144cddd99702116d69b57
This commit is contained in:
parent
e985c14c30
commit
42a7d2dc64
@ -14,6 +14,7 @@ gerrit review - Apply reviews to one or more patch sets
|
|||||||
[--submit | -s]
|
[--submit | -s]
|
||||||
[--abandon | --restore]
|
[--abandon | --restore]
|
||||||
[--publish]
|
[--publish]
|
||||||
|
[--json | -j]
|
||||||
[--delete]
|
[--delete]
|
||||||
[--verified <N>] [--code-review <N>]
|
[--verified <N>] [--code-review <N>]
|
||||||
[--label Label-Name=<N>]
|
[--label Label-Name=<N>]
|
||||||
@ -56,6 +57,12 @@ branch.
|
|||||||
Optional cover letter to include as part of the message
|
Optional cover letter to include as part of the message
|
||||||
sent to reviewers when the approval states are updated.
|
sent to reviewers when the approval states are updated.
|
||||||
|
|
||||||
|
--json::
|
||||||
|
-j::
|
||||||
|
Read review input from JSON file. See
|
||||||
|
link:rest-api-changes.html#review-input[ReviewInput] entity for the
|
||||||
|
format.
|
||||||
|
|
||||||
--notify::
|
--notify::
|
||||||
-n::
|
-n::
|
||||||
Who to send email notifications to after the review is stored.
|
Who to send email notifications to after the review is stored.
|
||||||
|
@ -16,6 +16,7 @@ package com.google.gerrit.sshd.commands;
|
|||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.io.CharStreams;
|
||||||
import com.google.gerrit.common.data.LabelType;
|
import com.google.gerrit.common.data.LabelType;
|
||||||
import com.google.gerrit.common.data.LabelValue;
|
import com.google.gerrit.common.data.LabelValue;
|
||||||
import com.google.gerrit.extensions.api.GerritApi;
|
import com.google.gerrit.extensions.api.GerritApi;
|
||||||
@ -30,8 +31,8 @@ import com.google.gerrit.reviewdb.client.Change;
|
|||||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
import com.google.gerrit.reviewdb.client.RevId;
|
import com.google.gerrit.reviewdb.client.RevId;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.server.OutputFormat;
|
||||||
import com.google.gerrit.server.config.AllProjectsName;
|
import com.google.gerrit.server.config.AllProjectsName;
|
||||||
import com.google.gerrit.server.project.InvalidChangeOperationException;
|
|
||||||
import com.google.gerrit.server.project.NoSuchChangeException;
|
import com.google.gerrit.server.project.NoSuchChangeException;
|
||||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||||
import com.google.gerrit.server.project.ProjectControl;
|
import com.google.gerrit.server.project.ProjectControl;
|
||||||
@ -39,6 +40,7 @@ import com.google.gerrit.server.util.LabelVote;
|
|||||||
import com.google.gerrit.sshd.CommandMetaData;
|
import com.google.gerrit.sshd.CommandMetaData;
|
||||||
import com.google.gerrit.sshd.SshCommand;
|
import com.google.gerrit.sshd.SshCommand;
|
||||||
import com.google.gerrit.util.cli.CmdLineParser;
|
import com.google.gerrit.util.cli.CmdLineParser;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.gwtorm.server.ResultSet;
|
import com.google.gwtorm.server.ResultSet;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
@ -50,6 +52,8 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -110,6 +114,9 @@ public class ReviewCommand extends SshCommand {
|
|||||||
@Option(name = "--delete", usage = "delete the specified draft patch set(s)")
|
@Option(name = "--delete", usage = "delete the specified draft patch set(s)")
|
||||||
private boolean deleteDraftPatchSet;
|
private boolean deleteDraftPatchSet;
|
||||||
|
|
||||||
|
@Option(name = "--json", aliases = "-j", usage = "read review input json from stdin")
|
||||||
|
private boolean json;
|
||||||
|
|
||||||
@Option(name = "--label", aliases = "-l", usage = "custom label(s) to assign", metaVar = "LABEL=VALUE")
|
@Option(name = "--label", aliases = "-l", usage = "custom label(s) to assign", metaVar = "LABEL=VALUE")
|
||||||
void addLabel(final String token) {
|
void addLabel(final String token) {
|
||||||
LabelVote v = LabelVote.parseWithEquals(token);
|
LabelVote v = LabelVote.parseWithEquals(token);
|
||||||
@ -159,12 +166,41 @@ public class ReviewCommand extends SshCommand {
|
|||||||
throw error("publish and delete actions are mutually exclusive");
|
throw error("publish and delete actions are mutually exclusive");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (json) {
|
||||||
|
if (restoreChange) {
|
||||||
|
throw error("json and restore actions are mutually exclusive");
|
||||||
|
}
|
||||||
|
if (submitChange) {
|
||||||
|
throw error("json and submit actions are mutually exclusive");
|
||||||
|
}
|
||||||
|
if (deleteDraftPatchSet) {
|
||||||
|
throw error("json and delete actions are mutually exclusive");
|
||||||
|
}
|
||||||
|
if (publishPatchSet) {
|
||||||
|
throw error("json and publish actions are mutually exclusive");
|
||||||
|
}
|
||||||
|
if (abandonChange) {
|
||||||
|
throw error("json and abandon actions are mutually exclusive");
|
||||||
|
}
|
||||||
|
if (changeComment != null) {
|
||||||
|
throw error("json and message are mutually exclusive");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
|
ReviewInput input = null;
|
||||||
|
if (json) {
|
||||||
|
input = reviewFromJson();
|
||||||
|
}
|
||||||
|
|
||||||
for (final PatchSet patchSet : patchSets) {
|
for (final PatchSet patchSet : patchSets) {
|
||||||
try {
|
try {
|
||||||
reviewPatchSet(patchSet);
|
if (input != null) {
|
||||||
} catch (UnloggedFailure e) {
|
applyReview(patchSet, input);
|
||||||
|
} else {
|
||||||
|
reviewPatchSet(patchSet);
|
||||||
|
}
|
||||||
|
} catch (RestApiException | UnloggedFailure e) {
|
||||||
ok = false;
|
ok = false;
|
||||||
writeError("error: " + e.getMessage() + "\n");
|
writeError("error: " + e.getMessage() + "\n");
|
||||||
} catch (NoSuchChangeException e) {
|
} catch (NoSuchChangeException e) {
|
||||||
@ -179,21 +215,30 @@ public class ReviewCommand extends SshCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
throw new UnloggedFailure(1, "one or more reviews failed;"
|
throw error("one or more reviews failed; review output above");
|
||||||
+ " review output above");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyReview(PatchSet patchSet,
|
private void applyReview(PatchSet patchSet,
|
||||||
final ReviewInput review) throws Exception {
|
final ReviewInput review) throws RestApiException {
|
||||||
gApi.get().changes()
|
gApi.get().changes()
|
||||||
.id(patchSet.getId().getParentKey().get())
|
.id(patchSet.getId().getParentKey().get())
|
||||||
.revision(patchSet.getRevision().get())
|
.revision(patchSet.getRevision().get())
|
||||||
.review(review);
|
.review(review);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reviewPatchSet(final PatchSet patchSet) throws Exception {
|
private ReviewInput reviewFromJson() throws UnloggedFailure {
|
||||||
|
try (InputStreamReader r =
|
||||||
|
new InputStreamReader(in, StandardCharsets.UTF_8)) {
|
||||||
|
return OutputFormat.JSON.newGson().
|
||||||
|
fromJson(CharStreams.toString(r), ReviewInput.class);
|
||||||
|
} catch (IOException | JsonSyntaxException e) {
|
||||||
|
writeError(e.getMessage() + '\n');
|
||||||
|
throw error("internal error while reading review input");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reviewPatchSet(final PatchSet patchSet) throws Exception {
|
||||||
if (changeComment == null) {
|
if (changeComment == null) {
|
||||||
changeComment = "";
|
changeComment = "";
|
||||||
}
|
}
|
||||||
@ -243,8 +288,7 @@ public class ReviewCommand extends SshCommand {
|
|||||||
} else if (deleteDraftPatchSet) {
|
} else if (deleteDraftPatchSet) {
|
||||||
revisionApi(patchSet).delete();
|
revisionApi(patchSet).delete();
|
||||||
}
|
}
|
||||||
} catch (IllegalStateException | InvalidChangeOperationException
|
} catch (IllegalStateException | RestApiException e) {
|
||||||
| RestApiException e) {
|
|
||||||
throw error(e.getMessage());
|
throw error(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user