diff --git a/platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java b/platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java index aa8a440f4f30..209a29b74011 100644 --- a/platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java +++ b/platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java @@ -48,6 +48,10 @@ public class ExtensionPointName { return Extensions.getExtensions(this); } + public T[] getExtensions(AreaInstance areaInstance) { + return Extensions.getExtensions(this, areaInstance); + } + public V findExtension(Class instanceOf) { return ContainerUtil.findInstance(getExtensions(), instanceOf); } diff --git a/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml b/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml index 3905e130e141..ec0c4aa10057 100644 --- a/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml @@ -51,6 +51,7 @@ + diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java new file mode 100644 index 000000000000..f893c7bd195e --- /dev/null +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.vcs; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; + +/** + * @author Dmitry Avdeev + * Date: 16.07.13 + */ +public abstract class VcsTaskHandler { + + public static VcsTaskHandler[] getAllHandlers(Project project) { + return EXTENSION_POINT_NAME.getExtensions(project); + } + + private static final ExtensionPointName EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.vcs.taskHandler"); + + public abstract void startNewTask(String name); + + public abstract void switchTask(String to); + + public abstract void closeTask(String name); +} diff --git a/plugins/git4idea/git4idea.iml b/plugins/git4idea/git4idea.iml index e361c833beb1..94a499bb7686 100644 --- a/plugins/git4idea/git4idea.iml +++ b/plugins/git4idea/git4idea.iml @@ -61,7 +61,7 @@ - + diff --git a/plugins/git4idea/src/META-INF/plugin.xml b/plugins/git4idea/src/META-INF/plugin.xml index e8b122d348a9..0af88bd947d0 100644 --- a/plugins/git4idea/src/META-INF/plugin.xml +++ b/plugins/git4idea/src/META-INF/plugin.xml @@ -166,6 +166,7 @@ + diff --git a/plugins/git4idea/src/git4idea/GitTaskHandler.java b/plugins/git4idea/src/git4idea/GitTaskHandler.java new file mode 100644 index 000000000000..c2436c8da75d --- /dev/null +++ b/plugins/git4idea/src/git4idea/GitTaskHandler.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package git4idea; + +import com.intellij.openapi.vcs.VcsTaskHandler; +import git4idea.branch.GitBrancher; +import git4idea.repo.GitRepository; +import git4idea.repo.GitRepositoryManager; + +import java.util.List; + +/** + * @author Dmitry Avdeev + * Date: 17.07.13 + */ +public class GitTaskHandler extends VcsTaskHandler { + + private final GitBrancher myBrancher; + private final GitRepositoryManager myRepositoryManager; + + public GitTaskHandler(GitBrancher brancher, GitRepositoryManager repositoryManager) { + myBrancher = brancher; + myRepositoryManager = repositoryManager; + } + + @Override + public void startNewTask(String name) { + List repositories = myRepositoryManager.getRepositories(); + myBrancher.checkoutNewBranch(name, repositories); + } + + @Override + public void switchTask(String name) { + myBrancher.checkout(name, myRepositoryManager.getRepositories(), null); + } + + @Override + public void closeTask(String name) { + myBrancher.merge(name, GitBrancher.DeleteOnMergeOption.DELETE, myRepositoryManager.getRepositories()); + } +} diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/BranchInfo.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/BranchInfo.java new file mode 100644 index 000000000000..ef8b817e2c3d --- /dev/null +++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/BranchInfo.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.tasks; + +import com.intellij.util.xmlb.annotations.Attribute; +import com.intellij.util.xmlb.annotations.Tag; + +/** + * @author Dmitry Avdeev + * Date: 18.07.13 + */ +@Tag("branch") +public class BranchInfo { + + @Attribute("name") + public String name; + + @Attribute("repository") + public String repository; +} diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/LocalTask.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/LocalTask.java index 392a29628875..bdf9c8ceb785 100644 --- a/plugins/tasks/tasks-api/src/com/intellij/tasks/LocalTask.java +++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/LocalTask.java @@ -44,6 +44,8 @@ public abstract class LocalTask extends Task { return false; } + // VCS interface + @NotNull public abstract List getChangeLists(); @@ -51,6 +53,15 @@ public abstract class LocalTask extends Task { public abstract void removeChangelist(final ChangeListInfo info); + @NotNull + public abstract List getBranches(); + + public abstract void addBranch(BranchInfo info); + + public abstract void removeBranch(final BranchInfo info); + + // time tracking interface + public abstract long getTotalTimeSpent(); public abstract boolean isRunning(); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SimpleOpenTaskDialog.form b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SimpleOpenTaskDialog.form index 5e061e4f701d..54f304b00329 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SimpleOpenTaskDialog.form +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SimpleOpenTaskDialog.form @@ -99,7 +99,7 @@ - + @@ -107,7 +107,7 @@ - + @@ -115,7 +115,7 @@ - + diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SimpleOpenTaskDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SimpleOpenTaskDialog.java index a66def940b7c..a0bd11fd06f0 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SimpleOpenTaskDialog.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/SimpleOpenTaskDialog.java @@ -27,7 +27,6 @@ import com.intellij.tasks.*; import com.intellij.tasks.impl.TaskManagerImpl; import com.intellij.tasks.impl.TaskUtil; import com.intellij.ui.IdeBorderFactory; -import com.intellij.ui.components.JBRadioButton; import com.intellij.util.ui.RadioButtonEnumModel; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -47,9 +46,6 @@ public class SimpleOpenTaskDialog extends DialogWrapper { private JCheckBox myCreateChangelist; private JCheckBox myMarkAsInProgressBox; private JLabel myTaskNameLabel; - private JBRadioButton myCreateBranch; - private JBRadioButton myCreateNewChangelist; - private JBRadioButton myDoNothing; private JPanel myVcsPanel; private JPanel myDistributedVcsPanel; private ButtonGroup myVcsGroup; diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/LocalTaskImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/LocalTaskImpl.java index d3b6469c076b..cdc14fb03c30 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/LocalTaskImpl.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/LocalTaskImpl.java @@ -62,6 +62,7 @@ public class LocalTaskImpl extends LocalTask { private boolean myRunning = false; private List myWorkItems = new ArrayList(); private Date myLastPost; + private List myBranches = new ArrayList(); /** for serialization */ @@ -215,6 +216,22 @@ public class LocalTaskImpl extends LocalTask { myChangeLists.remove(info); } + @NotNull + @Override + public List getBranches() { + return myBranches; + } + + @Override + public void addBranch(BranchInfo info) { + myBranches.add(info); + } + + @Override + public void removeBranch(BranchInfo info) { + myBranches.add(info); + } + public boolean isClosed() { return myClosed; } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java index 20142b180ef8..fc647676eab9 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java @@ -32,6 +32,7 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.VcsTaskHandler; import com.intellij.openapi.vcs.VcsType; import com.intellij.openapi.vcs.changes.*; import com.intellij.tasks.*; @@ -372,11 +373,17 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe @Override public void performVcsOperation(LocalTask task, VcsOperation operation) { + String name = getChangelistName(task); if (operation == VcsOperation.CREATE_CHANGELIST) { - String name = getChangelistName(task); String comment = TaskUtil.getChangeListComment(task); createChangeList(task, name, comment); } + else if (operation == VcsOperation.CREATE_BRANCH) { + VcsTaskHandler[] handlers = VcsTaskHandler.getAllHandlers(myProject); + for (VcsTaskHandler handler : handlers) { + handler.startNewTask(name); + } + } } private void saveActiveTask() { diff --git a/plugins/tasks/tasks-tests/tasks-tests.iml b/plugins/tasks/tasks-tests/tasks-tests.iml index 519e6002f570..50b9abc289e7 100644 --- a/plugins/tasks/tasks-tests/tasks-tests.iml +++ b/plugins/tasks/tasks-tests/tasks-tests.iml @@ -18,6 +18,7 @@ + diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TestRepository.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TestRepository.java index dc6b4aa14fda..1bb79498b38a 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TestRepository.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TestRepository.java @@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable; /** * @author Dmitry Avdeev */ -class TestRepository extends BaseRepository { +public class TestRepository extends BaseRepository { private Task[] myTasks; public TestRepository(Task... tasks) { diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java new file mode 100644 index 000000000000..6d98208d6fe1 --- /dev/null +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.tasks.vcs; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vcs.VcsTaskHandler; +import com.intellij.tasks.TaskManagerTestCase; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import git4idea.GitLocalBranch; +import git4idea.branch.GitBranchesCollection; +import git4idea.repo.GitRepository; +import git4idea.test.GitTestUtil; + +import java.io.File; +import java.util.Collection; +import java.util.List; + +/** + * @author Dmitry Avdeev + * Date: 18.07.13 + */ +public class TaskBranchesTest extends TaskManagerTestCase { + + public void testGitTaskHandler() throws Exception { + + List repositories = initRepositories("community", "idea"); + GitRepository repository = repositories.get(0); + + VcsTaskHandler[] handlers = VcsTaskHandler.getAllHandlers(getProject()); + assertEquals(1, handlers.length); + VcsTaskHandler handler = handlers[0]; + handler.startNewTask("first"); + Collection localBranches = repository.getBranches().getLocalBranches(); + assertEquals(2, localBranches.size()); + GitLocalBranch currentBranch = repository.getCurrentBranch(); + assertNotNull(currentBranch); + assertEquals("first", currentBranch.getName()); + } + + private List initRepositories(String... names) { + return ContainerUtil.map(names, new Function() { + @Override + public GitRepository fun(String s) { + return initRepository(s); + } + }); + } + + private GitRepository initRepository(String name) { + String tempDirectory = FileUtil.getTempDirectory(); + String root = tempDirectory + "/" + name; + assertTrue(new File(root).mkdirs()); + GitRepository repository = GitTestUtil.createRepository(getProject(), root); + GitBranchesCollection branches = repository.getBranches(); + assertEquals(1, branches.getLocalBranches().size()); + return repository; + } +} diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskVcsTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java similarity index 98% rename from plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskVcsTest.java rename to plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java index 404b22db5bdc..3954181ce4ef 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskVcsTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.tasks; +package com.intellij.tasks.vcs; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.util.Condition; @@ -22,6 +22,7 @@ import com.intellij.openapi.vcs.changes.*; import com.intellij.openapi.vcs.changes.committed.MockAbstractVcs; import com.intellij.openapi.vcs.changes.ui.CommitChangeListDialog; import com.intellij.openapi.vcs.impl.projectlevelman.AllVcses; +import com.intellij.tasks.*; import com.intellij.tasks.impl.LocalTaskImpl; import com.intellij.tasks.impl.TaskChangelistSupport; import com.intellij.tasks.impl.TaskManagerImpl; @@ -29,6 +30,7 @@ import com.intellij.testFramework.IdeaTestCase; import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase; import com.intellij.util.containers.ContainerUtil; import icons.TasksIcons; +import junit.framework.Assert; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -61,7 +63,7 @@ public class TaskVcsTest extends CodeInsightFixtureTestCase { assertEquals(defaultTask, myTaskManager.getAssociatedTask(myChangeListManager.getChangeListsCopy().get(0))); assertEquals(defaultTask.getChangeLists().get(0).id, myChangeListManager.getChangeListsCopy().get(0).getId()); - assertEquals(defaultTask.getChangeLists().get(0), new ChangeListInfo(myChangeListManager.getChangeListsCopy().get(0))); + Assert.assertEquals(defaultTask.getChangeLists().get(0), new ChangeListInfo(myChangeListManager.getChangeListsCopy().get(0))); } public void testSwitchingTasks() throws Exception {