diff --git a/platform/lang-impl/src/com/intellij/tools/Tool.java b/platform/lang-impl/src/com/intellij/tools/Tool.java index 26be341b6fae..5e7b5b7e222c 100644 --- a/platform/lang-impl/src/com/intellij/tools/Tool.java +++ b/platform/lang-impl/src/com/intellij/tools/Tool.java @@ -21,9 +21,12 @@ import com.intellij.execution.RunnerRegistry; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.executors.DefaultRunExecutor; import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.process.ProcessListener; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ExecutionEnvironmentBuilder; import com.intellij.execution.runners.ProgramRunner; +import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.util.ExecutionErrorDialog; import com.intellij.ide.macro.Macro; import com.intellij.ide.macro.MacroManager; @@ -262,9 +265,16 @@ public class Tool implements SchemeElement { } public void execute(AnActionEvent event, DataContext dataContext, long executionId) { + execute(event, dataContext, executionId, null); + } + + /** + * @return true if task has been started successfully + */ + public boolean execute(AnActionEvent event, DataContext dataContext, long executionId, @Nullable final ProcessListener processListener) { final Project project = PlatformDataKeys.PROJECT.getData(dataContext); if (project == null) { - return; + return false; } FileDocumentManager.getInstance().saveAllDocuments(); try { @@ -275,21 +285,34 @@ public class Tool implements SchemeElement { ExecutionEnvironment executionEnvironment = new ExecutionEnvironmentBuilder().setRunProfile(profile).setProject(project).build(); executionEnvironment.setExecutionId(executionId); - runner.execute(new DefaultRunExecutor(), executionEnvironment); + runner.execute(new DefaultRunExecutor(), executionEnvironment, new ProgramRunner.Callback() { + @Override + public void processStarted(RunContentDescriptor descriptor) { + ProcessHandler processHandler = descriptor.getProcessHandler(); + if (processHandler != null && processListener != null) { + processHandler.addProcessListener(processListener); + } + } + }); + return true; } else { GeneralCommandLine commandLine = createCommandLine(dataContext); if (commandLine == null) { - return; + return false; } OSProcessHandler handler = new OSProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString()); handler.addProcessListener(new ToolProcessAdapter(project, synchronizeAfterExecution(), getName())); + if (processListener != null) + handler.addProcessListener(processListener); handler.startNotify(); + return true; } } catch (ExecutionException ex) { ExecutionErrorDialog.show(ex, ToolsBundle.message("tools.process.start.error"), project); } + return false; } @Nullable diff --git a/platform/lang-impl/src/com/intellij/tools/ToolAction.java b/platform/lang-impl/src/com/intellij/tools/ToolAction.java index c47b0a5405aa..884c2e23ec79 100644 --- a/platform/lang-impl/src/com/intellij/tools/ToolAction.java +++ b/platform/lang-impl/src/com/intellij/tools/ToolAction.java @@ -16,11 +16,13 @@ package com.intellij.tools; +import com.intellij.execution.process.ProcessListener; import com.intellij.ide.macro.MacroManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.project.DumbAware; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -37,7 +39,7 @@ public class ToolAction extends AnAction implements DumbAware { } public void actionPerformed(AnActionEvent e) { - runTool(myActionId, e.getDataContext(), e, 0L); + runTool(myActionId, e.getDataContext(), e, 0L, null); } @Override @@ -62,18 +64,18 @@ public class ToolAction extends AnAction implements DumbAware { return ToolsProvider.getAllTools(); } - static void runTool(String actionId, DataContext context, long executionId) { - runTool(actionId, context, null, executionId); - } - static void runTool(String actionId, DataContext context) { - runTool(actionId, context, null, 0L); + runTool(actionId, context, null, 0L, null); } - static void runTool(String actionId, DataContext context, AnActionEvent e, long executionId) { + /** + * @return true if task has been started successfully + */ + static boolean runTool(String actionId, DataContext context, @Nullable AnActionEvent e, long executionId, @Nullable ProcessListener processListener) { Tool tool = findTool(actionId, context); if (tool != null) { - tool.execute(e, new HackyDataContext(context, e), executionId); + return tool.execute(e, new HackyDataContext(context, e), executionId, processListener); } + return false; } } diff --git a/platform/lang-impl/src/com/intellij/tools/ToolBeforeRunTask.java b/platform/lang-impl/src/com/intellij/tools/ToolBeforeRunTask.java index 9008262ea6b9..aef500c1a94e 100644 --- a/platform/lang-impl/src/com/intellij/tools/ToolBeforeRunTask.java +++ b/platform/lang-impl/src/com/intellij/tools/ToolBeforeRunTask.java @@ -16,8 +16,13 @@ package com.intellij.tools; import com.intellij.execution.BeforeRunTask; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.util.ui.UIUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.concurrency.Semaphore; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -25,6 +30,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; public class ToolBeforeRunTask extends BeforeRunTask { + private static final Logger LOG = Logger.getInstance(ToolBeforeRunTask.class); @NonNls private final static String ACTION_ID_ATTRIBUTE = "actionId"; private String myToolActionId; @@ -64,14 +70,35 @@ public class ToolBeforeRunTask extends BeforeRunTask { return (ToolBeforeRunTask)super.clone(); } - public void execute(final DataContext context, final long executionId) { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { + public boolean execute(final DataContext context, final long executionId) { + final Semaphore targetDone = new Semaphore(); + final boolean[] result = new boolean[1]; - @Override - public void run() { - ToolAction.runTool(myToolActionId, context, executionId); - } - }); + try { + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + @Override + public void run() { + targetDone.down(); + boolean runToolResult = ToolAction.runTool(myToolActionId, context, null, executionId, new ProcessAdapter() { + @Override + public void processTerminated(ProcessEvent event) { + result[0] = event.getExitCode() == 0; + targetDone.up(); + } + }); + if (!runToolResult) { + result[0] = false; + targetDone.up(); + } + } + }, ModalityState.NON_MODAL); + } + catch (Exception e) { + LOG.error(e); + return false; + } + targetDone.waitFor(); + return result[0]; } @Nullable diff --git a/platform/lang-impl/src/com/intellij/tools/ToolBeforeRunTaskProvider.java b/platform/lang-impl/src/com/intellij/tools/ToolBeforeRunTaskProvider.java index e6f8879a2f97..828e7add5cc7 100644 --- a/platform/lang-impl/src/com/intellij/tools/ToolBeforeRunTaskProvider.java +++ b/platform/lang-impl/src/com/intellij/tools/ToolBeforeRunTaskProvider.java @@ -101,7 +101,6 @@ public class ToolBeforeRunTaskProvider extends BeforeRunTaskProvider