Search in sources :

Example 11 with UIThreadUnsafe

use of com.virtuslab.qual.guieffect.UIThreadUnsafe in project git-machete-intellij-plugin by VirtusLab.

the class BaseOverrideForkPointAction method actionPerformed.

@Override
@UIEffect
public void actionPerformed(AnActionEvent anActionEvent) {
    val project = getProject(anActionEvent);
    val gitRepository = getSelectedGitRepository(anActionEvent).getOrNull();
    val branchUnderAction = getNameOfBranchUnderAction(anActionEvent);
    val branch = branchUnderAction.flatMap(pn -> getManagedBranchByName(anActionEvent, pn)).getOrNull();
    if (gitRepository == null || branch == null || branch.isRoot()) {
        return;
    }
    val nonRootBranch = branch.asNonRoot();
    val selectedCommit = new OverrideForkPointDialog(project, nonRootBranch.getParent(), nonRootBranch).showAndGetSelectedCommit();
    if (selectedCommit == null) {
        log().debug("Commit selected to be the new fork point is null: most likely the action has been canceled from override-fork-point dialog");
        return;
    }
    LOG.debug("Enqueueing fork point override");
    new Task.Backgroundable(project, "Overriding fork point...") {

        @Override
        @UIThreadUnsafe
        public void run(ProgressIndicator indicator) {
            overrideForkPoint(anActionEvent, branch, selectedCommit);
        }
    }.queue();
}
Also used : lombok.val(lombok.val) GENERAL(org.checkerframework.checker.i18nformatter.qual.I18nConversionCategory.GENERAL) ICommitOfManagedBranch(com.virtuslab.gitmachete.backend.api.ICommitOfManagedBranch) VirtualFile(com.intellij.openapi.vfs.VirtualFile) lombok.val(lombok.val) IManagedBranchSnapshot(com.virtuslab.gitmachete.backend.api.IManagedBranchSnapshot) CustomLog(lombok.CustomLog) SyncToParentStatus(com.virtuslab.gitmachete.backend.api.SyncToParentStatus) List(io.vavr.collection.List) GitMacheteBundle.getString(com.virtuslab.gitmachete.frontend.resourcebundles.GitMacheteBundle.getString) I18nFormat(org.checkerframework.checker.i18nformatter.qual.I18nFormat) IExpectsKeyGitMacheteRepository(com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeyGitMacheteRepository) ProgressIndicator(com.intellij.openapi.progress.ProgressIndicator) UIEffect(org.checkerframework.checker.guieffect.qual.UIEffect) Task(com.intellij.openapi.progress.Task) UIThreadUnsafe(com.virtuslab.qual.guieffect.UIThreadUnsafe) AnActionEvent(com.intellij.openapi.actionSystem.AnActionEvent) IEnhancedLambdaLogger(com.virtuslab.logger.IEnhancedLambdaLogger) Project(com.intellij.openapi.project.Project) GitConfigUtil(git4idea.config.GitConfigUtil) VcsException(com.intellij.openapi.vcs.VcsException) OverrideForkPointDialog(com.virtuslab.gitmachete.frontend.actions.dialogs.OverrideForkPointDialog) Task(com.intellij.openapi.progress.Task) ProgressIndicator(com.intellij.openapi.progress.ProgressIndicator) OverrideForkPointDialog(com.virtuslab.gitmachete.frontend.actions.dialogs.OverrideForkPointDialog) UIThreadUnsafe(com.virtuslab.qual.guieffect.UIThreadUnsafe) UIEffect(org.checkerframework.checker.guieffect.qual.UIEffect)

Example 12 with UIThreadUnsafe

use of com.virtuslab.qual.guieffect.UIThreadUnsafe in project git-machete-intellij-plugin by VirtusLab.

the class BaseRebaseBranchOntoParentAction method doRebase.

private void doRebase(Project project, GitRepository gitRepository, IGitMacheteRepositorySnapshot gitMacheteRepositorySnapshot, INonRootManagedBranchSnapshot branchToRebase, boolean shouldExplicitlyCheckout) {
    LOG.debug(() -> "Entering: project = ${project}, gitRepository = ${gitRepository}, branchToRebase = ${branchToRebase}");
    val tryGitRebaseParameters = Try.of(() -> branchToRebase.getParametersForRebaseOntoParent());
    if (tryGitRebaseParameters.isFailure()) {
        val e = tryGitRebaseParameters.getCause();
        // TODO (#172): redirect the user to the manual fork-point
        val message = e.getMessage() == null ? "Unable to get rebase parameters." : e.getMessage();
        LOG.error(message);
        IntelliJNotificationCompat.notifyError(project, getString("action.GitMachete.BaseRebaseBranchOntoParentAction.notification.title.rebase-fail"), message);
        return;
    }
    val gitRebaseParameters = tryGitRebaseParameters.get();
    LOG.debug(() -> "Queuing machete-pre-rebase hooks background task for '${branchToRebase.getName()}' branch");
    new Task.Backgroundable(project, getString("action.GitMachete.BaseRebaseBranchOntoParentAction.hook.task-title")) {

        @Override
        @UIThreadUnsafe
        public void run(ProgressIndicator indicator) {
            AtomicReference<Try<Option<IExecutionResult>>> wrapper = new AtomicReference<>(Try.success(Option.none()));
            new GitFreezingProcess(project, myTitle, () -> {
                LOG.info("Executing machete-pre-rebase hooks");
                val hookResult = Try.of(() -> gitMacheteRepositorySnapshot.executeMachetePreRebaseHookIfPresent(gitRebaseParameters));
                wrapper.set(hookResult);
            }).execute();
            Try<Option<IExecutionResult>> hookResult = wrapper.get();
            if (hookResult == null) {
                // Not really possible, it's here just to calm down Checker Framework.
                return;
            }
            if (hookResult.isFailure()) {
                val message = "machete-pre-rebase hooks refused to rebase ${NL}error: ${hookResult.getCause().getMessage()}";
                LOG.error(message);
                IntelliJNotificationCompat.notifyError(project, getString("action.GitMachete.BaseRebaseBranchOntoParentAction.notification.title.rebase-abort"), message);
                return;
            }
            val maybeExecutionResult = hookResult.get();
            if (maybeExecutionResult.isDefined() && maybeExecutionResult.get().getExitCode() != 0) {
                val message = "machete-pre-rebase hooks refused to rebase (exit code ${maybeExecutionResult.get().getExitCode()})";
                LOG.error(message);
                val executionResult = maybeExecutionResult.get();
                val stdoutOption = executionResult.getStdout();
                val stderrOption = executionResult.getStderr();
                IntelliJNotificationCompat.notifyError(project, getString("action.GitMachete.BaseRebaseBranchOntoParentAction.notification.title.rebase-abort"), message + (!stdoutOption.trim().isEmpty() ? NL + "stdout:" + NL + stdoutOption : "") + (!stderrOption.trim().isEmpty() ? NL + "stderr:" + NL + stderrOption : ""));
                return;
            }
            LOG.debug(() -> "Queuing rebase background task for '${branchToRebase.getName()}' branch");
            new Task.Backgroundable(project, getString("action.GitMachete.BaseRebaseBranchOntoParentAction.task-title")) {

                @Override
                @UIThreadUnsafe
                public void run(ProgressIndicator indicator) {
                    GitRebaseParams params = getIdeaRebaseParamsOf(gitRepository, gitRebaseParameters);
                    LOG.info("Rebasing '${gitRebaseParameters.getCurrentBranch().getName()}' branch " + "until ${gitRebaseParameters.getForkPointCommit().getHash()} commit " + "onto ${gitRebaseParameters.getNewBaseBranch().getName()}");
                    /*
             * Git4Idea ({@link git4idea.rebase.GitRebaseUtils#rebase}) does not allow to rebase in detached head state.
             * However, it is possible with Git (performing checkout implicitly) and should be allowed in the case of
             * "Checkout and Rebase Onto Parent" Action. To pass the git4idea check in such a case we checkout the branch
             * explicitly and then perform the actual rebase.
             */
                    if (shouldExplicitlyCheckout) {
                        CheckoutSelectedBranchAction.doCheckout(project, indicator, gitRebaseParameters.getCurrentBranch().getName(), gitRepository);
                    }
                    GitRebaseUtils.rebase(project, Collections.singletonList(gitRepository), params, indicator);
                }
            }.queue();
        }
    }.queue();
}
Also used : lombok.val(lombok.val) GitFreezingProcess(git4idea.util.GitFreezingProcess) Task(com.intellij.openapi.progress.Task) AtomicReference(java.util.concurrent.atomic.AtomicReference) IExecutionResult(com.virtuslab.gitmachete.backend.api.hooks.IExecutionResult) ProgressIndicator(com.intellij.openapi.progress.ProgressIndicator) GitRebaseParams(git4idea.branch.GitRebaseParams) Option(io.vavr.control.Option) Try(io.vavr.control.Try) UIThreadUnsafe(com.virtuslab.qual.guieffect.UIThreadUnsafe)

Example 13 with UIThreadUnsafe

use of com.virtuslab.qual.guieffect.UIThreadUnsafe in project git-machete-intellij-plugin by VirtusLab.

the class BaseRebaseBranchOntoParentAction method getIdeaRebaseParamsOf.

@UIThreadUnsafe
private GitRebaseParams getIdeaRebaseParamsOf(GitRepository repository, IGitRebaseParameters gitRebaseParameters) {
    GitVersion gitVersion = repository.getVcs().getVersion();
    String currentBranchName = gitRebaseParameters.getCurrentBranch().getName();
    String newBaseBranchFullName = gitRebaseParameters.getNewBaseBranch().getFullName();
    String forkPointCommitHash = gitRebaseParameters.getForkPointCommit().getHash();
    // TODO (#743): replace with a non-reflective constructor call
    try {
        // Proper solution for 2020.3+
        val constructor = GitRebaseParams.class.getConstructor(GitVersion.class, String.class, String.class, String.class, java.util.Set.class, GitRebaseParams.AutoSquashOption.class, GitRebaseEditorHandler.class);
        val gitRebaseOptionValueOf = Class.forName("git4idea.rebase.GitRebaseOption").getMethod("valueOf", String.class);
        val INTERACTIVE = gitRebaseOptionValueOf.invoke(null, "INTERACTIVE");
        val KEEP_EMPTY = gitRebaseOptionValueOf.invoke(null, "KEEP_EMPTY");
        val options = kotlin.collections.SetsKt.hashSetOf(INTERACTIVE, KEEP_EMPTY);
        return constructor.newInstance(gitVersion, currentBranchName, newBaseBranchFullName, /* upstream */
        forkPointCommitHash, /* selectedOptions */
        options, GitRebaseParams.AutoSquashOption.DEFAULT, /* editorHandler */
        null);
    } catch (ReflectiveOperationException e) {
        // Fallback for 2020.1 and 2020.2
        return new GitRebaseParams(gitVersion, currentBranchName, newBaseBranchFullName, /* upstream */
        forkPointCommitHash, /* interactive */
        true, /* preserveMerges */
        false);
    }
}
Also used : lombok.val(lombok.val) GitVersion(git4idea.config.GitVersion) GitRebaseParams(git4idea.branch.GitRebaseParams) GitMacheteBundle.getString(com.virtuslab.gitmachete.frontend.resourcebundles.GitMacheteBundle.getString) UIThreadUnsafe(com.virtuslab.qual.guieffect.UIThreadUnsafe)

Example 14 with UIThreadUnsafe

use of com.virtuslab.qual.guieffect.UIThreadUnsafe in project git-machete-intellij-plugin by VirtusLab.

the class CheckoutSelectedBranchAction method doCheckout.

@UIThreadUnsafe
public static void doCheckout(Project project, ProgressIndicator indicator, String branchToCheckoutName, GitRepository gitRepository) {
    GitBranchUiHandlerImpl uiHandler = new GitBranchUiHandlerImpl(project, Git.getInstance(), indicator);
    new GitBranchWorker(project, Git.getInstance(), uiHandler).checkout(branchToCheckoutName, /* detach */
    false, Collections.singletonList(gitRepository));
}
Also used : GitBranchUiHandlerImpl(git4idea.branch.GitBranchUiHandlerImpl) GitBranchWorker(git4idea.branch.GitBranchWorker) UIThreadUnsafe(com.virtuslab.qual.guieffect.UIThreadUnsafe)

Example 15 with UIThreadUnsafe

use of com.virtuslab.qual.guieffect.UIThreadUnsafe in project git-machete-intellij-plugin by VirtusLab.

the class CheckoutSelectedBranchAction method actionPerformed.

@Override
@UIEffect
public void actionPerformed(AnActionEvent anActionEvent) {
    val selectedBranchName = getSelectedBranchName(anActionEvent);
    if (selectedBranchName.isEmpty()) {
        return;
    }
    val project = getProject(anActionEvent);
    val gitRepository = getSelectedGitRepository(anActionEvent);
    if (gitRepository.isDefined()) {
        log().debug(() -> "Queuing '${selectedBranchName.get()}' branch checkout background task");
        new Task.Backgroundable(project, getString("action.GitMachete.CheckoutSelectedBranchAction.task-title")) {

            @Override
            @UIThreadUnsafe
            public void run(ProgressIndicator indicator) {
                doCheckout(project, indicator, selectedBranchName.get(), gitRepository.get());
            }
        }.queue();
    }
}
Also used : lombok.val(lombok.val) Task(com.intellij.openapi.progress.Task) ProgressIndicator(com.intellij.openapi.progress.ProgressIndicator) UIThreadUnsafe(com.virtuslab.qual.guieffect.UIThreadUnsafe) UIEffect(org.checkerframework.checker.guieffect.qual.UIEffect)

Aggregations

UIThreadUnsafe (com.virtuslab.qual.guieffect.UIThreadUnsafe)27 lombok.val (lombok.val)25 ProgressIndicator (com.intellij.openapi.progress.ProgressIndicator)8 Task (com.intellij.openapi.progress.Task)8 GitMacheteBundle.getString (com.virtuslab.gitmachete.frontend.resourcebundles.GitMacheteBundle.getString)8 UIEffect (org.checkerframework.checker.guieffect.qual.UIEffect)6 VcsException (com.intellij.openapi.vcs.VcsException)5 VirtualFile (com.intellij.openapi.vfs.VirtualFile)3 GitCoreException (com.virtuslab.gitcore.api.GitCoreException)3 GitMacheteException (com.virtuslab.gitmachete.backend.api.GitMacheteException)3 Nullable (org.checkerframework.checker.nullness.qual.Nullable)3 AnActionEvent (com.intellij.openapi.actionSystem.AnActionEvent)2 AccessToken (com.intellij.openapi.application.AccessToken)2 Project (com.intellij.openapi.project.Project)2 PsiFile (com.intellij.psi.PsiFile)2 IManagedBranchSnapshot (com.virtuslab.gitmachete.backend.api.IManagedBranchSnapshot)2 DeleteBranchOnSlideOutSuggestionDialog (com.virtuslab.gitmachete.frontend.actions.dialogs.DeleteBranchOnSlideOutSuggestionDialog)2 IExpectsKeyGitMacheteRepository (com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeyGitMacheteRepository)2 IEnhancedLambdaLogger (com.virtuslab.logger.IEnhancedLambdaLogger)2 GitRebaseParams (git4idea.branch.GitRebaseParams)2