Describe core revision actions cherrypick, rebase, submit
Exporting these actions as UiCommands makes them visible in the actions map of a RevisionInfo if CURRENT_ACTIONS option was requested by the client. This gives the client hints about which actions the caller can invoke at the time the RevisionInfo was retrieved. Change-Id: I17510aed35e000e1d9fc9eb24c3646b4a72bfac9
This commit is contained in:
		@@ -14,7 +14,6 @@
 | 
			
		||||
 | 
			
		||||
package com.google.gerrit.httpd.rpc.changedetail;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.common.data.Capable;
 | 
			
		||||
import com.google.gerrit.common.data.ChangeDetail;
 | 
			
		||||
import com.google.gerrit.common.data.ChangeInfo;
 | 
			
		||||
import com.google.gerrit.common.data.SubmitRecord;
 | 
			
		||||
@@ -136,9 +135,7 @@ public class ChangeDetailFactory extends Handler<ChangeDetail> {
 | 
			
		||||
        changeId));
 | 
			
		||||
 | 
			
		||||
    detail.setCanRevert(change.getStatus() == Change.Status.MERGED && control.canAddPatchSet());
 | 
			
		||||
 | 
			
		||||
    detail.setCanCherryPick(control.getProjectControl().canPushToAtLeastOneRef() == Capable.OK);
 | 
			
		||||
 | 
			
		||||
    detail.setCanCherryPick(control.getProjectControl().canUpload());
 | 
			
		||||
    detail.setCanEdit(control.getRefControl().canWrite());
 | 
			
		||||
    detail.setCanEditCommitMessage(change.getStatus().isOpen() && control.canAddPatchSet());
 | 
			
		||||
    detail.setCanEditTopicName(control.canEditTopicName());
 | 
			
		||||
 
 | 
			
		||||
@@ -18,11 +18,11 @@ 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.RestModifyView;
 | 
			
		||||
import com.google.gerrit.extensions.webui.UiCommand;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Change;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
import com.google.gerrit.server.change.CherryPick.Input;
 | 
			
		||||
import com.google.gerrit.server.change.CherryPickChange;
 | 
			
		||||
import com.google.gerrit.server.git.MergeException;
 | 
			
		||||
import com.google.gerrit.server.project.ChangeControl;
 | 
			
		||||
import com.google.gerrit.server.project.InvalidChangeOperationException;
 | 
			
		||||
@@ -30,7 +30,11 @@ import com.google.gerrit.server.project.RefControl;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
 | 
			
		||||
class CherryPick implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
class CherryPick implements RestModifyView<RevisionResource, Input>,
 | 
			
		||||
    UiCommand<RevisionResource> {
 | 
			
		||||
  private final Provider<ReviewDb> dbProvider;
 | 
			
		||||
  private final Provider<CherryPickChange> cherryPickChange;
 | 
			
		||||
  private final ChangeJson json;
 | 
			
		||||
@@ -90,4 +94,34 @@ class CherryPick implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
      throw new ResourceConflictException(e.getMessage());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Set<Place> getPlaces() {
 | 
			
		||||
    return EnumSet.of(Place.PATCHSET_ACTION_PANEL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getLabel(RevisionResource resource) {
 | 
			
		||||
    return "Cherry Pick To";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getTitle(RevisionResource resource) {
 | 
			
		||||
    return "Cherry pick change to a different branch";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean isVisible(RevisionResource resource) {
 | 
			
		||||
    return isEnabled(resource);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean isEnabled(RevisionResource resource) {
 | 
			
		||||
    return resource.getControl().getProjectControl().canUpload();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getConfirmationMessage(RevisionResource resource) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -61,18 +61,17 @@ public class Module extends RestApiModule {
 | 
			
		||||
    delete(REVIEWER_KIND).to(DeleteReviewer.class);
 | 
			
		||||
 | 
			
		||||
    child(CHANGE_KIND, "revisions").to(Revisions.class);
 | 
			
		||||
    post(REVISION_KIND, "cherrypick").to(CherryPick.class);
 | 
			
		||||
    get(REVISION_KIND, "commit").to(GetCommit.class);
 | 
			
		||||
    get(REVISION_KIND, "review").to(GetReview.class);
 | 
			
		||||
    post(REVISION_KIND, "review").to(PostReview.class);
 | 
			
		||||
    post(REVISION_KIND, "submit").to(Submit.class);
 | 
			
		||||
    post(REVISION_KIND, "rebase").to(Rebase.class);
 | 
			
		||||
    get(REVISION_KIND, "submit_type").to(TestSubmitType.Get.class);
 | 
			
		||||
    get(REVISION_KIND, "patch").to(GetPatch.class);
 | 
			
		||||
    get(REVISION_KIND, "submit_type").to(TestSubmitType.Get.class);
 | 
			
		||||
    post(REVISION_KIND, "test.submit_rule").to(TestSubmitRule.class);
 | 
			
		||||
    post(REVISION_KIND, "test.submit_type").to(TestSubmitType.class);
 | 
			
		||||
 | 
			
		||||
    post(REVISION_KIND, "cherrypick").to(CherryPick.class);
 | 
			
		||||
 | 
			
		||||
    child(REVISION_KIND, "drafts").to(Drafts.class);
 | 
			
		||||
    put(REVISION_KIND, "drafts").to(CreateDraft.class);
 | 
			
		||||
    get(DRAFT_KIND).to(GetDraft.class);
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ import com.google.gerrit.extensions.restapi.AuthException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.RestModifyView;
 | 
			
		||||
import com.google.gerrit.extensions.webui.UiCommand;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Change;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
@@ -34,8 +35,11 @@ import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class Rebase implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
public class Rebase implements RestModifyView<RevisionResource, Input>,
 | 
			
		||||
    UiCommand<RevisionResource> {
 | 
			
		||||
  public static class Input {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -76,6 +80,38 @@ public class Rebase implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
    return json.format(change.getId());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Set<Place> getPlaces() {
 | 
			
		||||
    return EnumSet.of(Place.PATCHSET_ACTION_PANEL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getLabel(RevisionResource resource) {
 | 
			
		||||
    return "Rebase";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getTitle(RevisionResource resource) {
 | 
			
		||||
    return "Rebase onto tip of branch or parent change";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean isVisible(RevisionResource resource) {
 | 
			
		||||
    return isEnabled(resource);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean isEnabled(RevisionResource resource) {
 | 
			
		||||
    return resource.getChange().getStatus().isOpen()
 | 
			
		||||
        && resource.getControl().canRebase()
 | 
			
		||||
        && rebaseChange.get().canRebase(resource);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getConfirmationMessage(RevisionResource resource) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static class CurrentRevision implements
 | 
			
		||||
      RestModifyView<ChangeResource, Input> {
 | 
			
		||||
    private final Provider<ReviewDb> dbProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@ import com.google.gerrit.common.data.SubmitRecord;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.AuthException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.RestModifyView;
 | 
			
		||||
import com.google.gerrit.extensions.webui.UiCommand;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Change;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
			
		||||
@@ -49,9 +50,12 @@ import java.io.IOException;
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class Submit implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
public class Submit implements RestModifyView<RevisionResource, Input>,
 | 
			
		||||
    UiCommand<RevisionResource> {
 | 
			
		||||
  public static class Input {
 | 
			
		||||
    public boolean waitForMerge;
 | 
			
		||||
  }
 | 
			
		||||
@@ -140,6 +144,44 @@ public class Submit implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Set<Place> getPlaces() {
 | 
			
		||||
    return EnumSet.of(Place.PATCHSET_ACTION_PANEL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getLabel(RevisionResource resource) {
 | 
			
		||||
    return String.format(
 | 
			
		||||
        "Submit Patch Set %d",
 | 
			
		||||
        resource.getPatchSet().getPatchSetId());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getTitle(RevisionResource resource) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean isVisible(RevisionResource resource) {
 | 
			
		||||
    PatchSet.Id current = resource.getChange().currentPatchSetId();
 | 
			
		||||
    return resource.getChange().getStatus().isOpen()
 | 
			
		||||
        && resource.getPatchSet().getId().equals(current)
 | 
			
		||||
        && isEnabled(resource);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean isEnabled(RevisionResource resource) {
 | 
			
		||||
    // Enable based on approximation. If the user has permission enable,
 | 
			
		||||
    // even if the change has not reached as submittable state according
 | 
			
		||||
    // to the project rules.
 | 
			
		||||
    return resource.getControl().canSubmit();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getConfirmationMessage(RevisionResource resource) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * If the merge was attempted and it failed the system usually writes a
 | 
			
		||||
   * comment as a ChangeMessage and sets status to NEW. Find the relevant
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ import com.google.gerrit.server.ChangeUtil;
 | 
			
		||||
import com.google.gerrit.server.GerritPersonIdent;
 | 
			
		||||
import com.google.gerrit.server.IdentifiedUser;
 | 
			
		||||
import com.google.gerrit.server.change.PatchSetInserter;
 | 
			
		||||
import com.google.gerrit.server.change.RevisionResource;
 | 
			
		||||
import com.google.gerrit.server.git.GitRepositoryManager;
 | 
			
		||||
import com.google.gerrit.server.git.MergeUtil;
 | 
			
		||||
import com.google.gerrit.server.project.ChangeControl;
 | 
			
		||||
@@ -351,6 +352,34 @@ public class RebaseChange {
 | 
			
		||||
    return objectId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean canRebase(RevisionResource r) {
 | 
			
		||||
    Repository git;
 | 
			
		||||
    try {
 | 
			
		||||
      git = gitManager.openRepository(r.getChange().getProject());
 | 
			
		||||
    } catch (RepositoryNotFoundException err) {
 | 
			
		||||
      return false;
 | 
			
		||||
    } catch (IOException err) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    try {
 | 
			
		||||
      findBaseRevision(
 | 
			
		||||
          r.getPatchSet().getId(),
 | 
			
		||||
          db,
 | 
			
		||||
          r.getChange().getDest(),
 | 
			
		||||
          git,
 | 
			
		||||
          null,
 | 
			
		||||
          null,
 | 
			
		||||
          null);
 | 
			
		||||
      return true;
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      return false;
 | 
			
		||||
    } catch (OrmException e) {
 | 
			
		||||
      return false;
 | 
			
		||||
    } finally {
 | 
			
		||||
      git.close();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static boolean canDoRebase(final ReviewDb db,
 | 
			
		||||
      final Change change, final GitRepositoryManager gitManager,
 | 
			
		||||
      List<PatchSetAncestor> patchSetAncestors,
 | 
			
		||||
 
 | 
			
		||||
@@ -217,6 +217,20 @@ public class ProjectControl {
 | 
			
		||||
        || isOwnerAnyRef());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean canUpload() {
 | 
			
		||||
    for (SectionMatcher matcher : access()) {
 | 
			
		||||
      AccessSection section = matcher.section;
 | 
			
		||||
      if (section.getName().startsWith("refs/for/")) {
 | 
			
		||||
        Permission permission = section.getPermission(Permission.PUSH);
 | 
			
		||||
        if (permission != null
 | 
			
		||||
            && controlForRef(section.getName()).canPerform(Permission.PUSH)) {
 | 
			
		||||
          return true;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Can this user see all the refs in this projects? */
 | 
			
		||||
  public boolean allRefsAreVisible() {
 | 
			
		||||
    return allRefsAreVisibleExcept(Collections.<String> emptySet());
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user