Plugin API for change and revision

Change [1] started to implement new API with RevisionApi.review.
This change implements the following API methods:

* abandon
* rebase
* restore
* revert
* submit
* delete (draft)

SSH review command was migrated to utilize the new API.
Acceptance tests were added for the new API methods.

[1] https://gerrit-review.googlesource.com/48664

Change-Id: I2240759ba64401d0760c72490b9f4d05f965ecfc
This commit is contained in:
David Ostrovsky 2013-11-04 21:19:26 +01:00 committed by Shawn Pearce
parent 72d5b01b47
commit 44a1930ebf
20 changed files with 516 additions and 121 deletions

View File

@ -0,0 +1,6 @@
include_defs('//gerrit-acceptance-tests/tests.defs')
acceptance_tests(
srcs = glob(['*IT.java']),
deps = ['//gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git:util'],
)

View File

@ -0,0 +1,145 @@
// 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.acceptance.api.change;
import static com.google.gerrit.acceptance.git.GitUtil.cloneProject;
import static com.google.gerrit.acceptance.git.GitUtil.createProject;
import static com.google.gerrit.acceptance.git.GitUtil.initSsh;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.AcceptanceTestRequestScope;
import com.google.gerrit.acceptance.AccountCreator;
import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.git.PushOneCommit;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import com.google.inject.util.Providers;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
public class ChangeIT extends AbstractDaemonTest {
@Inject
private AccountCreator accounts;
@Inject
private SchemaFactory<ReviewDb> reviewDbProvider;
@Inject
private GerritApi gApi;
@Inject
private AcceptanceTestRequestScope atrScope;
@Inject
private IdentifiedUser.GenericFactory identifiedUserFactory;
private TestAccount admin;
private Git git;
private ReviewDb db;
@Before
public void setUp() throws Exception {
admin = accounts.admin();
initSsh(admin);
Project.NameKey project = new Project.NameKey("p");
SshSession sshSession = new SshSession(server, admin);
createProject(sshSession, project.get());
git = cloneProject(sshSession.getUrl() + "/" + project.get());
db = reviewDbProvider.open();
atrScope.set(atrScope.newContext(reviewDbProvider, sshSession,
identifiedUserFactory.create(Providers.of(db), admin.getId())));
}
@After
public void cleanup() {
db.close();
}
@Test
public void abandon() throws GitAPIException,
IOException, RestApiException {
PushOneCommit.Result r = createChange();
gApi.changes()
.id("p~master~" + r.getChangeId())
.abandon();
}
@Test
public void restore() throws GitAPIException,
IOException, RestApiException {
PushOneCommit.Result r = createChange();
gApi.changes()
.id("p~master~" + r.getChangeId())
.abandon();
gApi.changes()
.id("p~master~" + r.getChangeId())
.restore();
}
@Test
public void revert() throws GitAPIException,
IOException, RestApiException {
PushOneCommit.Result r = createChange();
gApi.changes()
.id("p~master~" + r.getChangeId())
.revision(r.getCommit().name())
.review(approve());
gApi.changes()
.id("p~master~" + r.getChangeId())
.revision(r.getCommit().name())
.submit();
gApi.changes()
.id("p~master~" + r.getChangeId())
.revert();
}
// Change is already up to date
@Test(expected = ResourceConflictException.class)
public void rebase() throws GitAPIException,
IOException, RestApiException {
PushOneCommit.Result r = createChange();
gApi.changes()
.id("p~master~" + r.getChangeId())
.revision(r.getCommit().name())
.rebase();
}
private PushOneCommit.Result createChange() throws GitAPIException,
IOException {
PushOneCommit push = new PushOneCommit(db, admin.getIdent());
return push.to(git, "refs/for/master");
}
private static ReviewInput approve() {
return new ReviewInput()
.message("Looks good!")
.label("Code-Review", 2);
}
}

View File

@ -1,6 +1,6 @@
include_defs('//gerrit-acceptance-tests/tests.defs')
acceptance_tests(
srcs = ['ReviewIT.java'],
srcs = glob(['*IT.java']),
deps = ['//gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git:util'],
)

View File

@ -18,7 +18,6 @@ import static com.google.gerrit.acceptance.git.GitUtil.cloneProject;
import static com.google.gerrit.acceptance.git.GitUtil.createProject;
import static com.google.gerrit.acceptance.git.GitUtil.initSsh;
import com.google.common.collect.Maps;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.AcceptanceTestRequestScope;
import com.google.gerrit.acceptance.AccountCreator;
@ -27,12 +26,14 @@ import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.git.PushOneCommit;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import com.google.inject.util.Providers;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
@ -42,7 +43,7 @@ import org.junit.Test;
import java.io.IOException;
public class ReviewIT extends AbstractDaemonTest {
public class RevisionIT extends AbstractDaemonTest {
@Inject
private AccountCreator accounts;
@ -54,7 +55,7 @@ public class ReviewIT extends AbstractDaemonTest {
private GerritApi gApi;
@Inject
AcceptanceTestRequestScope atrScope;
private AcceptanceTestRequestScope atrScope;
@Inject
private IdentifiedUser.GenericFactory identifiedUserFactory;
@ -71,9 +72,9 @@ public class ReviewIT extends AbstractDaemonTest {
SshSession sshSession = new SshSession(server, admin);
createProject(sshSession, project.get());
git = cloneProject(sshSession.getUrl() + "/" + project.get());
atrScope.set(atrScope.newContext(reviewDbProvider, sshSession,
identifiedUserFactory.create(admin.getId())));
db = reviewDbProvider.open();
atrScope.set(atrScope.newContext(reviewDbProvider, sshSession,
identifiedUserFactory.create(Providers.of(db), admin.getId())));
}
@After
@ -88,17 +89,38 @@ public class ReviewIT extends AbstractDaemonTest {
gApi.changes()
.id("p~master~" + r.getChangeId())
.revision(r.getCommit().name())
.review(makeReview());
.review(approve());
}
@Test
public void reviewId() throws GitAPIException,
IOException, RestApiException {
PushOneCommit.Result r = createChange();
gApi.changes()
.id(r.getChangeId())
.current()
.review(approve());
}
@Test
public void submit() throws GitAPIException,
IOException, RestApiException {
PushOneCommit.Result r = createChange();
RevisionApi rApi = gApi.changes()
.id("p~master~" + r.getChangeId())
.current();
rApi.review(approve());
rApi.submit();
}
@Test
public void deleteDraft() throws GitAPIException,
IOException, RestApiException {
PushOneCommit.Result r = createDraft();
gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.review(makeReview());
.delete();
}
private PushOneCommit.Result createChange() throws GitAPIException,
@ -107,11 +129,15 @@ public class ReviewIT extends AbstractDaemonTest {
return push.to(git, "refs/for/master");
}
private static ReviewInput makeReview() {
ReviewInput in = new ReviewInput();
in.message = "Looks good!";
in.labels = Maps.newHashMap();
in.labels.put("Code-Review", (short) 2);
return in;
private PushOneCommit.Result createDraft() throws GitAPIException,
IOException {
PushOneCommit push = new PushOneCommit(db, admin.getIdent());
return push.to(git, "refs/drafts/master");
}
private static ReviewInput approve() {
return new ReviewInput()
.message("Looks good!")
.label("Code-Review", 2);
}
}

View File

@ -28,6 +28,7 @@ import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.git.GitUtil;
import com.google.gerrit.acceptance.git.PushOneCommit;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
@ -171,9 +172,9 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
}
private void approve(String changeId) throws IOException {
RestResponse r =
session.post("/changes/" + changeId + "/revisions/current/review",
ReviewInput.approve());
RestResponse r = session.post(
"/changes/" + changeId + "/revisions/current/review",
new ReviewInput().label("Code-Review", 2));
assertEquals(HttpStatus.SC_OK, r.getStatusCode());
r.consume();
}

View File

@ -32,8 +32,8 @@ java_library(
java_library(
name = 'util',
srcs = ['AccountInfo.java', 'ChangeInfo.java', 'ChangeMessageInfo.java',
'GroupInfo.java', 'ProjectConfigInput.java', 'ReviewInput.java',
'SubmitInput.java', 'SuggestReviewerInfo.java'],
'GroupInfo.java', 'ProjectConfigInput.java', 'SubmitInput.java',
'SuggestReviewerInfo.java'],
deps = [
'//lib:guava',
'//gerrit-reviewdb:server',

View File

@ -12,19 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.acceptance.rest.change;
package com.google.gerrit.extensions.api.changes;
import com.google.common.collect.Maps;
import com.google.gerrit.extensions.restapi.DefaultInput;
import java.util.Map;
public class ReviewInput {
Map<String, Integer> labels;
public static ReviewInput approve() {
ReviewInput in = new ReviewInput();
in.labels = Maps.newHashMap();
in.labels.put("Code-Review", 2);
return in;
}
public class AbandonInput {
@DefaultInput
public String message;
}

View File

@ -17,6 +17,18 @@ package com.google.gerrit.extensions.api.changes;
import com.google.gerrit.extensions.restapi.RestApiException;
public interface ChangeApi {
String id();
RevisionApi current() throws RestApiException;
RevisionApi revision(int id) throws RestApiException;
RevisionApi revision(String id) throws RestApiException;
void abandon() throws RestApiException;
void abandon(AbandonInput in) throws RestApiException;
void restore() throws RestApiException;
void restore(RestoreInput in) throws RestApiException;
ChangeApi revert() throws RestApiException;
ChangeApi revert(RevertInput in) throws RestApiException;
}

View File

@ -0,0 +1,23 @@
// 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.extensions.api.changes;
import com.google.gerrit.extensions.restapi.DefaultInput;
public class RestoreInput {
@DefaultInput
public String message;
}

View File

@ -0,0 +1,22 @@
// 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.extensions.api.changes;
import com.google.gerrit.extensions.restapi.DefaultInput;
public class RevertInput {
@DefaultInput
public String message;
}

View File

@ -16,6 +16,7 @@ package com.google.gerrit.extensions.api.changes;
import com.google.gerrit.extensions.restapi.DefaultInput;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -85,4 +86,31 @@ public class ReviewInput {
public int endCharacter;
}
}
public ReviewInput message(String msg) {
message = msg != null && !msg.isEmpty() ? msg : null;
return this;
}
public ReviewInput label(String name, short value) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException();
}
if (labels == null) {
labels = new LinkedHashMap<String, Short>(4);
}
labels.put(name, value);
return this;
}
public ReviewInput label(String name, int value) {
if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
throw new IllegalArgumentException();
}
return label(name, (short) value);
}
public ReviewInput label(String name) {
return label(name, (short) 1);
}
}

View File

@ -17,5 +17,11 @@ package com.google.gerrit.extensions.api.changes;
import com.google.gerrit.extensions.restapi.RestApiException;
public interface RevisionApi {
void delete() throws RestApiException;
void rebase() throws RestApiException;
void review(ReviewInput in) throws RestApiException;
/** {@code submit} with {@link SubmitInput#waitForMerge} set to true. */
void submit() throws RestApiException;
void submit(SubmitInput in) throws RestApiException;
}

View File

@ -0,0 +1,19 @@
// 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.extensions.api.changes;
public class SubmitInput {
public boolean waitForMerge;
}

View File

@ -14,34 +14,68 @@
package com.google.gerrit.server.api.changes;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.extensions.api.changes.AbandonInput;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.Changes;
import com.google.gerrit.extensions.api.changes.RestoreInput;
import com.google.gerrit.extensions.api.changes.RevertInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.change.Abandon;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.change.Restore;
import com.google.gerrit.server.change.Revert;
import com.google.gerrit.server.change.Revisions;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
class ChangeApiImpl implements ChangeApi {
interface Factory {
ChangeApiImpl create(ChangeResource change);
}
private final Changes changeApi;
private final Revisions revisions;
private final RevisionApiImpl.Factory revisionApi;
private final ChangeResource change;
private final Provider<Abandon> abandon;
private final Provider<Revert> revert;
private final Provider<Restore> restore;
@Inject
ChangeApiImpl(Revisions revisions,
RevisionApiImpl.Factory api,
ChangeApiImpl(Changes changeApi,
Revisions revisions,
RevisionApiImpl.Factory revisionApi,
Provider<Abandon> abandon,
Provider<Revert> revert,
Provider<Restore> restore,
@Assisted ChangeResource change) {
this.changeApi = changeApi;
this.revert = revert;
this.revisions = revisions;
this.revisionApi = api;
this.revisionApi = revisionApi;
this.abandon = abandon;
this.restore = restore;
this.change = change;
}
@Override
public String id() {
return Integer.toString(change.getChange().getId().get());
}
@Override
public RevisionApi current() throws RestApiException {
return revision("current");
}
@Override
public RevisionApi revision(int id) throws RestApiException {
return revision(String.valueOf(id));
@ -56,4 +90,56 @@ class ChangeApiImpl implements ChangeApi {
throw new RestApiException("Cannot parse revision", e);
}
}
@Override
public void abandon() throws RestApiException {
abandon(new AbandonInput());
}
@Override
public void abandon(AbandonInput in) throws RestApiException {
try {
abandon.get().apply(change, in);
} catch (OrmException e) {
throw new RestApiException("Cannot abandon change", e);
} catch (IOException e) {
throw new RestApiException("Cannot abandon change", e);
}
}
@Override
public void restore() throws RestApiException {
restore(new RestoreInput());
}
@Override
public void restore(RestoreInput in) throws RestApiException {
try {
restore.get().apply(change, in);
} catch (OrmException e) {
throw new RestApiException("Cannot restore change", e);
} catch (IOException e) {
throw new RestApiException("Cannot restore change", e);
}
}
@Override
public ChangeApi revert() throws RestApiException {
return revert(new RevertInput());
}
@Override
public ChangeApi revert(RevertInput in) throws RestApiException {
try {
return changeApi.id(revert.get().apply(change, in)._number);
} catch (OrmException e) {
throw new RestApiException("Cannot revert change", e);
} catch (EmailException e) {
throw new RestApiException("Cannot revert change", e);
} catch (IOException e) {
throw new RestApiException("Cannot revert change", e);
} catch (NoSuchChangeException e) {
throw new RestApiException("Cannot revert change", e);
}
}
}

View File

@ -14,11 +14,16 @@
package com.google.gerrit.server.api.changes;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.change.DeleteDraftPatchSet;
import com.google.gerrit.server.change.PostReview;
import com.google.gerrit.server.change.Rebase;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.change.Submit;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@ -31,13 +36,22 @@ class RevisionApiImpl implements RevisionApi {
RevisionApiImpl create(RevisionResource r);
}
private final Provider<DeleteDraftPatchSet> deleteDraft;
private final Provider<Rebase> rebase;
private final Provider<PostReview> review;
private final Provider<Submit> submit;
private final RevisionResource revision;
@Inject
RevisionApiImpl(Provider<PostReview> review,
RevisionApiImpl(Provider<DeleteDraftPatchSet> deleteDraft,
Provider<Rebase> rebase,
Provider<PostReview> review,
Provider<Submit> submit,
@Assisted RevisionResource r) {
this.deleteDraft = deleteDraft;
this.rebase = rebase;
this.review = review;
this.submit = submit;
this.revision = r;
}
@ -51,4 +65,44 @@ class RevisionApiImpl implements RevisionApi {
throw new RestApiException("Cannot post review", e);
}
}
@Override
public void submit() throws RestApiException {
SubmitInput in = new SubmitInput();
in.waitForMerge = true;
submit(in);
}
@Override
public void submit(SubmitInput in) throws RestApiException {
try {
submit.get().apply(revision, in);
} catch (OrmException e) {
throw new RestApiException("Cannot submit change", e);
} catch (IOException e) {
throw new RestApiException("Cannot submit change", e);
}
}
@Override
public void delete() throws RestApiException {
try {
deleteDraft.get().apply(revision, null);
} catch (OrmException e) {
throw new RestApiException("Cannot delete draft ps", e);
} catch (IOException e) {
throw new RestApiException("Cannot delete draft ps", e);
}
}
@Override
public void rebase() throws RestApiException {
try {
rebase.get().apply(revision, null);
} catch (OrmException e) {
throw new RestApiException("Cannot rebase ps", e);
} catch (EmailException e) {
throw new RestApiException("Cannot rebase ps", e);
}
}
}

View File

@ -17,9 +17,9 @@ package com.google.gerrit.server.change;
import com.google.common.base.Strings;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.extensions.api.changes.AbandonInput;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.DefaultInput;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.webui.UiAction;
@ -29,7 +29,6 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.Abandon.Input;
import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.mail.AbandonedSender;
@ -46,7 +45,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Collections;
public class Abandon implements RestModifyView<ChangeResource, Input>,
public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
UiAction<ChangeResource> {
private static final Logger log = LoggerFactory.getLogger(Abandon.class);
@ -56,11 +55,6 @@ public class Abandon implements RestModifyView<ChangeResource, Input>,
private final ChangeJson json;
private final ChangeIndexer indexer;
public static class Input {
@DefaultInput
public String message;
}
@Inject
Abandon(ChangeHooks hooks,
AbandonedSender.Factory abandonedSenderFactory,
@ -75,9 +69,9 @@ public class Abandon implements RestModifyView<ChangeResource, Input>,
}
@Override
public Object apply(ChangeResource req, Input input)
public Object apply(ChangeResource req, AbandonInput input)
throws BadRequestException, AuthException,
ResourceConflictException, Exception {
ResourceConflictException, OrmException, IOException {
ChangeControl control = req.getControl();
IdentifiedUser caller = (IdentifiedUser) control.getCurrentUser();
Change change = req.getChange();
@ -144,7 +138,7 @@ public class Abandon implements RestModifyView<ChangeResource, Input>,
&& resource.getControl().canAbandon());
}
private ChangeMessage newMessage(Input input, IdentifiedUser caller,
private ChangeMessage newMessage(AbandonInput input, IdentifiedUser caller,
Change change) throws OrmException {
StringBuilder msg = new StringBuilder();
msg.append("Abandoned");

View File

@ -17,8 +17,8 @@ package com.google.gerrit.server.change;
import com.google.common.base.Strings;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.extensions.api.changes.RestoreInput;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.DefaultInput;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.webui.UiAction;
@ -30,7 +30,6 @@ import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
import com.google.gerrit.server.change.Restore.Input;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.mail.ReplyToChangeSender;
import com.google.gerrit.server.mail.RestoredSender;
@ -46,7 +45,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Collections;
public class Restore implements RestModifyView<ChangeResource, Input>,
public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
UiAction<ChangeResource> {
private static final Logger log = LoggerFactory.getLogger(Restore.class);
@ -56,11 +55,6 @@ public class Restore implements RestModifyView<ChangeResource, Input>,
private final ChangeJson json;
private final ChangeIndexer indexer;
public static class Input {
@DefaultInput
public String message;
}
@Inject
Restore(ChangeHooks hooks,
RestoredSender.Factory restoredSenderFactory,
@ -75,8 +69,9 @@ public class Restore implements RestModifyView<ChangeResource, Input>,
}
@Override
public Object apply(ChangeResource req, Input input)
throws Exception {
public Object apply(ChangeResource req, RestoreInput input)
throws OrmException, IOException, AuthException,
ResourceConflictException {
ChangeControl control = req.getControl();
IdentifiedUser caller = (IdentifiedUser) control.getCurrentUser();
Change change = req.getChange();
@ -143,7 +138,7 @@ public class Restore implements RestModifyView<ChangeResource, Input>,
&& resource.getControl().canRestore());
}
private ChangeMessage newMessage(Input input, IdentifiedUser caller,
private ChangeMessage newMessage(RestoreInput input, IdentifiedUser caller,
Change change) throws OrmException {
StringBuilder msg = new StringBuilder();
msg.append("Restored");

View File

@ -16,6 +16,8 @@ package com.google.gerrit.server.change;
import com.google.common.base.Strings;
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.extensions.api.changes.RevertInput;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
@ -27,21 +29,25 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.Revert.Input;
import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.validators.CommitValidators;
import com.google.gerrit.server.mail.RevertedSender;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.ssh.NoSshInfo;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
public class Revert implements RestModifyView<ChangeResource, Input>,
import java.io.IOException;
public class Revert implements RestModifyView<ChangeResource, RevertInput>,
UiAction<ChangeResource> {
private final ChangeHooks hooks;
private final RevertedSender.Factory revertedSenderFactory;
@ -53,10 +59,6 @@ public class Revert implements RestModifyView<ChangeResource, Input>,
private final PatchSetInfoFactory patchSetInfoFactory;
private final ChangeInserter.Factory changeInserterFactory;
public static class Input {
public String message;
}
@Inject
Revert(ChangeHooks hooks,
RevertedSender.Factory revertedSenderFactory,
@ -79,7 +81,9 @@ public class Revert implements RestModifyView<ChangeResource, Input>,
}
@Override
public Object apply(ChangeResource req, Input input) throws Exception {
public ChangeInfo apply(ChangeResource req, RevertInput input)
throws AuthException, ResourceConflictException, IOException,
NoSuchChangeException, EmailException, OrmException, BadRequestException {
ChangeControl control = req.getControl();
Change change = req.getChange();
if (!control.canAddPatchSet()) {

View File

@ -21,6 +21,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestModifyView;
@ -34,7 +35,6 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.ProjectUtil;
import com.google.gerrit.server.change.Submit.Input;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MergeQueue;
import com.google.gerrit.server.index.ChangeIndexer;
@ -53,7 +53,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class Submit implements RestModifyView<RevisionResource, Input>,
public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
UiAction<RevisionResource> {
public static class Input {
public boolean waitForMerge;
@ -90,9 +90,9 @@ public class Submit implements RestModifyView<RevisionResource, Input>,
}
@Override
public Output apply(RevisionResource rsrc, Input input) throws AuthException,
ResourceConflictException, RepositoryNotFoundException, IOException,
OrmException {
public Output apply(RevisionResource rsrc, SubmitInput input)
throws AuthException, ResourceConflictException,
RepositoryNotFoundException, IOException, OrmException {
ChangeControl control = rsrc.getControl();
IdentifiedUser caller = (IdentifiedUser) control.getCurrentUser();
Change change = rsrc.getChange();
@ -317,7 +317,7 @@ public class Submit implements RestModifyView<RevisionResource, Input>,
}
public static class CurrentRevision implements
RestModifyView<ChangeResource, Input> {
RestModifyView<ChangeResource, SubmitInput> {
private final Provider<ReviewDb> dbProvider;
private final Submit submit;
private final ChangeJson json;
@ -332,9 +332,9 @@ public class Submit implements RestModifyView<RevisionResource, Input>,
}
@Override
public Object apply(ChangeResource rsrc, Input input) throws AuthException,
ResourceConflictException, RepositoryNotFoundException, IOException,
OrmException {
public Object apply(ChangeResource rsrc, SubmitInput input)
throws AuthException, ResourceConflictException,
RepositoryNotFoundException, IOException, OrmException {
PatchSet ps = dbProvider.get().patchSets()
.get(rsrc.getChange().currentPatchSetId());
if (ps == null) {

View File

@ -23,23 +23,19 @@ import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.common.data.ReviewResult;
import com.google.gerrit.common.data.ReviewResult.Error.Type;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.AbandonInput;
import com.google.gerrit.extensions.api.changes.RestoreInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.change.Abandon;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.change.DeleteDraftPatchSet;
import com.google.gerrit.server.change.Restore;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.change.Submit;
import com.google.gerrit.server.changedetail.PublishDraft;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException;
@ -131,9 +127,6 @@ public class ReviewCommand extends SshCommand {
@Inject
private ReviewDb db;
@Inject
private DeleteDraftPatchSet deleteDraftPatchSetImpl;
@Inject
private ProjectControl.Factory projectControlFactory;
@ -141,23 +134,11 @@ public class ReviewCommand extends SshCommand {
private AllProjectsName allProjects;
@Inject
private ChangeControl.Factory changeControlFactory;
@Inject
private Provider<Abandon> abandonProvider;
@Inject
private Provider<GerritApi> api;
private Provider<GerritApi> gApi;
@Inject
private PublishDraft.Factory publishDraftFactory;
@Inject
private Provider<Restore> restoreProvider;
@Inject
private Provider<Submit> submitProvider;
private List<ApproveOption> optionList;
private Map<String, Short> customLabels;
@ -213,10 +194,10 @@ public class ReviewCommand extends SshCommand {
}
}
private void applyReview(final ChangeControl ctl, final PatchSet patchSet,
private void applyReview(PatchSet patchSet,
final ReviewInput review) throws Exception {
api.get().changes()
.id(ctl.getChange().getChangeId())
gApi.get().changes()
.id(patchSet.getId().getParentKey().get())
.revision(patchSet.getRevision().get())
.review(review);
}
@ -248,44 +229,41 @@ public class ReviewCommand extends SshCommand {
}
try {
ChangeControl ctl =
changeControlFactory.controlFor(patchSet.getId().getParentKey());
if (abandonChange) {
final Abandon abandon = abandonProvider.get();
final Abandon.Input input = new Abandon.Input();
AbandonInput input = new AbandonInput();
input.message = changeComment;
applyReview(ctl, patchSet, review);
applyReview(patchSet, review);
try {
abandon.apply(new ChangeResource(ctl), input);
gApi.get().changes()
.id(patchSet.getId().getParentKey().get())
.abandon(input);
} catch (AuthException e) {
writeError("error: " + parseError(Type.ABANDON_NOT_PERMITTED) + "\n");
} catch (ResourceConflictException e) {
writeError("error: " + parseError(Type.CHANGE_IS_CLOSED) + "\n");
}
} else if (restoreChange) {
final Restore restore = restoreProvider.get();
final Restore.Input input = new Restore.Input();
RestoreInput input = new RestoreInput();
input.message = changeComment;
try {
restore.apply(new ChangeResource(ctl), input);
applyReview(ctl, patchSet, review);
gApi.get().changes()
.id(patchSet.getId().getParentKey().get())
.restore(input);
applyReview(patchSet, review);
} catch (AuthException e) {
writeError("error: " + parseError(Type.RESTORE_NOT_PERMITTED) + "\n");
} catch (ResourceConflictException e) {
writeError("error: " + parseError(Type.CHANGE_NOT_ABANDONED) + "\n");
}
} else {
applyReview(ctl, patchSet, review);
applyReview(patchSet, review);
}
if (submitChange) {
Submit submit = submitProvider.get();
Submit.Input input = new Submit.Input();
input.waitForMerge = true;
submit.apply(new RevisionResource(
new ChangeResource(ctl), patchSet),
input);
gApi.get().changes()
.id(patchSet.getId().getParentKey().get())
.revision(patchSet.getRevision().get())
.submit();
}
if (publishPatchSet) {
@ -293,9 +271,10 @@ public class ReviewCommand extends SshCommand {
publishDraftFactory.create(patchSet.getId()).call();
handleReviewResultErrors(result);
} else if (deleteDraftPatchSet) {
deleteDraftPatchSetImpl.apply(new RevisionResource(
new ChangeResource(ctl), patchSet),
new DeleteDraftPatchSet.Input());
gApi.get().changes()
.id(patchSet.getId().getParentKey().get())
.revision(patchSet.getRevision().get())
.delete();
}
} catch (InvalidChangeOperationException e) {
throw error(e.getMessage());
@ -307,6 +286,8 @@ public class ReviewCommand extends SshCommand {
throw error(e.getMessage());
} catch (ResourceConflictException e) {
throw error(e.getMessage());
} catch (RestApiException e) {
throw error(e.getMessage());
}
}