diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java index 0ee5f2ed09c3..456722a416e1 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java @@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.List; @@ -30,6 +31,8 @@ import java.util.List; */ public abstract class VcsTaskHandler { + public static final String DEFAULT_PROHIBITED_SYMBOLS = " "; + public static VcsTaskHandler[] getAllHandlers(final Project project) { VcsTaskHandler[] extensions = EXTENSION_POINT_NAME.getExtensions(project); List handlers = ContainerUtil.filter(extensions, new Condition() { @@ -86,4 +89,12 @@ public abstract class VcsTaskHandler { * @return all existing tasks (branches) */ public abstract TaskInfo[] getAllExistingTasks(); + + /** + * @return REGEXP with prohibited symbols for replaceAll(REGEXP, other) future call, null if every symbol is possible + */ + @Nullable + public String getProhibitedSymbolsInBranchNames() { + return DEFAULT_PROHIBITED_SYMBOLS; + } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgTaskHandler.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgTaskHandler.java index cae21530a6be..46e0ca6d3a43 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgTaskHandler.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgTaskHandler.java @@ -102,4 +102,10 @@ public class HgTaskHandler extends DvcsTaskHandler { protected boolean hasBranch(@NotNull HgRepository repository, @NotNull String name) { return HgUtil.getNamesWithoutHashes(repository.getBookmarks()).contains(name) || repository.getOpenedBranches().contains(name); } + + @Override + @Nullable + public String getProhibitedSymbolsInBranchNames() { + return null; + } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java index 01aa53d21b58..b6f34b433e4d 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java @@ -44,6 +44,7 @@ import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Collection; +import java.util.regex.Pattern; /** * @author Dmitry Avdeev @@ -174,7 +175,10 @@ public class OpenTaskDialog extends DialogWrapper { }); } - myBranchName.setText(taskManager.suggestBranchName(task)); + myBranchName.setText( + taskManager.suggestBranchName(task, myVcsTaskHandler != null + ? myVcsTaskHandler.getProhibitedSymbolsInBranchNames() + : VcsTaskHandler.DEFAULT_PROHIBITED_SYMBOLS)); myChangelistName.setText(taskManager.getChangelistName(task)); } updateFields(true); @@ -258,6 +262,12 @@ public class OpenTaskDialog extends DialogWrapper { if (branchName.isEmpty()) { return new ValidationInfo("Branch name should not be empty", myBranchName); } + else if (myVcsTaskHandler != null) { + String regExp = myVcsTaskHandler.getProhibitedSymbolsInBranchNames(); + if (regExp != null && (Pattern.compile(regExp).matcher(branchName)).find()) { + return new ValidationInfo("Branch name contains prohibited symbols or regexp: \'" + regExp + "\'"); + } + } else if (branchName.contains(" ")) { return new ValidationInfo("Branch name should not contain spaces"); } 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 0fc1253e5db5..2ca5eb173c8c 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 @@ -997,9 +997,15 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe return StringUtil.shortenTextWithEllipsis(name, 100, 0); } - public String suggestBranchName(Task task) { + @TestOnly + public String suggestBranchName(@NotNull Task task) { + return suggestBranchName(task, VcsTaskHandler.DEFAULT_PROHIBITED_SYMBOLS); + } + + public String suggestBranchName(@NotNull Task task, @Nullable String prohibitedRegExp) { if (task.isIssue()) { - return TaskUtil.formatTask(task, myConfig.branchNameFormat).replace(' ', '-'); + String formatTask = TaskUtil.formatTask(task, myConfig.branchNameFormat); + return prohibitedRegExp != null ? formatTask.replaceAll(prohibitedRegExp, "-") : formatTask; } else { String summary = task.getSummary(); @@ -1009,7 +1015,6 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe } } - @TestOnly public ChangeListAdapter getChangeListListener() { return myChangeListListener; diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java index 2542ec2b3a99..43508d49a0fe 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java @@ -382,6 +382,13 @@ public class TaskVcsTest extends CodeInsightFixtureTestCase { LocalTaskImpl strange = new LocalTaskImpl("1", "very long and strange summary"); assertEquals("very-long", myTaskManager.suggestBranchName(strange)); + + myTaskManager.getState().branchNameFormat = "{id} {summary}"; + + LocalTaskImpl withIllegalSymbolsInIssue = new LocalTaskImpl("1", "contains Illegal$Symbols"); + withIllegalSymbolsInIssue.setIssue(true); + assertEquals("1-contains-Illegal-Symbols", myTaskManager.suggestBranchName(withIllegalSymbolsInIssue, " |\\$")); + assertEquals("1-contains-Illegal$Symbols", myTaskManager.suggestBranchName(withIllegalSymbolsInIssue)); } private TestRepository myRepository;