[hg]: execute bookmark operations as background tasks and add ability to execute synchronously if needed

This commit is contained in:
Nadya Zabrodina
2016-04-02 01:43:42 +03:00
parent c6aeb7e59e
commit dc535473a0
5 changed files with 51 additions and 61 deletions
@@ -113,6 +113,7 @@ hg4idea.progress.countingHeads=Checking number of heads...
hg4idea.progress.pull.with.rebase=Rebasing patches
hg4idea.progress.pull.with.update=Updating repository
hg4idea.progress.rebase=Rebasing repository
hg4idea.progress.bookmark=Creating Bookmark {0}...
hg4idea.mq.progress.goto=Goto {0}...
hg4idea.mq.progress.pop=Pop all applied patches...
@@ -97,7 +97,7 @@ public class HgTaskHandler extends DvcsTaskHandler<HgRepository> {
VirtualFile repositoryRoot = repository.getRoot();
try {
new HgCommitCommand(project, repository, "Automated merge with " + branch).executeInCurrentThread();
new HgBookmarkCommand(project, repositoryRoot, branch).deleteBookmark();
HgBookmarkCommand.deleteBookmarkSynchronously(project, repositoryRoot, branch);
}
catch (HgCommandException e) {
HgErrorUtil.handleException(project, e);
@@ -306,14 +306,11 @@ public class HgBranchPopupActions {
@Override
public void actionPerformed(AnActionEvent e) {
for (HgRepository repository : myRepositories) {
try {
new HgBookmarkCommand(myProject, repository.getRoot(), myBranchName).deleteBookmark();
HgUtil.executeOnPooledThread(() -> {
for (HgRepository repository : myRepositories) {
HgBookmarkCommand.deleteBookmarkSynchronously(myProject, repository.getRoot(), myBranchName);
}
catch (HgCommandException exception) {
HgErrorUtil.handleException(myProject, exception);
}
}
}, myProject);
}
}
}
@@ -1,79 +1,62 @@
package org.zmlx.hg4idea.command;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsNotifier;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcsMessages;
import org.zmlx.hg4idea.action.HgCommandResultNotifier;
import org.zmlx.hg4idea.execution.HgCommandException;
import org.zmlx.hg4idea.execution.HgCommandExecutor;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.execution.HgCommandResultHandler;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgErrorUtil;
import java.util.ArrayList;
import java.util.List;
import static com.intellij.util.containers.ContainerUtil.emptyList;
import static java.util.Collections.singletonList;
import static org.zmlx.hg4idea.util.HgUtil.getRepositoryManager;
public class HgBookmarkCommand {
@NotNull private final Project myProject;
@NotNull private final VirtualFile myRepo;
@Nullable private final String myBookmarkName;
@NotNull private final HgCommandResultHandler myBookmarkResultHandler;
public HgBookmarkCommand(@NotNull Project project,
@NotNull VirtualFile repo,
@Nullable String bookmarkName) {
myProject = project;
myRepo = repo;
myBookmarkName = bookmarkName;
myBookmarkResultHandler = new HgCommandResultHandler() {
@Override
public void process(@Nullable HgCommandResult result) {
if(myProject.isDisposed()) return;
getRepositoryManager(myProject).updateRepository(myRepo);
if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
new HgCommandResultNotifier(myProject)
.notifyError(result, "Hg Error", "Hg bookmark command failed for " + myBookmarkName);
}
}
};
}
public void createBookmarkAsynchronously(boolean isActive) throws HgCommandException {
if (isActive) {
executeBookmarkCommandAsynchronously();
}
else {
executeBookmarkCommandAsynchronously("--inactive");
}
}
public static void createBookmarkAsynchronously(@NotNull List<HgRepository> repositories, @NotNull String name, boolean isActive) {
for (HgRepository repository : repositories) {
Project project = repository.getProject();
try {
new HgBookmarkCommand(project, repository.getRoot(), name).createBookmarkAsynchronously(isActive);
}
catch (HgCommandException exception) {
HgErrorUtil.handleException(project, exception);
}
final Project project = ObjectUtils.assertNotNull(ContainerUtil.getFirstItem(repositories)).getProject();
if (StringUtil.isEmptyOrSpaces(name)) {
VcsNotifier.getInstance(project).notifyError("Hg Error", "Bookmark name is empty");
}
new Task.Backgroundable(project, HgVcsMessages.message("hg4idea.progress.bookmark", name)) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
for (HgRepository repository : repositories) {
executeBookmarkCommandSynchronously(project, repository.getRoot(), name, isActive ? emptyList() : singletonList("--inactive"));
}
}
}.queue();
}
public void deleteBookmark() throws HgCommandException {
executeBookmarkCommandAsynchronously("-d"); //delete
public static void deleteBookmarkSynchronously(@NotNull Project project, @NotNull VirtualFile repo, @NotNull String name) {
executeBookmarkCommandSynchronously(project, repo, name, singletonList("-d"));
}
private void executeBookmarkCommandAsynchronously(@NotNull String... args) throws HgCommandException {
if (StringUtil.isEmptyOrSpaces(myBookmarkName)) {
throw new HgCommandException("bookmark name is empty");
private static void executeBookmarkCommandSynchronously(@NotNull Project project,
@NotNull VirtualFile repositoryRoot,
@NotNull String name,
@NotNull List<String> args) {
ArrayList<String> arguments = ContainerUtil.newArrayList(args);
arguments.add(name);
HgCommandResult result = new HgCommandExecutor(project).executeInCurrentThread(repositoryRoot, "bookmark", arguments);
if (project.isDisposed()) return;
getRepositoryManager(project).updateRepository(repositoryRoot);
if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
new HgCommandResultNotifier(project)
.notifyError(result, "Hg Error",
String.format("Hg bookmark command failed for repository %s with name %s ", repositoryRoot.getName(), name));
}
List<String> arguments = ContainerUtil.newArrayList(args);
arguments.add(myBookmarkName);
new HgCommandExecutor(myProject).execute(myRepo, "bookmark", arguments, myBookmarkResultHandler);
}
}
@@ -69,6 +69,7 @@ public abstract class TaskBranchesTest extends PlatformTestCase {
final String first = "first";
VcsTaskHandler.TaskInfo firstInfo = handler.startNewTask(first);
repository.update();
assertEquals(first, firstInfo.getName());
assertEquals(2, firstInfo.getRepositories().size());
@@ -76,15 +77,18 @@ public abstract class TaskBranchesTest extends PlatformTestCase {
assertEquals(first, repository.getCurrentBranchName());
handler.switchToTask(defaultInfo, null);
repository.update();
assertEquals(defaultBranchName, repository.getCurrentBranchName());
final String second = "second";
VcsTaskHandler.TaskInfo secondInfo = handler.startNewTask(second);
repository.update();
assertEquals(3, getNumberOfBranches(repository));
assertEquals(second, repository.getCurrentBranchName());
handler.switchToTask(firstInfo, null);
commitChanges(repository);
handler.closeTask(secondInfo, firstInfo);
repository.update();
assertEquals(2, getNumberOfBranches(repository));
}
@@ -115,6 +119,7 @@ public abstract class TaskBranchesTest extends PlatformTestCase {
commitChanges(repository);
myTaskManager.mergeBranch(localTask);
repository.update();
assertEquals(defaultBranchName, repository.getCurrentBranchName());
assertEquals(1, getNumberOfBranches(repository));
@@ -144,7 +149,7 @@ public abstract class TaskBranchesTest extends PlatformTestCase {
myTaskManager.createBranch(localTask, defaultTask, myTaskManager.suggestBranchName(localTask));
commitChanges(repository);
myTaskManager.mergeBranch(localTask);
repository.update();
assertEquals(getDefaultBranchName(), repository.getCurrentBranchName());
assertEquals(1, getNumberOfBranches(repository));
}
@@ -166,13 +171,14 @@ public abstract class TaskBranchesTest extends PlatformTestCase {
}
public void testBranchBloating() throws Exception {
initRepository("foo");
Repository repository = initRepository("foo");
LocalTask defaultTask = myTaskManager.getActiveTask();
assertNotNull(defaultTask);
assertEquals(0, defaultTask.getBranches().size());
LocalTaskImpl foo = myTaskManager.createLocalTask("foo");
LocalTask localTask = myTaskManager.activateTask(foo, false);
myTaskManager.createBranch(localTask, defaultTask, myTaskManager.suggestBranchName(localTask));
repository.update();
assertEquals(2, localTask.getBranches().size());
assertEquals(1, defaultTask.getBranches().size());
@@ -180,6 +186,7 @@ public abstract class TaskBranchesTest extends PlatformTestCase {
LocalTaskImpl bar = myTaskManager.createLocalTask("bar");
LocalTask barTask = myTaskManager.activateTask(bar, false);
myTaskManager.createBranch(localTask, defaultTask, myTaskManager.suggestBranchName(barTask));
repository.update();
assertEquals(1, defaultTask.getBranches().size());
}
@@ -199,8 +206,10 @@ public abstract class TaskBranchesTest extends PlatformTestCase {
info.name = "non-existing";
info.repository = defaultTask.getBranches().get(0).repository;
defaultTask.addBranch(info);
repository.update();
assertEquals("foo", repository.getCurrentBranchName());
myTaskManager.activateTask(defaultTask, false);
repository.update();
assertEquals(getDefaultBranchName(), repository.getCurrentBranchName());
// do not re-create "non-existing"
assertEquals(2, getNumberOfBranches(repository));