Eclipseplugins
CherryPickJob.java
1 package com.proalpha.pds.gitutils.cherrypick;
2 
3 import java.io.IOException;
4 import java.lang.reflect.InvocationTargetException;
5 import java.text.MessageFormat;
6 
7 import org.eclipse.core.runtime.IProgressMonitor;
8 import org.eclipse.core.runtime.IStatus;
9 import org.eclipse.core.runtime.Status;
10 import org.eclipse.core.runtime.SubMonitor;
11 import org.eclipse.core.runtime.jobs.Job;
12 import org.eclipse.egit.core.EclipseGitProgressTransformer;
13 import org.eclipse.egit.ui.JobFamilies;
14 import org.eclipse.egit.ui.internal.staging.StagingView;
15 import org.eclipse.jface.dialogs.MessageDialog;
16 import org.eclipse.jgit.api.CherryPickResult.CherryPickStatus;
17 import org.eclipse.jgit.api.errors.GitAPIException;
18 import org.eclipse.jgit.lib.Constants;
19 import org.eclipse.jgit.lib.Repository;
20 import org.eclipse.swt.widgets.Display;
21 import org.eclipse.ui.PlatformUI;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 
25 import com.proalpha.git.PaGit;
26 import com.proalpha.git.commands.PaIssueConveyanceCommand;
27 import com.proalpha.git.model.PaCherryPickResult;
28 import com.proalpha.git.util.PaBranchName;
29 import com.proalpha.git.util.PaCommitMsg;
30 import com.proalpha.git.util.PaRepository;
31 import com.proalpha.pds.gitutils.common.CheckoutOperation;
32 
33 @SuppressWarnings("restriction")
34 public class CherryPickJob extends Job {
35 
36  private final Logger logger = LoggerFactory.getLogger(CherryPickJob.class);
37 
38  private int noOfCommits = 0;
39 
40  public CherryPickJob(int noOfCommits) {
41  super(MessageFormat.format("Cherry picking {0} commits", noOfCommits));
42 
43  this.noOfCommits = noOfCommits;
44  }
45 
46  @Override
47  protected IStatus run(IProgressMonitor monitor) {
48 
49  PaIssueConveyanceCommand picCo = CherryPick.getInstance().getCherryPickCommand();
50  CherryPickSettings cherryPickSettings = CherryPick.getInstance().getCherryPickSettings();
51  PaCherryPickResult cpResult = null;
52  CherryPickStatus cpStatus = null;
53 
54  final SubMonitor progress = SubMonitor.convert(monitor, "pA CherryPick", this.noOfCommits + 2);
55  final CherryPickOperation cpOp = new CherryPickOperation(picCo);
56 
57  CheckoutOperation coOp;
58  if (cherryPickSettings.getTargetBranchPoint().startsWith(Constants.DEFAULT_REMOTE_NAME))
59  coOp = new CheckoutOperation(picCo.getRepository(), Constants.DEFAULT_REMOTE_NAME,
60  cherryPickSettings.getTargetBranchPoint(), PaBranchName.getShortBranchName(picCo.getTargetRef()),
61  cherryPickSettings.isUpdateTargetBranchPoint(), // Update source branch (this is the branch, where
62  // the new branch is branched off
63  true /* Update target branch if it already exists */);
64  else
65  coOp = new CheckoutOperation(picCo.getRepository(), PaBranchName.getShortBranchName(picCo.getTargetRef()));
66 
67  try {
68  // Ensure that branch is checked out
69  progress.setTaskName("Creating the target branch");
70  coOp.run();
71  progress.worked(1);
72 
73  progress.setTaskName("Picking the commits");
74  PaGit.getInstance()
75  .setProgressMonitor(new EclipseGitProgressTransformer(progress.newChild(this.noOfCommits)));
76  cpOp.execute();
77  CherryPick.getInstance().setCherryPickResult(cpOp.getOperationResult());
78 
79  cpResult = CherryPick.getInstance().getCherryPickResult();
80  cpStatus = CherryPick.getInstance().getCherryPickResult().getStatus();
81 
82  if (cpStatus != CherryPickStatus.OK)
83  setConflictMessage(cherryPickSettings, cpResult);
84  else {
85  try {
86  PaRepository.disconnectRemote('_' + cherryPickSettings.getSourceRepoString());
87 
88  } catch (IOException | GitAPIException e) {
89  logger.error("Exception while disconnecting remote {}", picCo.getSourceRef(), e);
90  }
91  }
92 
93  showResultDialog(monitor, picCo.getRepository(), cpResult);
94  } catch (InvocationTargetException | GitAPIException e) {
95  Throwable cause = (e.getCause() == null) ? e : e.getCause();
96  String msg = cause.getMessage();
97  // Display display = Display.getDefault();
98  // Shell shell = Display.getDefault().getActiveShell(); --> throws "Invalid
99  // thread access"
100  Display.getDefault().asyncExec(() -> MessageDialog.openError(null, "Cherry pick failed", msg));
101  } finally {
102  // If an unexpected error occurred (there is no result) or
103  // all is complete: forget the last pick to be able to run a new cherry pick
104  // operation
105  if (CherryPick.getInstance().getCherryPickResult() == null
106  || CherryPick.getInstance().getCherryPickResult() != null
107  && CherryPick.getInstance().getCherryPickResult().getStatus() == CherryPickStatus.OK)
108  CherryPick.getInstance().reinitialize();
109 
110  monitor.done();
111  }
112  return Status.OK_STATUS;
113  }
114 
115  @Override
116  public boolean belongsTo(Object family) {
117  if (JobFamilies.CHERRY_PICK.equals(family))
118  return true;
119  return super.belongsTo(family);
120  }
121 
122  private void setConflictMessage(CherryPickSettings settings, PaCherryPickResult result) {
123  PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
124  StagingView view = (StagingView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
125  .findView(StagingView.VIEW_ID);
126 
127  logger.debug("Commit failed: Initialize the commit msg of the git staging view.");
128  if (view != null) {
129  String msg = PaCommitMsg.getCherryPickMsg(settings.getTargetIssue(),
130  result.getOpenPicks().get(0).getFullMessage(), result.getOpenPicks().get(0).getId().name());
131  msg = msg + System.getProperty("line.separator");
132  msg = msg + System.getProperty("line.separator");
133  msg += "Conflict resolution: DO NOT EDIT THIS MESSAGE";
134  view.setCommitMessage(msg);
135  view.setFocus();
136  }
137  });
138  }
139 
140  private void showResultDialog(IProgressMonitor monitor, Repository repository,
141  PaCherryPickResult cherryPickResult) {
142  PlatformUI.getWorkbench().getDisplay()
143  .asyncExec(() -> new CherryPickResultDialog(
144  PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), monitor, cherryPickResult)
145  .open());
146  }
147 
148 }