public CreatePullRequestModel( @NotNull final Project project, @NotNull final GitRepository gitRepository) { this.project = project; this.gitRepository = gitRepository; this.tfGitRemotes = TfGitHelper.getTfGitRemotes(gitRepository); this.remoteBranchComboModel = createRemoteBranchDropdownModel(); this.targetBranch = (GitRemoteBranch) this.remoteBranchComboModel.getSelectedItem(); this.applicationProvider = new ApplicationProvider(); this.pullRequestHelper = new PullRequestHelper(); this.diffCompareInfoProvider = new DiffCompareInfoProvider(); this.diffCache = CacheBuilder.newBuilder() .maximumSize(20) .build( new CacheLoader<Pair<String, String>, GitCommitCompareInfo>() { @Override public GitCommitCompareInfo load(Pair<String, String> key) throws Exception { // if we missed the cache, then show the loading spinner, otherwise // just switch to the diff we have to avoid flickering the screen applicationProvider.invokeAndWaitWithAnyModality( new Runnable() { @Override public void run() { // set the view to show loading setLoading(true); } }); return getDiffCompareInfoProvider() .getBranchCompareInfo( project, gitRepository, key.getFirst(), key.getSecond()); } }); this.executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); }
/** * Create pull request on a background thread * * <p>This method will first check to see if the local branch has a tracking branch: yes: push the * commits to the remote tracking branch no: try create a remote branch matching the local branch * name exactly, with the remote set to the GitRemote of the target branch * * <p>If push fails for whatever reason, stop and show an error message * * <p>After we push the local branch, then create the pull request. Pull request link should be * returned in a notification bubble */ public void createPullRequest() { /* verifying branch selections */ final GitLocalBranch sourceBranch = this.getSourceBranch(); final GitRemoteBranch targetBranch = this.getTargetBranch(); if (sourceBranch == null) { // how did we get here? validation failed? notifyCreateFailedError( project, TfPluginBundle.message(TfPluginBundle.KEY_CREATE_PR_ERRORS_SOURCE_EMPTY)); return; } if (targetBranch == null) { // how did we get here? validation failed? notifyCreateFailedError( project, TfPluginBundle.message(TfPluginBundle.KEY_CREATE_PR_ERRORS_TARGET_NOT_SELECTED)); return; } if (targetBranch.equals(this.getRemoteTrackingBranch())) { // how did we get here? Didn't we filter you out? notifyCreateFailedError( project, TfPluginBundle.message(TfPluginBundle.KEY_CREATE_PR_ERRORS_TARGET_IS_LOCAL_TRACKING)); return; } // TODO Determine the correct/best way to get the remote url final String gitRemoteUrl = TfGitHelper.getTfGitRemote(gitRepository).getFirstUrl(); final CreatePullRequestModel createModel = this; /* Let's keep all server interactions to a background thread */ final Task.Backgroundable createPullRequestTask = new Task.Backgroundable( project, TfPluginBundle.message(TfPluginBundle.KEY_CREATE_PR_DIALOG_TITLE), true, PerformInBackgroundOption.DEAF) { @Override public void run(@NotNull ProgressIndicator progressIndicator) { // get context from manager, create PAT if needed, and store in active context final ServerContext context = ServerContextManager.getInstance() .getAuthenticatedContext( gitRemoteUrl, TfPluginBundle.message(TfPluginBundle.KEY_PAT_TOKEN_DESC), true); if (context == null) { notifyCreateFailedError( project, TfPluginBundle.message( TfPluginBundle.KEY_ERRORS_AUTH_NOT_SUCCESSFUL, gitRemoteUrl)); return; } ListenableFuture<Pair<String, GitCommandResult>> pushResult = doPushCommits( gitRepository, sourceBranch, targetBranch.getRemote(), progressIndicator); Futures.addCallback( pushResult, new FutureCallback<Pair<String, GitCommandResult>>() { @Override public void onSuccess(@Nullable Pair<String, GitCommandResult> result) { if (result != null && StringUtils.isNotEmpty(result.getFirst())) { final String title = createModel.getTitle(); final String description = createModel.getDescription(); final String branchNameOnRemoteServer = result.getFirst(); doCreatePullRequest( project, context, title, description, branchNameOnRemoteServer, targetBranch); } else { // I really don't have anything else to say, push failed, the title says it // all // I have no error message to be more specific notifyPushFailedError(createModel.getProject(), StringUtils.EMPTY); } } @Override public void onFailure(Throwable t) { notifyPushFailedError(createModel.getProject(), t.getLocalizedMessage()); } }); } }; createPullRequestTask.queue(); }