CPP-2671 Correctly support configurations without build targets in "Run Another Configuration" tasks

This commit is contained in:
Vyacheslav Karpukhin
2015-03-23 14:39:27 +01:00
parent 11c8cb8233
commit ccc6875bc4
4 changed files with 110 additions and 70 deletions
@@ -60,6 +60,7 @@ import java.util.List;
public class ExecutionManagerImpl extends ExecutionManager implements Disposable {
public static final Key<Object> EXECUTION_SESSION_ID_KEY = Key.create("EXECUTION_SESSION_ID_KEY");
public static final Key<Boolean> EXECUTION_SKIP_RUN = Key.create("EXECUTION_SKIP_RUN");
private static final Logger LOG = Logger.getInstance(ExecutionManagerImpl.class);
private static final ProcessHandler[] EMPTY_PROCESS_HANDLERS = new ProcessHandler[0];
@@ -169,17 +170,24 @@ public class ExecutionManagerImpl extends ExecutionManager implements Disposable
}
protected void doRun(@NotNull final ExecutionEnvironment environment, @NotNull final Runnable startRunnable) {
// important! Do not use DumbService.smartInvokeLater here because it depends on modality state
// and execution of startRunnable could be skipped if modality state check fails
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (!myProject.isDisposed()) {
DumbService.getInstance(myProject).runWhenSmart(startRunnable);
Boolean allowSkipRun = environment.getUserData(EXECUTION_SKIP_RUN);
if (allowSkipRun != null && allowSkipRun) {
environment.getProject().getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(environment.getExecutor().getId(),
environment);
}
else {
// important! Do not use DumbService.smartInvokeLater here because it depends on modality state
// and execution of startRunnable could be skipped if modality state check fails
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (!myProject.isDisposed()) {
DumbService.getInstance(myProject).runWhenSmart(startRunnable);
}
}
}
});
});
}
}
@Override
@@ -31,6 +31,7 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Disposer;
@@ -193,75 +194,78 @@ extends BeforeRunTaskProvider<RunConfigurationBeforeRunProvider.RunConfigurableB
return false;
}
else {
return doRun(executorId, environment);
}
}
beforeRun(environment);
protected boolean doRun(@NotNull final String executorId, @NotNull final ExecutionEnvironment environment) {
final Semaphore targetDone = new Semaphore();
final Ref<Boolean> result = new Ref<Boolean>(false);
final Disposable disposable = Disposer.newDisposable();
final Semaphore targetDone = new Semaphore();
final Ref<Boolean> result = new Ref<Boolean>(false);
final Disposable disposable = Disposer.newDisposable();
myProject.getMessageBus().connect(disposable).subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter() {
@Override
public void processStartScheduled(final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
targetDone.down();
}
}
@Override
public void processNotStarted(final String executorIdLocal, @NotNull final ExecutionEnvironment environmentLocal) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
onProcessNotStarted(environment, result, targetDone);
}
}
@Override
public void processStarted(final String executorIdLocal,
@NotNull final ExecutionEnvironment environmentLocal,
@NotNull final ProcessHandler handler) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
handler.addProcessListener(new ProcessAdapter() {
@Override
public void processTerminated(ProcessEvent event) {
result.set(event.getExitCode() == 0);
targetDone.up();
}
});
}
}
});
try {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
myProject.getMessageBus().connect(disposable).subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter() {
@Override
public void run() {
try {
environment.getRunner().execute(environment);
}
catch (ExecutionException e) {
targetDone.up();
LOG.error(e);
public void processStartScheduled(final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
targetDone.down();
}
}
}, ModalityState.NON_MODAL);
}
catch (Exception e) {
LOG.error(e);
@Override
public void processNotStarted(final String executorIdLocal, @NotNull final ExecutionEnvironment environmentLocal) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
Boolean skipRun = environment.getUserData(ExecutionManagerImpl.EXECUTION_SKIP_RUN);
if (skipRun != null && skipRun) {
result.set(true);
}
targetDone.up();
}
}
@Override
public void processStarted(final String executorIdLocal,
@NotNull final ExecutionEnvironment environmentLocal,
@NotNull final ProcessHandler handler) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
handler.addProcessListener(new ProcessAdapter() {
@Override
public void processTerminated(ProcessEvent event) {
result.set(event.getExitCode() == 0);
targetDone.up();
}
});
}
}
});
try {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
try {
environment.getRunner().execute(environment);
}
catch (ExecutionException e) {
targetDone.up();
LOG.error(e);
}
}
}, ModalityState.NON_MODAL);
}
catch (Exception e) {
LOG.error(e);
Disposer.dispose(disposable);
return false;
}
targetDone.waitFor();
Disposer.dispose(disposable);
return false;
return result.get();
}
targetDone.waitFor();
Disposer.dispose(disposable);
return result.get();
}
protected void onProcessNotStarted(@NotNull ExecutionEnvironment environment, @NotNull Ref<Boolean> result,
@NotNull Semaphore targetDone) {
targetDone.up();
private static void beforeRun(@NotNull ExecutionEnvironment environment) {
for (RunConfigurationBeforeRunProviderDelegate delegate : Extensions.getExtensions(RunConfigurationBeforeRunProviderDelegate.EP_NAME)) {
delegate.beforeRun(environment);
}
}
public class RunConfigurableBeforeRunTask extends BeforeRunTask<RunConfigurableBeforeRunTask> {
@@ -0,0 +1,26 @@
/*
* Copyright 2000-2015 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.execution.impl;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.extensions.ExtensionPointName;
import org.jetbrains.annotations.NotNull;
public interface RunConfigurationBeforeRunProviderDelegate {
ExtensionPointName<RunConfigurationBeforeRunProviderDelegate> EP_NAME = ExtensionPointName.create("com.intellij.runConfigurationBeforeRunProviderDelegate");
void beforeRun(@NotNull ExecutionEnvironment environment);
}
@@ -242,5 +242,7 @@
<extensionPoint qualifiedName="com.intellij.diff.DiffTool" interface="com.intellij.diff.DiffTool"/>
<extensionPoint name="testStatusListener" interface="com.intellij.execution.testframework.TestStatusListener"/>
<extensionPoint name="runConfigurationBeforeRunProviderDelegate" interface="com.intellij.execution.impl.RunConfigurationBeforeRunProviderDelegate"/>
</extensionPoints>
</idea-plugin>