diff --git a/.gitignore b/.gitignore index 0fdb83c..b954802 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ *.zip *.jar out -gitflow.iml \ No newline at end of file +*.iml \ No newline at end of file diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index dddc32a..807db2e 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -2,7 +2,7 @@ Git Flow Integration Gitflow Git Flow Integration - 0.4.3 + 0.4.4 VCS Integration Opher Vishnia @@ -17,23 +17,21 @@ - - - - + + + + - - - - + + + + - - - + + + - - gitflow.GitflowComponent diff --git a/README.md b/README.md index 32ba425..7ec2d29 100644 --- a/README.md +++ b/README.md @@ -59,4 +59,3 @@ This plugin is under the [Apache 2.0 license](http://www.apache.org/licenses/LIC Copyright 2013-2014, Opher Vishnia. -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/OpherV/gitflow4idea/trend.png)](https://bitdeli.com/free "Bitdeli Badge") diff --git a/docs/project_setup.md b/docs/project_setup.md new file mode 100644 index 0000000..e75085e --- /dev/null +++ b/docs/project_setup.md @@ -0,0 +1,70 @@ +# Project setup help + +This is a quick overview how to setup the project for development. + +## 1. Make sure the plugin development plugin is enabled + +Start IDEA, go to *Settings -> Plugins* and make sure that `Plugin DevKit` is installed and enabled. +If it's not, install it now. + +## 2. Clone the project from GitHub + +Typically you check out your fork of the project on GitHub here. + +## 3. Import the project into IDEA + +Select the *Import Project* option (e.g. by pressing shift twice and entering "import project") +and navigate to the cloned repository directory when prompted. + +### Model + +Chose "From existing sources" when prompted for a model. + +### SDK Setup + +If you dont have a plugin SDK yet, click `+` to add an SDK and select *IntelliJ Platform Plugin SDK* + +1. Navigate to your IDEA installation and select the installation directory. +2. Afterwards select a JDK when prompted + +Select your plugin SDK as the one to use. + +### Other + +The remaining options can be left at default + +## 4. Change the project type + +Open the projects iml file (it should be named `gitflow4idea.iml` by default) and replace its contents with this: + +```xml + + + + + + + + + + + +``` + +Then close and reopen the project to apply the changes. + +## 5. Add git4idea dependency + +1. Open the module settings and navigate to *Modules -> gitflow4idea (or your project name here)* and select the *Dependencies* tab. +2. Click add -> "JARs or directories" and add `git4idea.jar`. + This can be found in your IDEA installation directory under `plugins/git4idea/lib`. +3. Change the scope of the added JAR to **provided**. + +## 6. Create a run configuration + +Go to Run/Debug configurations and create a new configuration of the type `Plugin`. Under "Use classpath of module" select the project (`gitflow4idea` by default). +Click run. A new IDEA instance should start with the plugin running. + +And that's it. You can now make changes to the source and run them. + + diff --git a/src/gitflow/GitInitLineHandler.java b/src/gitflow/GitInitLineHandler.java index 5ae5dc5..94945f2 100644 --- a/src/gitflow/GitInitLineHandler.java +++ b/src/gitflow/GitInitLineHandler.java @@ -4,24 +4,25 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; -import git4idea.commands.GitCommand; -import git4idea.commands.GitLineHandler; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; -import java.io.PrintWriter; + +import git4idea.commands.GitCommand; +import git4idea.commands.GitLineHandler; public class GitInitLineHandler extends GitLineHandler { private BufferedWriter writer; GitflowInitOptions _initOptions; - public GitInitLineHandler(GitflowInitOptions initOptions,@NotNull Project project, @NotNull VirtualFile vcsRoot, @NotNull GitCommand command) { + public GitInitLineHandler(GitflowInitOptions initOptions, @NotNull Project project, @NotNull VirtualFile vcsRoot, @NotNull GitCommand command) { super(project, vcsRoot, command); - _initOptions=initOptions; + _initOptions = initOptions; } @Nullable @@ -39,54 +40,59 @@ protected void processTerminated(final int exitCode) { @Override protected void onTextAvailable(String s, Key key) { - super.onTextAvailable(s,key); + super.onTextAvailable(s, key); try { - if (s.contains("Branch name for production releases")){ + if (s.contains("Branch name for production releases")) { writer.write(_initOptions.getProductionBranch()); myVcs.showCommandLine(_initOptions.getProductionBranch()); writer.newLine(); writer.flush(); } - if (s.contains("Branch name for \"next release\"") || - s.contains("Which branch should be used for integration of the")){ + if (s.contains("Branch name for \"next release\"")) { writer.write(_initOptions.getDevelopmentBranch()); myVcs.showCommandLine(_initOptions.getDevelopmentBranch()); writer.newLine(); writer.flush(); } - if (s.contains("Feature branches")){ + + if (s.contains("Which branch should be used for integration of the")) { + writer.newLine(); + writer.flush(); + } + + if (s.contains("Feature branches")) { writer.write(_initOptions.getFeaturePrefix()); myVcs.showCommandLine(_initOptions.getFeaturePrefix()); writer.newLine(); writer.flush(); } - if (s.contains("Release branches")){ + if (s.contains("Release branches")) { writer.write(_initOptions.getReleasePrefix()); myVcs.showCommandLine(_initOptions.getReleasePrefix()); writer.newLine(); writer.flush(); } - if (s.contains("Hotfix branches")){ + if (s.contains("Hotfix branches")) { writer.write(_initOptions.getHotfixPrefix()); myVcs.showCommandLine(_initOptions.getHotfixPrefix()); writer.newLine(); writer.flush(); } - if (s.contains("Support branches")){ + if (s.contains("Support branches")) { writer.write(_initOptions.getSupportPrefix()); myVcs.showCommandLine(_initOptions.getSupportPrefix()); writer.newLine(); writer.flush(); } - if (s.contains("Version tag")){ + if (s.contains("Version tag")) { writer.write(_initOptions.getVersionPrefix()); myVcs.showCommandLine(_initOptions.getVersionPrefix()); writer.newLine(); writer.flush(); } - if (s.contains("Hooks and filters")){ + if (s.contains("Hooks and filters")) { writer.newLine(); writer.flush(); } diff --git a/src/gitflow/Gitflow.java b/src/gitflow/Gitflow.java index 3bc4560..0d5aeb9 100644 --- a/src/gitflow/Gitflow.java +++ b/src/gitflow/Gitflow.java @@ -1,16 +1,15 @@ package gitflow; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + import git4idea.commands.Git; import git4idea.commands.GitCommandResult; import git4idea.commands.GitLineHandlerListener; import git4idea.repo.GitRemote; import git4idea.repo.GitRepository; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** - * - * * @author Opher Vishnia / opherv.com / opherv@gmail.com */ public interface Gitflow extends Git { @@ -23,26 +22,27 @@ public GitCommandResult initRepo(@NotNull GitRepository repository, GitCommandResult startFeature(@NotNull GitRepository repository, @NotNull String featureName, + @Nullable String baseBranch, @Nullable GitLineHandlerListener... listeners); GitCommandResult finishFeature(@NotNull GitRepository repository, - @NotNull String featureName, - @Nullable GitLineHandlerListener... listeners); - - GitCommandResult publishFeature(@NotNull GitRepository repository, @NotNull String featureName, @Nullable GitLineHandlerListener... listeners); - GitCommandResult pullFeature(@NotNull GitRepository repository, + GitCommandResult publishFeature(@NotNull GitRepository repository, @NotNull String featureName, - @NotNull GitRemote remote, @Nullable GitLineHandlerListener... listeners); - GitCommandResult trackFeature(@NotNull GitRepository repository, + GitCommandResult pullFeature(@NotNull GitRepository repository, @NotNull String featureName, @NotNull GitRemote remote, @Nullable GitLineHandlerListener... listeners); + GitCommandResult trackFeature(@NotNull GitRepository repository, + @NotNull String featureName, + @NotNull GitRemote remote, + @Nullable GitLineHandlerListener... listeners); + //release GitCommandResult startRelease(@NotNull GitRepository repository, @@ -61,22 +61,22 @@ GitCommandResult publishRelease(@NotNull GitRepository repository, @Nullable GitLineHandlerListener... listeners); GitCommandResult trackRelease(@NotNull GitRepository repository, - @NotNull String releaseName, - @Nullable GitLineHandlerListener... listeners); + @NotNull String releaseName, + @Nullable GitLineHandlerListener... listeners); //hotfix GitCommandResult startHotfix(@NotNull GitRepository repository, @NotNull String hotfixName, + @Nullable String baseBranch, @Nullable GitLineHandlerListener... listeners); GitCommandResult finishHotfix(@NotNull GitRepository repository, - @NotNull String hotfixName, - @NotNull String tagMessage, - @Nullable GitLineHandlerListener... listeners); + @NotNull String hotfixName, + @NotNull String tagMessage, + @Nullable GitLineHandlerListener... listeners); GitCommandResult publishHotfix(@NotNull GitRepository repository, @NotNull String hotfixName, @Nullable GitLineHandlerListener... listeners); - } diff --git a/src/gitflow/GitflowImpl.java b/src/gitflow/GitflowImpl.java index a8ed4e3..b9382ff 100644 --- a/src/gitflow/GitflowImpl.java +++ b/src/gitflow/GitflowImpl.java @@ -1,20 +1,25 @@ package gitflow; import com.intellij.openapi.project.Project; -import git4idea.commands.*; -import git4idea.repo.GitRemote; -import git4idea.repo.GitRepository; +import com.intellij.openapi.vfs.VirtualFile; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.List; + +import git4idea.commands.GitCommand; +import git4idea.commands.GitCommandResult; +import git4idea.commands.GitImpl; +import git4idea.commands.GitLineHandler; +import git4idea.commands.GitLineHandlerListener; +import git4idea.repo.GitRemote; +import git4idea.repo.GitRepository; /** - * - * * @author Opher Vishnia / opherv.com / opherv@gmail.com */ @@ -22,10 +27,10 @@ public class GitflowImpl extends GitImpl implements Gitflow { //we must use reflection to add this command, since the git4idea implementation doesn't expose it - private GitCommand GitflowCommand(){ - Method m= null; + private GitCommand GitflowCommand() { + Method m = null; try { - m = GitCommand.class.getDeclaredMethod("write",String.class); + m = GitCommand.class.getDeclaredMethod("write", String.class); } catch (NoSuchMethodException e) { e.printStackTrace(); } @@ -35,7 +40,7 @@ private GitCommand GitflowCommand(){ GitCommand command = null; try { - command = (GitCommand) m.invoke(null,"flow");//now its ok + command = (GitCommand) m.invoke(null, "flow");//now its ok } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { @@ -46,10 +51,10 @@ private GitCommand GitflowCommand(){ } //we must use reflection to add this command, since the git4idea implementation doesn't expose it - private static GitCommandResult run(@org.jetbrains.annotations.NotNull git4idea.commands.GitLineHandler handler){ - Method m = null; + private static GitCommandResult run(@org.jetbrains.annotations.NotNull git4idea.commands.GitLineHandler handler) { + Method m = null; try { - m = GitImpl.class.getDeclaredMethod("run",GitLineHandler.class); + m = GitImpl.class.getDeclaredMethod("run", GitLineHandler.class); } catch (NoSuchMethodException e) { e.printStackTrace(); } @@ -59,7 +64,7 @@ private static GitCommandResult run(@org.jetbrains.annotations.NotNull git4idea. GitCommandResult result = null; try { - result = (GitCommandResult ) m.invoke(null, handler);//now its ok + result = (GitCommandResult) m.invoke(null, handler);//now its ok } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { @@ -74,7 +79,7 @@ public GitCommandResult initRepo(@NotNull GitRepository repository, GitCommandResult result; - if(initOptions.isUseDefaults()) { + if (initOptions.isUseDefaults()) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitflowCommand()); h.setSilent(false); h.setStdoutSuppressed(false); @@ -83,12 +88,11 @@ public GitCommandResult initRepo(@NotNull GitRepository repository, h.addParameters("init"); h.addParameters("-d"); - result = run(h); - } - else{ + result = run(h); + } else { - final GitInitLineHandler h = new GitInitLineHandler(initOptions,repository.getProject(), repository.getRoot(), GitflowCommand()); + final GitInitLineHandler h = new GitInitLineHandler(initOptions, repository.getProject(), repository.getRoot(), GitflowCommand()); h.setSilent(false); h.setStdoutSuppressed(false); @@ -99,7 +103,7 @@ public GitCommandResult initRepo(@NotNull GitRepository repository, for (GitLineHandlerListener listener : listeners) { h.addLineListener(listener); } - result = run(h); + result = run(h); } @@ -111,6 +115,7 @@ public GitCommandResult initRepo(@NotNull GitRepository repository, public GitCommandResult startFeature(@NotNull GitRepository repository, @NotNull String featureName, + @Nullable String baseBranch, @Nullable GitLineHandlerListener... listeners) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitflowCommand()); h.setSilent(false); @@ -122,6 +127,10 @@ public GitCommandResult startFeature(@NotNull GitRepository repository, } h.addParameters(featureName); + if (baseBranch != null) { + h.addParameters(baseBranch); + } + for (GitLineHandlerListener listener : listeners) { h.addLineListener(listener); } @@ -129,8 +138,8 @@ public GitCommandResult startFeature(@NotNull GitRepository repository, } public GitCommandResult finishFeature(@NotNull GitRepository repository, - @NotNull String featureName, - @Nullable GitLineHandlerListener... listeners) { + @NotNull String featureName, + @Nullable GitLineHandlerListener... listeners) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitflowCommand()); setUrl(h, repository); @@ -157,8 +166,8 @@ public GitCommandResult finishFeature(@NotNull GitRepository repository, public GitCommandResult publishFeature(@NotNull GitRepository repository, - @NotNull String featureName, - @Nullable GitLineHandlerListener... listeners) { + @NotNull String featureName, + @Nullable GitLineHandlerListener... listeners) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitflowCommand()); setUrl(h, repository); h.setSilent(false); @@ -177,9 +186,9 @@ public GitCommandResult publishFeature(@NotNull GitRepository repository, // feature pull seems to be kind of useless. see // http://stackoverflow.com/questions/18412750/why-doesnt-git-flow-feature-pull-track public GitCommandResult pullFeature(@NotNull GitRepository repository, - @NotNull String featureName, - @NotNull GitRemote remote, - @Nullable GitLineHandlerListener... listeners) { + @NotNull String featureName, + @NotNull GitRemote remote, + @Nullable GitLineHandlerListener... listeners) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitflowCommand()); setUrl(h, repository); h.setSilent(false); @@ -195,9 +204,9 @@ public GitCommandResult pullFeature(@NotNull GitRepository repository, } public GitCommandResult trackFeature(@NotNull GitRepository repository, - @NotNull String featureName, - @NotNull GitRemote remote, - @Nullable GitLineHandlerListener... listeners) { + @NotNull String featureName, + @NotNull GitRemote remote, + @Nullable GitLineHandlerListener... listeners) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitflowCommand()); setUrl(h, repository); h.setSilent(false); @@ -248,14 +257,13 @@ public GitCommandResult finishRelease(@NotNull GitRepository repository, if (GitflowConfigurable.releaseFetchOrigin(repository.getProject())) { h.addParameters("-F"); } - if(GitflowConfigurable.pushOnReleaseFinish(repository.getProject())) { + if (GitflowConfigurable.pushOnReleaseFinish(repository.getProject())) { h.addParameters("-p"); } if (GitflowConfigurable.dontTagRelease(repository.getProject())) { h.addParameters("-n"); - } - else{ + } else { h.addParameters("-m"); h.addParameters(tagMessage); } @@ -288,8 +296,8 @@ public GitCommandResult publishRelease(@NotNull GitRepository repository, } public GitCommandResult trackRelease(@NotNull GitRepository repository, - @NotNull String releaseName, - @Nullable GitLineHandlerListener... listeners) { + @NotNull String releaseName, + @Nullable GitLineHandlerListener... listeners) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitflowCommand()); setUrl(h, repository); h.setSilent(false); @@ -308,8 +316,9 @@ public GitCommandResult trackRelease(@NotNull GitRepository repository, //hotfix public GitCommandResult startHotfix(@NotNull GitRepository repository, - @NotNull String hotfixName, - @Nullable GitLineHandlerListener... listeners) { + @NotNull String hotfixName, + @Nullable String baseBranch, + @Nullable GitLineHandlerListener... listeners) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitflowCommand()); h.setSilent(false); @@ -320,6 +329,10 @@ public GitCommandResult startHotfix(@NotNull GitRepository repository, } h.addParameters(hotfixName); + if (baseBranch != null) { + h.addParameters(baseBranch); + } + for (GitLineHandlerListener listener : listeners) { h.addLineListener(listener); } @@ -327,9 +340,9 @@ public GitCommandResult startHotfix(@NotNull GitRepository repository, } public GitCommandResult finishHotfix(@NotNull GitRepository repository, - @NotNull String hotfixName, - @NotNull String tagMessage, - @Nullable GitLineHandlerListener... listeners) { + @NotNull String hotfixName, + @NotNull String tagMessage, + @Nullable GitLineHandlerListener... listeners) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitflowCommand()); setUrl(h, repository); h.setSilent(false); @@ -346,8 +359,7 @@ public GitCommandResult finishHotfix(@NotNull GitRepository repository, if (GitflowConfigurable.dontTagHotfix(repository.getProject())) { h.addParameters("-n"); - } - else{ + } else { h.addParameters("-m"); h.addParameters(tagMessage); } @@ -378,13 +390,14 @@ public GitCommandResult publishHotfix(@NotNull GitRepository repository, return run(h); } - private void setUrl (GitLineHandler h, GitRepository repository){ - ArrayList remotes = new ArrayList(repository.getRemotes()); + private void setUrl(GitLineHandler h, GitRepository repository) { + ArrayList remotes = new ArrayList(repository.getRemotes()); //make sure a remote repository is available - if (!remotes.isEmpty()){ + if (!remotes.isEmpty()) { h.setUrl(remotes.iterator().next().getFirstUrl()); } } + } diff --git a/src/gitflow/actions/StartFeatureAction.java b/src/gitflow/actions/StartFeatureAction.java index d08f02c..8e33fde 100644 --- a/src/gitflow/actions/StartFeatureAction.java +++ b/src/gitflow/actions/StartFeatureAction.java @@ -1,53 +1,55 @@ package gitflow.actions; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; -import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.DialogWrapper; + +import org.jetbrains.annotations.NotNull; + import git4idea.commands.GitCommandResult; -import git4idea.validators.GitNewBranchNameValidator; +import gitflow.ui.GitflowStartFeatureDialog; import gitflow.ui.NotifyUtil; -import org.jetbrains.annotations.NotNull; public class StartFeatureAction extends GitflowAction { - StartFeatureAction() { super("Start Feature"); } @Override public void actionPerformed(AnActionEvent e) { - //set up context variables super.actionPerformed(e); - final String featureName = Messages.showInputDialog(myProject, "Enter the name of new feature:", "New Feature", Messages.getQuestionIcon(), "", - GitNewBranchNameValidator.newInstance(repos)); - - if (featureName!=null && !featureName.isEmpty()){ - new Task.Backgroundable(myProject,"Starting feature "+featureName,false){ - @Override - public void run(@NotNull ProgressIndicator indicator) { - GitCommandResult result = myGitflow.startFeature(repo,featureName,new GitflowErrorsListener(myProject)); + GitflowStartFeatureDialog dialog = new GitflowStartFeatureDialog(myProject); + dialog.show(); + if (dialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) return; - if (result.success()) { - String startedFeatureMessage = String.format("A new branch '%s%s' was created, based on '%s'", featurePrefix, featureName, developBranch); - NotifyUtil.notifySuccess(myProject, featureName, startedFeatureMessage); - } - else { - NotifyUtil.notifyError(myProject, "Error", "Please have a look at the Version Control console for more details"); - } + final String featureName = dialog.getNewBranchName(); + final String baseBranchName = dialog.getBaseBranchName(); - repo.update(); + new Task.Backgroundable(myProject, "Starting feature " + featureName, false) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + createFeatureBranch(baseBranchName, featureName); + } + }.queue(); + } - } - }.queue(); + private void createFeatureBranch(String baseBranchName, String featureName) { + GitflowErrorsListener errorListener = new GitflowErrorsListener(myProject); + GitCommandResult result = myGitflow.startFeature(repo, featureName, baseBranchName, errorListener); - } - else{ - Messages.showWarningDialog(myProject, "You must provide a name for the feature", "Whoops"); + if (result.success()) { + String startedFeatureMessage = String.format("A new branch '%s%s' was created, based on '%s'", featurePrefix, featureName, baseBranchName); + NotifyUtil.notifySuccess(myProject, featureName, startedFeatureMessage); + } else { + NotifyUtil.notifyError(myProject, "Error", "Please have a look at the Version Control console for more details"); } + repo.update(); + virtualFileMananger.asyncRefresh(null); //update editors } } \ No newline at end of file diff --git a/src/gitflow/actions/StartHotfixAction.java b/src/gitflow/actions/StartHotfixAction.java index e898f21..dff5bb6 100644 --- a/src/gitflow/actions/StartHotfixAction.java +++ b/src/gitflow/actions/StartHotfixAction.java @@ -3,11 +3,14 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; -import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.DialogWrapper; + +import org.jetbrains.annotations.NotNull; + import git4idea.commands.GitCommandResult; -import git4idea.validators.GitNewBranchNameValidator; +import gitflow.ui.GitflowStartHotfixDialog; import gitflow.ui.NotifyUtil; -import org.jetbrains.annotations.NotNull; + public class StartHotfixAction extends GitflowAction { @@ -19,34 +22,34 @@ public class StartHotfixAction extends GitflowAction { public void actionPerformed(AnActionEvent e) { super.actionPerformed(e); - final String hotfixName = Messages.showInputDialog(myProject, "Enter the name of the new hotfix:", "New Hotfix", Messages.getQuestionIcon(), "", - GitNewBranchNameValidator.newInstance(repos)); - final GitflowErrorsListener errorLineHandler = new GitflowErrorsListener(myProject); + GitflowStartHotfixDialog dialog = new GitflowStartHotfixDialog(myProject); + dialog.show(); - //must insert hotfix name - if (hotfixName!=null && !hotfixName.isEmpty()){ - new Task.Backgroundable(myProject,"Starting hotfix "+hotfixName,false){ - @Override - public void run(@NotNull ProgressIndicator indicator) { - GitCommandResult result = myGitflow.startHotfix(repo, hotfixName, errorLineHandler); + if (dialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) return; - if (result.success()) { - String startedHotfixMessage = String.format("A new hotfix '%s%s' was created, based on '%s'", hotfixPrefix, hotfixName, masterBranch); - NotifyUtil.notifySuccess(myProject, hotfixName, startedHotfixMessage); - } - else { - NotifyUtil.notifyError(myProject, "Error", "Please have a look at the Version Control console for more details"); - } + final String hotfixName = dialog.getNewBranchName(); + final String baseBranchName = dialog.getBaseBranchName(); - repo.update(); + new Task.Backgroundable(myProject, "Starting hotfix " + hotfixName, false) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + createHotfixBranch(baseBranchName, hotfixName); + } + }.queue(); + } - } - }.queue(); + private void createHotfixBranch(String baseBranchName, String hotfixBranchName) { + GitflowErrorsListener errorListener = new GitflowErrorsListener(myProject); + GitCommandResult result = myGitflow.startHotfix(repo, hotfixBranchName, baseBranchName, errorListener); - } - else{ - Messages.showWarningDialog(myProject, "You must provide a name for the hotfix", "Whoops"); + if (result.success()) { + String startedHotfixMessage = String.format("A new hotfix '%s%s' was created, based on '%s'", + hotfixPrefix, hotfixBranchName, baseBranchName); + NotifyUtil.notifySuccess(myProject, hotfixBranchName, startedHotfixMessage); + } else { + NotifyUtil.notifyError(myProject, "Error", "Please have a look at the Version Control console for more details"); } + repo.update(); } } \ No newline at end of file diff --git a/src/gitflow/ui/AbstractBranchStartDialog.form b/src/gitflow/ui/AbstractBranchStartDialog.form new file mode 100644 index 0000000..44c0611 --- /dev/null +++ b/src/gitflow/ui/AbstractBranchStartDialog.form @@ -0,0 +1,45 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/gitflow/ui/AbstractBranchStartDialog.java b/src/gitflow/ui/AbstractBranchStartDialog.java new file mode 100644 index 0000000..9ab59af --- /dev/null +++ b/src/gitflow/ui/AbstractBranchStartDialog.java @@ -0,0 +1,130 @@ +package gitflow.ui; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.ValidationInfo; + +import java.util.List; + +import javax.swing.*; + +import git4idea.repo.GitRepository; +import gitflow.Gitflow; +import gitflow.GitflowBranchUtil; + +/** + * Base class for a "start" dialog. Such a dialog prompts the user to enter a name for a new branch + * and select a base branch. See {@link GitflowStartFeatureDialog} for an example implementation. + */ +public abstract class AbstractBranchStartDialog extends DialogWrapper { + + private JPanel contentPane; + private JTextField branchNameTextField; + private JComboBox branchFromCombo; + private JLabel branchNameLabel; + + private Project project; + private GitflowBranchUtil gitflowBranchUtil; + + public AbstractBranchStartDialog(Project project) { + super(project, false); + this.project = project; + this.gitflowBranchUtil = new GitflowBranchUtil(project); + + init(); + final String label = getLabel(); + setTitle("New " + label + "..."); + branchNameLabel.setText(String.format("Enter a name for the new %s...", label)); + setModal(true); + + branchFromCombo.setModel(createBranchComboModel()); + } + + @Override + public JComponent getPreferredFocusedComponent() { + return branchNameTextField; + } + + /** + * @return The name of the new branch as specified by the user + */ + public String getNewBranchName() { + return branchNameTextField.getText().trim(); + } + + /** + * @return The name of the base branch (the branch on which the new hotfix or feature should be + * based on) + */ + public String getBaseBranchName() { + ComboEntry selectedBranch = (ComboEntry) branchFromCombo.getModel().getSelectedItem(); + return selectedBranch.getBranchName(); + } + + /** + * @return The label for this dialog (e.g. "hotfix" or "feature"). Will be used for the window + * title and other labels. + */ + protected abstract String getLabel(); + + /** + * @return The name of the default branch, i.e. the branch that is selected by default when + * opening the dialog. + */ + protected abstract String getDefaultBranch(); + + protected Project getProject() { + return this.project; + } + + @Override + protected ValidationInfo doValidate() { + boolean isBranchNameSpecified = branchNameTextField.getText().trim().length() > 0; + if (!isBranchNameSpecified) { + return new ValidationInfo("No name specified", branchNameTextField); + } else { + return null; + } + } + + @Override + protected JComponent createCenterPanel() { + return contentPane; + } + + private ComboBoxModel createBranchComboModel() { + final List branchList = gitflowBranchUtil.getLocalBranchNames(); + final String defaultBranch = getDefaultBranch(); + branchList.remove(defaultBranch); + + ComboEntry[] entries = new ComboEntry[branchList.size() + 1]; + entries[0] = new ComboEntry(defaultBranch, defaultBranch + " (default)"); + for (int i = 1; i <= branchList.size(); i++) { + String branchName = branchList.get(i - 1); + entries[i] = new ComboEntry(branchName, branchName); + } + + return new DefaultComboBoxModel(entries); + } + + /** + * An entry for the branch selection dropdown/combo. + */ + private static class ComboEntry { + private String branchName, label; + + public ComboEntry(String branchName, String label) { + this.branchName = branchName; + this.label = label; + } + + public String getBranchName() { + return branchName; + } + + @Override + public String toString() { + return label; + } + } +} diff --git a/src/gitflow/ui/GitflowStartFeatureDialog.java b/src/gitflow/ui/GitflowStartFeatureDialog.java new file mode 100644 index 0000000..ded81b3 --- /dev/null +++ b/src/gitflow/ui/GitflowStartFeatureDialog.java @@ -0,0 +1,22 @@ +package gitflow.ui; + +import com.intellij.openapi.project.Project; + +import gitflow.GitflowConfigUtil; + +public class GitflowStartFeatureDialog extends AbstractBranchStartDialog { + + public GitflowStartFeatureDialog(Project project) { + super(project); + } + + @Override + protected String getLabel() { + return "feature"; + } + + @Override + protected String getDefaultBranch() { + return GitflowConfigUtil.getDevelopBranch(getProject()); + } +} diff --git a/src/gitflow/ui/GitflowStartHotfixDialog.java b/src/gitflow/ui/GitflowStartHotfixDialog.java new file mode 100644 index 0000000..101b6f5 --- /dev/null +++ b/src/gitflow/ui/GitflowStartHotfixDialog.java @@ -0,0 +1,22 @@ +package gitflow.ui; + +import com.intellij.openapi.project.Project; + +import gitflow.GitflowConfigUtil; + +public class GitflowStartHotfixDialog extends AbstractBranchStartDialog { + + public GitflowStartHotfixDialog(Project project) { + super(project); + } + + @Override + protected String getLabel() { + return "hotfix"; + } + + @Override + protected String getDefaultBranch() { + return GitflowConfigUtil.getMasterBranch(getProject()); + } +}