IDEA-91212 Launch does not wait for external tools to complete (external tool configured as 'Before launch' for the Run configuration)

This commit is contained in:
Vassiliy Kudryashov
2013-03-03 21:20:24 +04:00
parent 4043b68d3e
commit b1386a57cc
4 changed files with 72 additions and 21 deletions
@@ -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 <code>true</code> 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
@@ -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 <code>true</code> 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;
}
}
@@ -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<ToolBeforeRunTask> {
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<ToolBeforeRunTask> {
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
@@ -101,7 +101,6 @@ public class ToolBeforeRunTaskProvider extends BeforeRunTaskProvider<ToolBeforeR
if (!task.isExecutable()) {
return false;
}
task.execute(context, env.getExecutionId());
return true;
return task.execute(context, env.getExecutionId());
}
}