Support debug of non-jvm Gradle tasks in External System

GitOrigin-RevId: 2d9b816110abf38cbc9159558e696e729e0f4025
This commit is contained in:
Kirill Shmakov
2019-09-27 08:31:42 +00:00
committed by intellij-monorepo-bot
parent b8ec126655
commit cea74ff27f
18 changed files with 745 additions and 483 deletions
@@ -29,6 +29,7 @@
<orderEntry type="module" module-name="intellij.platform.vcs.impl" />
<orderEntry type="library" name="NanoXML" level="project" />
<orderEntry type="library" name="jackson-databind" level="project" />
<orderEntry type="module" module-name="intellij.platform.debugger.impl" />
</component>
<component name="copyright">
<Base>
@@ -16,8 +16,16 @@
package com.intellij.openapi.externalSystem.service.execution;
import com.intellij.build.BuildView;
import com.intellij.debugger.DebugEnvironment;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.DefaultDebugEnvironment;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.JavaDebugProcess;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.impl.GenericDebuggerRunner;
import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.configurations.RemoteConnection;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunProfileState;
@@ -26,8 +34,14 @@ import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.ide.ui.EditorOptionsTopHitProvider;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugProcessStarter;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -39,6 +53,8 @@ import java.net.ServerSocket;
public class ExternalSystemTaskDebugRunner extends GenericDebuggerRunner {
static final Logger LOG = Logger.getInstance(ExternalSystemTaskDebugRunner.class);
private static final String ATTACH_VM_FAILED = "ATTACH_VM_FAILED";
@NotNull
@Override
public String getRunnerId() {
@@ -54,11 +70,11 @@ public class ExternalSystemTaskDebugRunner extends GenericDebuggerRunner {
@Override
protected RunContentDescriptor createContentDescriptor(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment)
throws ExecutionException {
if (state instanceof ExternalSystemRunConfiguration.MyRunnableState) {
ExternalSystemRunConfiguration.MyRunnableState myRunnableState = (ExternalSystemRunConfiguration.MyRunnableState)state;
if (state instanceof ExternalSystemRunnableState) {
ExternalSystemRunnableState myRunnableState = (ExternalSystemRunnableState)state;
int port = myRunnableState.getDebugPort();
if (port > 0) {
RunContentDescriptor runContentDescriptor = doGetRunContentDescriptor(myRunnableState, environment, port);
RunContentDescriptor runContentDescriptor = doGetRunContentDescriptor(myRunnableState, environment);
if (runContentDescriptor == null) return null;
ProcessHandler processHandler = runContentDescriptor.getProcessHandler();
@@ -76,18 +92,16 @@ public class ExternalSystemTaskDebugRunner extends GenericDebuggerRunner {
LOG.warn(String.format(
"Can't attach debugger to external system task execution. Reason: invalid run profile state is provided"
+ "- expected '%s' but got '%s'",
ExternalSystemRunConfiguration.MyRunnableState.class.getName(), state.getClass().getName()
ExternalSystemRunnableState.class.getName(), state.getClass().getName()
));
}
return null;
}
@Nullable
private RunContentDescriptor doGetRunContentDescriptor(@NotNull ExternalSystemRunConfiguration.MyRunnableState state,
@NotNull ExecutionEnvironment environment,
int port) throws ExecutionException {
RemoteConnection connection = new RemoteConnection(true, "127.0.0.1", String.valueOf(port), true);
RunContentDescriptor runContentDescriptor = attachVirtualMachine(state, environment, connection, true);
private RunContentDescriptor doGetRunContentDescriptor(@NotNull ExternalSystemRunnableState state,
@NotNull ExecutionEnvironment environment) throws ExecutionException {
RunContentDescriptor runContentDescriptor = createProcessToDebug(state, environment);
if (runContentDescriptor == null) return null;
state.setContentDescriptor(runContentDescriptor);
@@ -109,4 +123,55 @@ public class ExternalSystemTaskDebugRunner extends GenericDebuggerRunner {
descriptor.setRunnerLayoutUi(runContentDescriptor.getRunnerLayoutUi());
return descriptor;
}
@NotNull
private XDebugProcess jvmProcessToDebug(@NotNull XDebugSession session,
ExternalSystemRunnableState state,
@NotNull ExecutionEnvironment env) throws ExecutionException {
RemoteConnection connection = new RemoteConnection(true, "127.0.0.1", String.valueOf(state.getDebugPort()), true);
DebugEnvironment environment = new DefaultDebugEnvironment(env, state, connection, DebugEnvironment.LOCAL_START_TIMEOUT);
final DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(env.getProject()).attachVirtualMachine(environment);
if (debuggerSession == null) {
throw new ExecutionException(ATTACH_VM_FAILED);
}
final DebugProcessImpl debugProcess = debuggerSession.getProcess();
XDebugSessionImpl sessionImpl = (XDebugSessionImpl)session;
ExecutionResult executionResult = debugProcess.getExecutionResult();
sessionImpl.addExtraActions(executionResult.getActions());
if (executionResult instanceof DefaultExecutionResult) {
sessionImpl.addRestartActions(((DefaultExecutionResult)executionResult).getRestartActions());
}
return JavaDebugProcess.create(session, debuggerSession);
}
@Nullable
private RunContentDescriptor createProcessToDebug(ExternalSystemRunnableState state,
@NotNull ExecutionEnvironment env) throws ExecutionException {
RunContentDescriptor result;
try {
result = XDebuggerManager.getInstance(env.getProject()).startSession(env, new XDebugProcessStarter() {
@Override
@NotNull
public XDebugProcess start(@NotNull XDebugSession session) throws ExecutionException {
XDebugProcess nonJvmDebugProcess = state.startDebugProcess(session, env);
return nonJvmDebugProcess != null ? nonJvmDebugProcess : jvmProcessToDebug(session, state, env);
}
}).getRunContentDescriptor();
}
catch (ExecutionException e) {
if (!e.getMessage().equals(ATTACH_VM_FAILED)) {
throw e;
}
result = null;
}
return result;
}
}
@@ -10,7 +10,6 @@ import com.intellij.debugger.engine.managerThread.DebuggerCommand;
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ProgramRunnerUtil;
import com.intellij.execution.RunManager;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.impl.ConsoleViewImpl;
@@ -18,8 +17,6 @@ import com.intellij.execution.impl.EditorHyperlinkSupport;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.remote.RemoteConfiguration;
import com.intellij.execution.remote.RemoteConfigurationType;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
import com.intellij.execution.runners.ProgramRunner;
@@ -32,6 +29,8 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.markup.HighlighterLayer;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.externalSystem.debugger.DebuggerBackendExtension;
import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.StreamUtil;
@@ -64,9 +63,9 @@ class ForkedDebuggerThread extends Thread {
private final ExecutionConsole myMainExecutionConsole;
ForkedDebuggerThread(@NotNull ProcessHandler mainProcessHandler,
@NotNull RunContentDescriptor mainRunContentDescriptor,
@NotNull ServerSocket socket,
@NotNull Project project) {
@NotNull RunContentDescriptor mainRunContentDescriptor,
@NotNull ServerSocket socket,
@NotNull Project project) {
super("external task forked debugger runner");
setDaemon(true);
mySocket = socket;
@@ -122,6 +121,16 @@ class ForkedDebuggerThread extends Thread {
// the stream can not be closed in the current thread
//noinspection IOResourceOpenedButNotSafelyClosed
DataInputStream stream = new DataInputStream(accept.getInputStream());
String debuggerId = stream.readUTF();
String processName = stream.readUTF();
String processParameters = stream.readUTF();
if (processParameters.startsWith(ForkedDebuggerHelper.FINISH_PARAMS)) {
removeTerminatedForks(processName, processParameters, accept, stream);
return;
}
myMainProcessHandler.addProcessListener(new ProcessAdapter() {
@Override
public void processTerminated(@NotNull ProcessEvent event) {
@@ -129,76 +138,78 @@ class ForkedDebuggerThread extends Thread {
StreamUtil.closeStream(accept);
}
});
int signal = stream.readInt();
String processName = stream.readUTF();
if (signal > 0) {
String debugPort = String.valueOf(signal);
attachVM(myProject, processName, debugPort, new ProgramRunner.Callback() {
@Override
public void processStarted(RunContentDescriptor descriptor) {
// select tab for the forked process only when it has been suspended
descriptor.setSelectContentWhenAdded(false);
// restore selection of the 'main' tab to avoid flickering of the reused content tab when no suspend events occur
ProcessHandler forkedProcessHandler = descriptor.getProcessHandler();
if (forkedProcessHandler != null) {
myMainProcessHandler.addProcessListener(new ProcessAdapter() {
@Override
public void processWillTerminate(@NotNull ProcessEvent event, boolean willBeDestroyed) {
myMainProcessHandler.removeProcessListener(this);
terminateForkedProcess(forkedProcessHandler);
}
});
forkedProcessHandler.addProcessListener(new MyForkedProcessListener(descriptor, processName));
try {
accept.getOutputStream().write(0);
stream.close();
}
catch (IOException e) {
ExternalSystemTaskDebugRunner.LOG.debug(e);
}
for (DebuggerBackendExtension extension : DebuggerBackendExtension.EP_NAME.getExtensionList()) {
if (extension.id().equals(debuggerId)) {
RunnerAndConfigurationSettings settings = extension.debugConfigurationSettings(myProject, processName, processParameters);
runDebugConfiguration(settings, new ProgramRunner.Callback() {
@Override
public void processStarted(RunContentDescriptor descriptor) {
handleStartedDebugConfiguration(descriptor, processName, accept, stream);
}
}
});
}
else if (signal == 0) {
// remove content for terminated forked processes
ApplicationManager.getApplication().invokeLater(() -> {
final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
ContentManager contentManager = toolWindowManager.getToolWindow(ToolWindowId.DEBUG).getContentManager();
Content content = contentManager.findContent(processName);
if (content != null) {
RunContentDescriptor descriptor = content.getUserData(RunContentDescriptor.DESCRIPTOR_KEY);
if (descriptor != null) {
ProcessHandler handler = descriptor.getProcessHandler();
if (handler != null) {
handler.destroyProcess();
}
}
}
try {
accept.getOutputStream().write(0);
stream.close();
}
catch (IOException e) {
ExternalSystemTaskDebugRunner.LOG.debug(e);
}
});
});
break;
}
}
}
private static void attachVM(@NotNull Project project, String runConfigName, @NotNull String debugPort, ProgramRunner.Callback callback) {
RunnerAndConfigurationSettings runSettings = RunManager.getInstance(project).createConfiguration(runConfigName, RemoteConfigurationType.class);
runSettings.setActivateToolWindowBeforeRun(false);
RemoteConfiguration configuration = (RemoteConfiguration)runSettings.getConfiguration();
configuration.HOST = "localhost";
configuration.PORT = debugPort;
configuration.USE_SOCKET_TRANSPORT = true;
configuration.SERVER_MODE = true;
private void unblockRemote(Socket socket, DataInputStream inputStream) {
try {
socket.getOutputStream().write(0);
inputStream.close();
}
catch (IOException e) {
ExternalSystemTaskDebugRunner.LOG.debug(e);
}
}
private void handleStartedDebugConfiguration(RunContentDescriptor descriptor,
String processName,
Socket socket,
DataInputStream inputStream) {
// select tab for the forked process only when it has been suspended
descriptor.setSelectContentWhenAdded(false);
// restore selection of the 'main' tab to avoid flickering of the reused content tab when no suspend events occur
ProcessHandler forkedProcessHandler = descriptor.getProcessHandler();
if (forkedProcessHandler != null) {
myMainProcessHandler.addProcessListener(new ProcessAdapter() {
@Override
public void processWillTerminate(@NotNull ProcessEvent event, boolean willBeDestroyed) {
myMainProcessHandler.removeProcessListener(this);
terminateForkedProcess(forkedProcessHandler);
}
});
forkedProcessHandler.addProcessListener(new MyForkedProcessListener(descriptor, processName));
unblockRemote(socket, inputStream);
}
}
private void removeTerminatedForks(@NotNull String processName,
@NotNull String processParams,
Socket socket,
DataInputStream inputStream) {
ApplicationManager.getApplication().invokeLater(() -> {
final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
ContentManager contentManager = toolWindowManager.getToolWindow(ToolWindowId.DEBUG).getContentManager();
Content content = contentManager.findContent(processName);
if (content != null) {
RunContentDescriptor descriptor = content.getUserData(RunContentDescriptor.DESCRIPTOR_KEY);
if (descriptor != null) {
ProcessHandler handler = descriptor.getProcessHandler();
if (handler != null) {
handler.destroyProcess();
}
}
}
unblockRemote(socket, inputStream);
});
}
private static void runDebugConfiguration(@NotNull RunnerAndConfigurationSettings runSettings, ProgramRunner.Callback callback) {
try {
runSettings.setActivateToolWindowBeforeRun(false);
ExecutionEnvironment environment = ExecutionEnvironmentBuilder.create(DefaultDebugExecutor.getDebugExecutorInstance(), runSettings)
.contentToReuse(null)
.dataContext(null)
@@ -339,7 +350,8 @@ class ForkedDebuggerThread extends Thread {
debugProcess.stop(true);
}
});
} else {
}
else {
processHandler.destroyProcess();
}
}
@@ -0,0 +1,43 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.externalSystem.debugger;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Provides ability to preconfigure tasks run by external system and to attach them with debugger.
*/
public interface DebuggerBackendExtension {
ExtensionPointName<DebuggerBackendExtension> EP_NAME = ExtensionPointName.create("com.intellij.externalSystem.debuggerBackend");
String id();
default List<String> initializationCode(@NotNull String dispatchPort, @NotNull String parameters) {
return new ArrayList();
}
RunnerAndConfigurationSettings debugConfigurationSettings(@NotNull Project project,
@NotNull String processName,
@NotNull String processParameters);
default HashMap<String, String> splitParameters(@NotNull String processParameters) {
HashMap<String, String> result = new HashMap();
final String[] envVars = processParameters.split(ForkedDebuggerHelper.PARAMETERS_SEPARATOR);
for (String envVar : envVars) {
final int idx = envVar.indexOf('=');
if (idx > -1) {
result.put(envVar.substring(0, idx), idx < envVar.length() - 1 ? envVar.substring(idx + 1) : "");
}
}
return result;
}
}
@@ -20,5 +20,6 @@
<orderEntry type="library" name="kotlin-reflect" level="project" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer.annotations" />
<orderEntry type="module" module-name="intellij.platform.debugger" />
</component>
</module>
@@ -2,51 +2,29 @@
package com.intellij.openapi.externalSystem.service.execution;
import com.intellij.build.*;
import com.intellij.build.events.BuildEvent;
import com.intellij.build.events.FailureResult;
import com.intellij.build.events.impl.FinishBuildEventImpl;
import com.intellij.build.events.impl.StartBuildEventImpl;
import com.intellij.build.events.impl.SuccessResultImpl;
import com.intellij.diagnostic.logging.LogConfigurationPanel;
import com.intellij.execution.*;
import com.intellij.execution.configurations.*;
import com.intellij.execution.console.DuplexConsoleView;
import com.intellij.execution.impl.ConsoleViewImpl;
import com.intellij.execution.impl.ExecutionManagerImpl;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.FakeRerunAction;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.FoldingModel;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.execution.ExternalSystemExecutionConsoleManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationEvent;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter;
import com.intellij.openapi.externalSystem.model.task.event.ExternalSystemBuildEvent;
import com.intellij.openapi.externalSystem.model.task.event.ExternalSystemTaskExecutionEvent;
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemExecuteTaskTask;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.options.SettingsEditorGroup;
@@ -59,10 +37,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScopes;
import com.intellij.util.ArrayUtil;
import com.intellij.util.net.NetUtils;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.xmlb.Accessor;
import com.intellij.util.xmlb.SerializationFilter;
import com.intellij.util.xmlb.XmlSerializer;
@@ -72,31 +47,24 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.util.Collections;
import static com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper.DEBUG_FORK_SOCKET_PARAM;
import static com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper.DEBUG_SETUP_PREFIX;
import static com.intellij.openapi.externalSystem.util.ExternalSystemUtil.convert;
import static com.intellij.openapi.externalSystem.util.ExternalSystemUtil.getConsoleManagerFor;
import static com.intellij.openapi.util.text.StringUtil.nullize;
/**
* @author Denis Zhdanov
*/
public class ExternalSystemRunConfiguration extends LocatableConfigurationBase implements SearchScopeProvidingRunProfile {
private static final ExtensionPointName<ExternalSystemRunConfigurationExtension> EP_NAME
static final ExtensionPointName<ExternalSystemRunConfigurationExtension> EP_NAME
= ExtensionPointName.create("com.intellij.externalSystem.runConfigurationExtension");
public static final Key<InputStream> RUN_INPUT_KEY = Key.create("RUN_INPUT_KEY");
public static final Key<Class<? extends BuildProgressListener>> PROGRESS_LISTENER_KEY = Key.create("PROGRESS_LISTENER_KEY");
private static final Logger LOG = Logger.getInstance(ExternalSystemRunConfiguration.class);
static final Logger LOG = Logger.getInstance(ExternalSystemRunConfiguration.class);
private ExternalSystemTaskExecutionSettings mySettings = new ExternalSystemTaskExecutionSettings();
private static final boolean DISABLE_FORK_DEBUGGER = Boolean.getBoolean("external.system.disable.fork.debugger");
static final boolean DISABLE_FORK_DEBUGGER = Boolean.getBoolean("external.system.disable.fork.debugger");
public ExternalSystemRunConfiguration(@NotNull ProjectSystemId externalSystemId,
Project project,
@@ -178,7 +146,8 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) {
// DebugExecutor ID - com.intellij.execution.executors.DefaultDebugExecutor.EXECUTOR_ID
String debugExecutorId = ToolWindowId.DEBUG;
MyRunnableState runnableState = new MyRunnableState(mySettings, getProject(), debugExecutorId.equals(executor.getId()), this, env);
ExternalSystemRunnableState
runnableState = new ExternalSystemRunnableState(mySettings, getProject(), debugExecutorId.equals(executor.getId()), this, env);
copyUserDataTo(runnableState);
return runnableState;
}
@@ -203,264 +172,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
return scope;
}
public static class MyRunnableState extends UserDataHolderBase implements RunProfileState {
@NotNull private final ExternalSystemTaskExecutionSettings mySettings;
@NotNull private final Project myProject;
@NotNull private final ExternalSystemRunConfiguration myConfiguration;
@NotNull private final ExecutionEnvironment myEnv;
@Nullable private RunContentDescriptor myContentDescriptor;
private final int myDebugPort;
private ServerSocket myForkSocket = null;
public MyRunnableState(@NotNull ExternalSystemTaskExecutionSettings settings,
@NotNull Project project,
boolean debug,
@NotNull ExternalSystemRunConfiguration configuration,
@NotNull ExecutionEnvironment env) {
mySettings = settings;
myProject = project;
myConfiguration = configuration;
myEnv = env;
int port;
if (debug) {
try {
port = NetUtils.findAvailableSocketPort();
}
catch (IOException e) {
LOG.warn("Unexpected I/O exception occurred on attempt to find a free port to use for external system task debugging", e);
port = 0;
}
}
else {
port = 0;
}
myDebugPort = port;
}
public int getDebugPort() {
return myDebugPort;
}
@Nullable
public ServerSocket getForkSocket() {
if (myForkSocket == null && !DISABLE_FORK_DEBUGGER) {
try {
myForkSocket = new ServerSocket(0, 0, InetAddress.getByName("127.0.0.1"));
}
catch (IOException e) {
LOG.error(e);
}
}
return myForkSocket;
}
@Nullable
@Override
public ExecutionResult execute(Executor executor, @NotNull ProgramRunner runner) throws ExecutionException {
if (myProject.isDisposed()) return null;
String jvmParametersSetup = getJvmParametersSetup();
ApplicationManager.getApplication().assertIsDispatchThread();
FileDocumentManager.getInstance().saveAllDocuments();
final ExternalSystemExecuteTaskTask task = new ExternalSystemExecuteTaskTask(myProject, mySettings, jvmParametersSetup);
copyUserDataTo(task);
final String executionName = StringUtil.isNotEmpty(mySettings.getExecutionName())
? mySettings.getExecutionName()
: StringUtil.isNotEmpty(myConfiguration.getName())
? myConfiguration.getName() : AbstractExternalSystemTaskConfigurationType.generateName(
myProject, mySettings.getExternalSystemId(), mySettings.getExternalProjectPath(),
mySettings.getTaskNames(), mySettings.getExecutionName(), ": ", "");
final ExternalSystemProcessHandler processHandler = new ExternalSystemProcessHandler(task, executionName);
final ExternalSystemExecutionConsoleManager<ExternalSystemRunConfiguration, ExecutionConsole, ProcessHandler>
consoleManager = getConsoleManagerFor(task);
final ExecutionConsole consoleView =
consoleManager.attachExecutionConsole(myProject, task, myEnv, processHandler);
AnAction[] restartActions;
if (consoleView == null) {
restartActions = AnAction.EMPTY_ARRAY;
Disposer.register(myProject, processHandler);
}
else {
Disposer.register(myProject, consoleView);
Disposer.register(consoleView, processHandler);
restartActions = consoleManager.getRestartActions(consoleView);
}
Class<? extends BuildProgressListener> progressListenerClazz = task.getUserData(PROGRESS_LISTENER_KEY);
final BuildProgressListener progressListener =
progressListenerClazz != null ? ServiceManager.getService(myProject, progressListenerClazz)
: createBuildView(task.getId(), executionName, task.getExternalProjectPath(), consoleView);
EP_NAME.forEachExtensionSafe(extension -> extension.attachToProcess(myConfiguration, processHandler, myEnv.getRunnerSettings()));
ApplicationManager.getApplication().executeOnPooledThread(() -> {
final String startDateTime = DateFormatUtil.formatTimeWithSeconds(System.currentTimeMillis());
final String greeting;
final String settingsDescription = StringUtil.isEmpty(mySettings.toString()) ? "" : String.format(" '%s'", mySettings.toString());
if (mySettings.getTaskNames().size() > 1) {
greeting = ExternalSystemBundle.message("run.text.starting.multiple.task", startDateTime, settingsDescription) + "\n";
}
else {
greeting = ExternalSystemBundle.message("run.text.starting.single.task", startDateTime, settingsDescription) + "\n";
}
processHandler.notifyTextAvailable(greeting + "\n", ProcessOutputTypes.SYSTEM);
try (BuildEventDispatcher eventDispatcher = new ExternalSystemEventDispatcher(task.getId(), progressListener, false)) {
ExternalSystemTaskNotificationListenerAdapter taskListener = new ExternalSystemTaskNotificationListenerAdapter() {
@Override
public void onStart(@NotNull ExternalSystemTaskId id, String workingDir) {
if (progressListener != null) {
long eventTime = System.currentTimeMillis();
AnAction rerunTaskAction = new MyTaskRerunAction(progressListener, myEnv, myContentDescriptor);
BuildViewSettingsProvider viewSettingsProvider =
consoleView instanceof BuildViewSettingsProvider ?
new BuildViewSettingsProviderAdapter((BuildViewSettingsProvider)consoleView) : null;
progressListener.onEvent(id,
new StartBuildEventImpl(new DefaultBuildDescriptor(id, executionName, workingDir, eventTime), "running...")
.withProcessHandler(processHandler, view -> foldGreetingOrFarewell(consoleView, greeting, true))
.withContentDescriptorSupplier(() -> myContentDescriptor)
.withRestartAction(rerunTaskAction)
.withRestartActions(restartActions)
.withExecutionEnvironment(myEnv)
.withBuildViewSettingsProvider(viewSettingsProvider)
);
}
}
@Override
public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) {
if (consoleView != null) {
consoleManager.onOutput(consoleView, processHandler, text, stdOut ? ProcessOutputTypes.STDOUT : ProcessOutputTypes.STDERR);
}
else {
processHandler.notifyTextAvailable(text, stdOut ? ProcessOutputTypes.STDOUT : ProcessOutputTypes.STDERR);
}
eventDispatcher.setStdOut(stdOut);
eventDispatcher.append(text);
}
@Override
public void onFailure(@NotNull ExternalSystemTaskId id, @NotNull Exception e) {
FailureResult failureResult =
ExternalSystemUtil.createFailureResult(executionName + " failed", e, id.getProjectSystemId(), myProject);
eventDispatcher.onEvent(id, new FinishBuildEventImpl(id, null, System.currentTimeMillis(), "failed", failureResult));
processHandler.notifyProcessTerminated(1);
}
@Override
public void onSuccess(@NotNull ExternalSystemTaskId id) {
eventDispatcher.onEvent(id, new FinishBuildEventImpl(
id, null, System.currentTimeMillis(), "successful", new SuccessResultImpl()));
}
@Override
public void onStatusChange(@NotNull ExternalSystemTaskNotificationEvent event) {
if (event instanceof ExternalSystemBuildEvent) {
eventDispatcher.onEvent(event.getId(), ((ExternalSystemBuildEvent)event).getBuildEvent());
}
else if (event instanceof ExternalSystemTaskExecutionEvent) {
BuildEvent buildEvent = convert(((ExternalSystemTaskExecutionEvent)event));
eventDispatcher.onEvent(event.getId(), buildEvent);
}
}
@Override
public void onEnd(@NotNull ExternalSystemTaskId id) {
final String endDateTime = DateFormatUtil.formatTimeWithSeconds(System.currentTimeMillis());
final String farewell;
if (mySettings.getTaskNames().size() > 1) {
farewell = ExternalSystemBundle.message("run.text.ended.multiple.task", endDateTime, settingsDescription);
}
else {
farewell = ExternalSystemBundle.message("run.text.ended.single.task", endDateTime, settingsDescription);
}
processHandler.notifyTextAvailable(farewell + "\n", ProcessOutputTypes.SYSTEM);
foldGreetingOrFarewell(consoleView, farewell, false);
processHandler.notifyProcessTerminated(0);
eventDispatcher.close();
}
};
task.execute(ArrayUtil.prepend(taskListener, ExternalSystemTaskNotificationListener.EP_NAME.getExtensions()));
}
});
ExecutionConsole executionConsole = progressListener instanceof ExecutionConsole ? (ExecutionConsole)progressListener : consoleView;
DefaultActionGroup actionGroup = new DefaultActionGroup();
if (executionConsole instanceof BuildView) {
actionGroup.addAll(((BuildView)executionConsole).getSwitchActions());
actionGroup.add(BuildTreeFilters.createFilteringActionsGroup((BuildView)executionConsole));
}
DefaultExecutionResult executionResult = new DefaultExecutionResult(executionConsole, processHandler, actionGroup.getChildren(null));
executionResult.setRestartActions(restartActions);
return executionResult;
}
@Nullable
private String getJvmParametersSetup() throws ExecutionException {
final SimpleJavaParameters extensionsJP = new SimpleJavaParameters();
EP_NAME.forEachExtensionSafe(
extension -> extension.updateVMParameters(myConfiguration, extensionsJP, myEnv.getRunnerSettings(), myEnv.getExecutor()));
String jvmParametersSetup;
if (myDebugPort > 0) {
jvmParametersSetup = DEBUG_SETUP_PREFIX + myDebugPort;
if (getForkSocket() != null) {
jvmParametersSetup += (" " + DEBUG_FORK_SOCKET_PARAM + getForkSocket().getLocalPort());
}
}
else {
final ParametersList allVMParameters = new ParametersList();
final ParametersList data = myEnv.getUserData(ExternalSystemTaskExecutionSettings.JVM_AGENT_SETUP_KEY);
if (data != null) {
for (String parameter : data.getList()) {
if (parameter.startsWith("-agentlib:")) continue;
if (parameter.startsWith("-agentpath:")) continue;
if (parameter.startsWith("-javaagent:")) continue;
throw new ExecutionException(ExternalSystemBundle.message("run.invalid.jvm.agent.configuration", parameter));
}
allVMParameters.addAll(data.getParameters());
}
allVMParameters.addAll(extensionsJP.getVMParametersList().getParameters());
jvmParametersSetup = allVMParameters.getParametersString();
}
return nullize(jvmParametersSetup);
}
private BuildProgressListener createBuildView(ExternalSystemTaskId id,
String executionName,
String workingDir,
ExecutionConsole executionConsole) {
BuildDescriptor buildDescriptor = new DefaultBuildDescriptor(id, executionName, workingDir, System.currentTimeMillis());
return new BuildView(myProject, executionConsole, buildDescriptor, "build.toolwindow.run.selection.state",
new ViewManager() {
@Override
public boolean isConsoleEnabledByDefault() {
return true;
}
@Override
public boolean isBuildContentView() {
return false;
}
});
}
public void setContentDescriptor(@Nullable RunContentDescriptor contentDescriptor) {
myContentDescriptor = contentDescriptor;
if (contentDescriptor != null) {
contentDescriptor.setExecutionId(myEnv.getExecutionId());
RunnerAndConfigurationSettings settings = myEnv.getRunnerAndConfigurationSettings();
if (settings != null) {
contentDescriptor.setActivateToolWindowWhenAdded(settings.isActivateToolWindowBeforeRun());
}
}
}
}
private static void foldGreetingOrFarewell(@Nullable ExecutionConsole consoleView, String text, boolean isGreeting) {
static void foldGreetingOrFarewell(@Nullable ExecutionConsole consoleView, String text, boolean isGreeting) {
int limit = 100;
if (text.length() < limit) {
return;
@@ -505,7 +217,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
}
}
private static class MyTaskRerunAction extends FakeRerunAction {
static class MyTaskRerunAction extends FakeRerunAction {
private final BuildProgressListener myProgressListener;
private final RunContentDescriptor myContentDescriptor;
private final ExecutionEnvironment myEnvironment;
@@ -0,0 +1,324 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.externalSystem.service.execution;
import com.intellij.build.*;
import com.intellij.build.events.BuildEvent;
import com.intellij.build.events.FailureResult;
import com.intellij.build.events.impl.FinishBuildEventImpl;
import com.intellij.build.events.impl.StartBuildEventImpl;
import com.intellij.build.events.impl.SuccessResultImpl;
import com.intellij.execution.*;
import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.SimpleJavaParameters;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.execution.ExternalSystemExecutionConsoleManager;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationEvent;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter;
import com.intellij.openapi.externalSystem.model.task.event.ExternalSystemBuildEvent;
import com.intellij.openapi.externalSystem.model.task.event.ExternalSystemTaskExecutionEvent;
import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper;
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemExecuteTaskTask;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.net.NetUtils;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugSession;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import static com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper.DEBUG_FORK_SOCKET_PARAM;
import static com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper.JVM_DEBUG_SETUP_PREFIX;
import static com.intellij.openapi.externalSystem.util.ExternalSystemUtil.convert;
import static com.intellij.openapi.externalSystem.util.ExternalSystemUtil.getConsoleManagerFor;
import static com.intellij.openapi.util.text.StringUtil.nullize;
public class ExternalSystemRunnableState extends UserDataHolderBase implements RunProfileState {
@NotNull private final ExternalSystemTaskExecutionSettings mySettings;
@NotNull private final Project myProject;
@NotNull private final ExternalSystemRunConfiguration myConfiguration;
@NotNull private final ExecutionEnvironment myEnv;
@Nullable private RunContentDescriptor myContentDescriptor;
private final int myDebugPort;
private ServerSocket myForkSocket = null;
public ExternalSystemRunnableState(@NotNull ExternalSystemTaskExecutionSettings settings,
@NotNull Project project,
boolean debug,
@NotNull ExternalSystemRunConfiguration configuration,
@NotNull ExecutionEnvironment env) {
mySettings = settings;
myProject = project;
myConfiguration = configuration;
myEnv = env;
int port;
if (debug) {
try {
port = NetUtils.findAvailableSocketPort();
}
catch (IOException e) {
ExternalSystemRunConfiguration.LOG
.warn("Unexpected I/O exception occurred on attempt to find a free port to use for external system task debugging", e);
port = 0;
}
}
else {
port = 0;
}
myDebugPort = port;
}
public int getDebugPort() {
return myDebugPort;
}
@Nullable
public ServerSocket getForkSocket() {
if (myForkSocket == null && !ExternalSystemRunConfiguration.DISABLE_FORK_DEBUGGER) {
try {
myForkSocket = new ServerSocket(0, 0, InetAddress.getByName("127.0.0.1"));
}
catch (IOException e) {
ExternalSystemRunConfiguration.LOG.error(e);
}
}
return myForkSocket;
}
@Nullable
@Override
public ExecutionResult execute(Executor executor, @NotNull ProgramRunner runner) throws ExecutionException {
if (myProject.isDisposed()) return null;
String jvmParametersSetup = getJvmParametersSetup();
ApplicationManager.getApplication().assertIsDispatchThread();
FileDocumentManager.getInstance().saveAllDocuments();
final ExternalSystemExecuteTaskTask task = new ExternalSystemExecuteTaskTask(myProject, mySettings, jvmParametersSetup);
copyUserDataTo(task);
final String executionName = StringUtil.isNotEmpty(mySettings.getExecutionName())
? mySettings.getExecutionName()
: StringUtil.isNotEmpty(myConfiguration.getName())
? myConfiguration.getName() : AbstractExternalSystemTaskConfigurationType.generateName(
myProject, mySettings.getExternalSystemId(), mySettings.getExternalProjectPath(),
mySettings.getTaskNames(), mySettings.getExecutionName(), ": ", "");
final ExternalSystemProcessHandler processHandler = new ExternalSystemProcessHandler(task, executionName);
final ExternalSystemExecutionConsoleManager<ExternalSystemRunConfiguration, ExecutionConsole, ProcessHandler>
consoleManager = getConsoleManagerFor(task);
final ExecutionConsole consoleView =
consoleManager.attachExecutionConsole(myProject, task, myEnv, processHandler);
AnAction[] restartActions;
if (consoleView == null) {
restartActions = AnAction.EMPTY_ARRAY;
Disposer.register(myProject, processHandler);
}
else {
Disposer.register(myProject, consoleView);
Disposer.register(consoleView, processHandler);
restartActions = consoleManager.getRestartActions(consoleView);
}
Class<? extends BuildProgressListener> progressListenerClazz = task.getUserData(ExternalSystemRunConfiguration.PROGRESS_LISTENER_KEY);
final BuildProgressListener progressListener =
progressListenerClazz != null ? ServiceManager.getService(myProject, progressListenerClazz)
: createBuildView(task.getId(), executionName, task.getExternalProjectPath(), consoleView);
ExternalSystemRunConfiguration.EP_NAME
.forEachExtensionSafe(extension -> extension.attachToProcess(myConfiguration, processHandler, myEnv.getRunnerSettings()));
ApplicationManager.getApplication().executeOnPooledThread(() -> {
final String startDateTime = DateFormatUtil.formatTimeWithSeconds(System.currentTimeMillis());
final String greeting;
final String settingsDescription = StringUtil.isEmpty(mySettings.toString()) ? "" : String.format(" '%s'", mySettings.toString());
if (mySettings.getTaskNames().size() > 1) {
greeting = ExternalSystemBundle.message("run.text.starting.multiple.task", startDateTime, settingsDescription) + "\n";
}
else {
greeting = ExternalSystemBundle.message("run.text.starting.single.task", startDateTime, settingsDescription) + "\n";
}
processHandler.notifyTextAvailable(greeting + "\n", ProcessOutputTypes.SYSTEM);
try (BuildEventDispatcher eventDispatcher = new ExternalSystemEventDispatcher(task.getId(), progressListener, false)) {
ExternalSystemTaskNotificationListenerAdapter taskListener = new ExternalSystemTaskNotificationListenerAdapter() {
@Override
public void onStart(@NotNull ExternalSystemTaskId id, String workingDir) {
if (progressListener != null) {
long eventTime = System.currentTimeMillis();
AnAction rerunTaskAction = new ExternalSystemRunConfiguration.MyTaskRerunAction(progressListener, myEnv, myContentDescriptor);
BuildViewSettingsProvider viewSettingsProvider =
consoleView instanceof BuildViewSettingsProvider ?
new BuildViewSettingsProviderAdapter((BuildViewSettingsProvider)consoleView) : null;
progressListener.onEvent(id,
new StartBuildEventImpl(new DefaultBuildDescriptor(id, executionName, workingDir, eventTime),
"running...")
.withProcessHandler(processHandler, view -> ExternalSystemRunConfiguration
.foldGreetingOrFarewell(consoleView, greeting, true))
.withContentDescriptorSupplier(() -> myContentDescriptor)
.withRestartAction(rerunTaskAction)
.withRestartActions(restartActions)
.withExecutionEnvironment(myEnv)
.withBuildViewSettingsProvider(viewSettingsProvider)
);
}
}
@Override
public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) {
if (consoleView != null) {
consoleManager.onOutput(consoleView, processHandler, text, stdOut ? ProcessOutputTypes.STDOUT : ProcessOutputTypes.STDERR);
}
else {
processHandler.notifyTextAvailable(text, stdOut ? ProcessOutputTypes.STDOUT : ProcessOutputTypes.STDERR);
}
eventDispatcher.setStdOut(stdOut);
eventDispatcher.append(text);
}
@Override
public void onFailure(@NotNull ExternalSystemTaskId id, @NotNull Exception e) {
FailureResult failureResult =
ExternalSystemUtil.createFailureResult(executionName + " failed", e, id.getProjectSystemId(), myProject);
eventDispatcher.onEvent(id, new FinishBuildEventImpl(id, null, System.currentTimeMillis(), "failed", failureResult));
processHandler.notifyProcessTerminated(1);
}
@Override
public void onSuccess(@NotNull ExternalSystemTaskId id) {
eventDispatcher.onEvent(id, new FinishBuildEventImpl(
id, null, System.currentTimeMillis(), "successful", new SuccessResultImpl()));
}
@Override
public void onStatusChange(@NotNull ExternalSystemTaskNotificationEvent event) {
if (event instanceof ExternalSystemBuildEvent) {
eventDispatcher.onEvent(event.getId(), ((ExternalSystemBuildEvent)event).getBuildEvent());
}
else if (event instanceof ExternalSystemTaskExecutionEvent) {
BuildEvent buildEvent = convert(((ExternalSystemTaskExecutionEvent)event));
eventDispatcher.onEvent(event.getId(), buildEvent);
}
}
@Override
public void onEnd(@NotNull ExternalSystemTaskId id) {
final String endDateTime = DateFormatUtil.formatTimeWithSeconds(System.currentTimeMillis());
final String farewell;
if (mySettings.getTaskNames().size() > 1) {
farewell = ExternalSystemBundle.message("run.text.ended.multiple.task", endDateTime, settingsDescription);
}
else {
farewell = ExternalSystemBundle.message("run.text.ended.single.task", endDateTime, settingsDescription);
}
processHandler.notifyTextAvailable(farewell + "\n", ProcessOutputTypes.SYSTEM);
ExternalSystemRunConfiguration.foldGreetingOrFarewell(consoleView, farewell, false);
processHandler.notifyProcessTerminated(0);
eventDispatcher.close();
}
};
task.execute(ArrayUtil.prepend(taskListener, ExternalSystemTaskNotificationListener.EP_NAME.getExtensions()));
}
});
ExecutionConsole executionConsole = progressListener instanceof ExecutionConsole ? (ExecutionConsole)progressListener : consoleView;
DefaultActionGroup actionGroup = new DefaultActionGroup();
if (executionConsole instanceof BuildView) {
actionGroup.addAll(((BuildView)executionConsole).getSwitchActions());
actionGroup.add(BuildTreeFilters.createFilteringActionsGroup((BuildView)executionConsole));
}
DefaultExecutionResult executionResult = new DefaultExecutionResult(executionConsole, processHandler, actionGroup.getChildren(null));
executionResult.setRestartActions(restartActions);
return executionResult;
}
@Nullable
private String getJvmParametersSetup() throws ExecutionException {
final SimpleJavaParameters extensionsJP = new SimpleJavaParameters();
ExternalSystemRunConfiguration.EP_NAME.forEachExtensionSafe(
extension -> extension.updateVMParameters(myConfiguration, extensionsJP, myEnv.getRunnerSettings(), myEnv.getExecutor()));
String jvmParametersSetup;
if (myDebugPort > 0) {
jvmParametersSetup = ForkedDebuggerHelper.JVM_DEBUG_SETUP_PREFIX + myDebugPort;
if (getForkSocket() != null) {
jvmParametersSetup += (" " + DEBUG_FORK_SOCKET_PARAM + getForkSocket().getLocalPort());
}
}
else {
final ParametersList allVMParameters = new ParametersList();
final ParametersList data = myEnv.getUserData(ExternalSystemTaskExecutionSettings.JVM_AGENT_SETUP_KEY);
if (data != null) {
for (String parameter : data.getList()) {
if (parameter.startsWith("-agentlib:")) continue;
if (parameter.startsWith("-agentpath:")) continue;
if (parameter.startsWith("-javaagent:")) continue;
throw new ExecutionException(ExternalSystemBundle.message("run.invalid.jvm.agent.configuration", parameter));
}
allVMParameters.addAll(data.getParameters());
}
allVMParameters.addAll(extensionsJP.getVMParametersList().getParameters());
jvmParametersSetup = allVMParameters.getParametersString();
}
return nullize(jvmParametersSetup);
}
private BuildProgressListener createBuildView(ExternalSystemTaskId id,
String executionName,
String workingDir,
ExecutionConsole executionConsole) {
BuildDescriptor buildDescriptor = new DefaultBuildDescriptor(id, executionName, workingDir, System.currentTimeMillis());
return new BuildView(myProject, executionConsole, buildDescriptor, "build.toolwindow.run.selection.state",
new ViewManager() {
@Override
public boolean isConsoleEnabledByDefault() {
return true;
}
@Override
public boolean isBuildContentView() {
return false;
}
});
}
public void setContentDescriptor(@Nullable RunContentDescriptor contentDescriptor) {
myContentDescriptor = contentDescriptor;
if (contentDescriptor != null) {
contentDescriptor.setExecutionId(myEnv.getExecutionId());
RunnerAndConfigurationSettings settings = myEnv.getRunnerAndConfigurationSettings();
if (settings != null) {
contentDescriptor.setActivateToolWindowWhenAdded(settings.isActivateToolWindowBeforeRun());
}
}
}
@Nullable
public XDebugProcess startDebugProcess(@NotNull XDebugSession session,
@NotNull ExecutionEnvironment env) {
return null;
}
}
@@ -43,7 +43,7 @@ class ExternalSystemTaskRunner : GenericProgramRunner<RunnerSettings>() {
@Throws(ExecutionException::class)
override fun doExecute(state: RunProfileState, environment: ExecutionEnvironment): RunContentDescriptor? {
if (state !is ExternalSystemRunConfiguration.MyRunnableState && state !is HistoryTestRunnableState) {
if (state !is ExternalSystemRunnableState && state !is HistoryTestRunnableState) {
return null
}
@@ -54,7 +54,7 @@ class ExternalSystemTaskRunner : GenericProgramRunner<RunnerSettings>() {
return runContentDescriptor
}
(state as ExternalSystemRunConfiguration.MyRunnableState).setContentDescriptor(runContentDescriptor)
(state as ExternalSystemRunnableState).setContentDescriptor(runContentDescriptor)
if (executionResult.executionConsole is BuildView) {
return runContentDescriptor
}
@@ -25,13 +25,13 @@ public class ForkedDebuggerConfiguration {
@Nullable
public static ForkedDebuggerConfiguration parse(@Nullable String jvmAgentSetup) {
if (jvmAgentSetup != null && jvmAgentSetup.startsWith(ForkedDebuggerHelper.DEBUG_SETUP_PREFIX)) {
if (jvmAgentSetup != null && jvmAgentSetup.startsWith(ForkedDebuggerHelper.JVM_DEBUG_SETUP_PREFIX)) {
int forkSocketIndex = jvmAgentSetup.indexOf(ForkedDebuggerHelper.DEBUG_FORK_SOCKET_PARAM);
if (forkSocketIndex > 0) {
try {
int forkSocketPort =
Integer.parseInt(jvmAgentSetup.substring(forkSocketIndex + ForkedDebuggerHelper.DEBUG_FORK_SOCKET_PARAM.length()));
int debugPort = Integer.parseInt(jvmAgentSetup.substring(ForkedDebuggerHelper.DEBUG_SETUP_PREFIX.length(), forkSocketIndex - 1));
int debugPort = Integer.parseInt(jvmAgentSetup.substring(ForkedDebuggerHelper.JVM_DEBUG_SETUP_PREFIX.length(), forkSocketIndex - 1));
return new ForkedDebuggerConfiguration(forkSocketPort, debugPort);
}
catch (NumberFormatException ignore) {
@@ -42,6 +42,6 @@ public class ForkedDebuggerConfiguration {
}
public String getJvmAgentSetup(boolean isJdk9orLater) {
return ForkedDebuggerHelper.DEBUG_SETUP_PREFIX + (isJdk9orLater ? "127.0.0.1:" : "") + myDebugPort;
return ForkedDebuggerHelper.JVM_DEBUG_SETUP_PREFIX + (isJdk9orLater ? "127.0.0.1:" : "") + myDebugPort;
}
}
@@ -11,51 +11,57 @@ import java.net.Socket;
*/
public class ForkedDebuggerHelper {
public static final String DEBUG_SETUP_PREFIX = "-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=";
public static final String JVM_DEBUG_SETUP_PREFIX = "-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=";
public static final String DEBUG_FORK_SOCKET_PARAM = "-forkSocket";
public static String setupDebugger(String processName, int debugPort) {
String setup = "";
public static final String DEBUG_SERVER_PORT_KEY = "DEBUG_SERVER_PORT";
public static final String PARAMETERS_SEPARATOR = ";";
public static final String FINISH_PARAMS = "FINISH_PARAMS";
// returns port at which debugger is supposed to communicate with debuggee process
public static int setupDebugger(String debuggerId, String processName, String processParameters, int dispatchPort) {
int port = 0;
try {
if (debugPort > -1) {
int debugAddress = findAvailableSocketPort();
if (debugAddress > -1) {
setup = DEBUG_SETUP_PREFIX + debugAddress;
send(debugAddress, processName, debugPort);
}
}
port = findAvailableSocketPort();
processParameters = (processParameters == null || processParameters.isEmpty()) ? "" : processParameters + PARAMETERS_SEPARATOR;
processParameters = processParameters + DEBUG_SERVER_PORT_KEY + "=" + port;
send(debuggerId, processName, processParameters, dispatchPort);
}
catch (Exception e) {
catch (IOException e) {
//noinspection CallToPrintStackTrace
e.printStackTrace();
}
return setup;
return port;
}
public static void processFinished(String processName, int debugPort) {
send(0, processName, debugPort);
}
private static void send(int signal, String processName, int debugPort) {
public static void signalizeFinish(String debuggerId, String processName, int dispatchPort) {
try {
Socket socket = new Socket("127.0.0.1", debugPort);
send(debuggerId, processName, FINISH_PARAMS, dispatchPort);
}
catch (IOException e) {
//noinspection CallToPrintStackTrace
e.printStackTrace();
}
}
private static void send(String debuggerId, String processName, String processParameters, int dispatchPort) throws IOException {
Socket socket = new Socket("127.0.0.1", dispatchPort);
try {
DataOutputStream stream = new DataOutputStream(socket.getOutputStream());
try {
DataOutputStream stream = new DataOutputStream(socket.getOutputStream());
try {
stream.writeInt(signal);
stream.writeUTF(processName);
// wait for the signal handling
int read = socket.getInputStream().read();
}
finally {
stream.close();
}
stream.writeUTF(debuggerId);
stream.writeUTF(processName);
stream.writeUTF(processParameters);
// wait for the signal handling
int read = socket.getInputStream().read();
}
finally {
socket.close();
stream.close();
}
}
catch (Exception ignore) {
finally {
socket.close();
}
}
@@ -76,6 +82,11 @@ public class ForkedDebuggerHelper {
e.printStackTrace();
}
}
if (port <= -1) {
throw new IOException("Failed to find available port");
}
return port;
}
finally {
@@ -2,6 +2,8 @@
<extensionPoints>
<extensionPoint qualifiedName="com.intellij.externalSystemManager"
interface="com.intellij.openapi.externalSystem.ExternalSystemManager"/>
<extensionPoint qualifiedName="com.intellij.externalSystem.debuggerBackend"
interface="com.intellij.openapi.externalSystem.debugger.DebuggerBackendExtension"/>
<extensionPoint qualifiedName="com.intellij.externalSystemWorkspaceContributor"
interface="com.intellij.openapi.externalSystem.service.project.ExternalProjectsWorkspaceImpl$Contributor"/>
<extensionPoint qualifiedName="com.intellij.externalProjectDataService"
@@ -48,6 +48,7 @@
<projectTaskRunner implementation="org.jetbrains.plugins.gradle.execution.build.GradleProjectTaskRunner" id="gradle" order="first"/>
<buildProcess.parametersProvider implementation="org.jetbrains.plugins.gradle.compiler.GradleBuildProcessParametersProvider"/>
<externalSystemNotificationExtension implementation="org.jetbrains.plugins.gradle.service.notification.GradleNotificationJavaExtension"/>
<externalSystem.debuggerBackend implementation="org.jetbrains.plugins.gradle.service.debugger.GradleJvmDebuggerBackend" />
<externalProjectDataService implementation="org.jetbrains.plugins.gradle.service.project.data.BuildClasspathModuleGradleDataService"/>
<projectService serviceImplementation="org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager"/>
@@ -0,0 +1,49 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.gradle.service.debugger
import com.intellij.execution.RunManager.Companion.getInstance
import com.intellij.execution.RunnerAndConfigurationSettings
import com.intellij.execution.remote.RemoteConfiguration
import com.intellij.execution.remote.RemoteConfigurationType
import com.intellij.openapi.externalSystem.debugger.DebuggerBackendExtension
import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper
import com.intellij.openapi.project.Project
class GradleJvmDebuggerBackend : DebuggerBackendExtension {
override fun id() = "Gradle JVM"
override fun debugConfigurationSettings(project: Project,
processName: String,
processParameters: String): RunnerAndConfigurationSettings {
val runSettings = getInstance(project).createConfiguration(processName, RemoteConfigurationType::class.java)
val description = splitParameters(processParameters)
val configuration = runSettings.configuration as RemoteConfiguration
configuration.HOST = "localhost"
configuration.PORT = description[ForkedDebuggerHelper.DEBUG_SERVER_PORT_KEY]
configuration.USE_SOCKET_TRANSPORT = true
configuration.SERVER_MODE = true
return runSettings
}
override fun initializationCode(dispatchPort: String, parameters: String) = listOf(
"import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper",
"gradle.taskGraph.beforeTask { Task task ->",
" if (task instanceof org.gradle.api.tasks.testing.Test) {",
" task.maxParallelForks = 1",
" task.forkEvery = 0",
" }",
" if (task instanceof JavaForkOptions) {",
" def debugPort = ForkedDebuggerHelper.setupDebugger('${id()}', task.path, '$parameters', $dispatchPort)",
" def jvmArgs = task.jvmArgs.findAll{!it?.startsWith('-agentlib:jdwp') && !it?.startsWith('-Xrunjdwp')}",
" jvmArgs << ForkedDebuggerHelper.JVM_DEBUG_SETUP_PREFIX + debugPort",
" task.jvmArgs = jvmArgs",
" }",
"}",
"gradle.taskGraph.afterTask { Task task ->",
" if (task instanceof JavaForkOptions) {",
" ForkedDebuggerHelper.signalizeFinish('${id()}', task.path, $dispatchPort)",
" }",
"}")
}
@@ -6,14 +6,18 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerConfiguration;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.Order;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.execution.ParametersListUtil;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.tooling.model.idea.IdeaProject;
import org.jetbrains.annotations.NotNull;
@@ -31,6 +35,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Vladislav.Soroka
@@ -144,11 +149,11 @@ public class JavaGradleProjectResolver extends AbstractProjectResolverExtension
@Override
public void enhanceTaskProcessing(@NotNull List<String> taskNames,
@Nullable String jvmParametersSetup,
@NotNull Consumer<String> initScriptConsumer,
boolean testExecutionExpected) {
@NotNull Map<String, String> parameters) {
String testExecutionExpected = parameters.get(GradleProjectResolverExtension.TEST_EXECUTION_EXPECTED_KEY);
if (testExecutionExpected) {
if (Boolean.valueOf(testExecutionExpected)) {
try (InputStream stream = getClass().getResourceAsStream("/org/jetbrains/plugins/gradle/java/addTestListener.groovy")) {
String addTestListenerScript = StreamUtil.readText(stream, StandardCharsets.UTF_8);
initScriptConsumer.consume(addTestListenerScript);
@@ -157,6 +162,46 @@ public class JavaGradleProjectResolver extends AbstractProjectResolverExtension
LOG.info(e);
}
}
String jvmParametersSetup = parameters.get(GradleProjectResolverExtension.JVM_PARAMETERS_SETUP_KEY);
enhanceTaskProcessing(taskNames, jvmParametersSetup, initScriptConsumer);
}
private String loadTestEventListenerDefinition() {
try(InputStream stream = getClass().getResourceAsStream("/org/jetbrains/plugins/gradle/IJTestLogger.groovy")) {
return StreamUtil.readText(stream, StandardCharsets.UTF_8);
} catch (IOException e) {
LOG.info(e);
}
return "";
}
@Override
public void enhanceTaskProcessing(@NotNull List<String> taskNames,
@Nullable String jvmParametersSetup,
@NotNull Consumer<String> initScriptConsumer) {
if (!StringUtil.isEmpty(jvmParametersSetup)) {
ForkedDebuggerConfiguration forkedDebuggerSetup = ForkedDebuggerConfiguration.parse(jvmParametersSetup);
if (forkedDebuggerSetup == null) {
final String names = "[\"" + StringUtil.join(taskNames, "\", \"") + "\"]";
final String jvmArgs = Arrays.stream(ParametersListUtil.parseToArray(jvmParametersSetup))
.map(s -> '\'' + s.trim().replace("\\", "\\\\") + '\'').collect(Collectors.joining(" << "));
final String[] lines = {
"gradle.taskGraph.beforeTask { Task task ->",
" if (task instanceof JavaForkOptions && (" + names + ".contains(task.name) || " + names + ".contains(task.path))) {",
" def jvmArgs = task.jvmArgs.findAll{!it?.startsWith('-agentlib:jdwp') && !it?.startsWith('-Xrunjdwp')}",
" jvmArgs << " + jvmArgs,
" task.jvmArgs = jvmArgs",
" }" +
"}",
};
final String script = StringUtil.join(lines, SystemProperties.getLineSeparator());
initScriptConsumer.consume(script);
}
}
final String testEventListenerDefinition = loadTestEventListenerDefinition();
initScriptConsumer.consume(testEventListenerDefinition);
}
@NotNull
@@ -15,6 +15,7 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Element;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.GradleIdeManager;
@@ -25,6 +26,12 @@ public class GradleRunConfiguration extends ExternalSystemRunConfiguration imple
public static final String DEBUG_FLAG_NAME = "GradleScriptDebugEnabled";
public static final Key<Boolean> DEBUG_FLAG_KEY = Key.create("DEBUG_GRADLE_SCRIPT");
@ApiStatus.Internal
public static final Key<Integer> DEBUGGER_DISPATCH_PORT_KEY = Key.create("DEBUGGER_DISPATCH_PORT");
@ApiStatus.Internal
public static final Key<String> DEBUGGER_PARAMETERS_KEY = Key.create("DEBUGGER_PARAMETERS");
private boolean isScriptDebugEnabled = true;
public GradleRunConfiguration(Project project, ConfigurationFactory factory, String name) {
@@ -6,6 +6,7 @@ import com.google.gson.GsonBuilder;
import com.intellij.execution.configurations.SimpleJavaParameters;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.debugger.DebuggerBackendExtension;
import com.intellij.openapi.externalSystem.model.ConfigurationDataImpl;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
@@ -837,69 +838,30 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
public void enhanceTaskProcessing(@NotNull List<String> taskNames,
@Nullable String jvmParametersSetup,
@NotNull Consumer<String> initScriptConsumer) {
if (!StringUtil.isEmpty(jvmParametersSetup)) {
ForkedDebuggerConfiguration forkedDebuggerSetup = ForkedDebuggerConfiguration.parse(jvmParametersSetup);
if (forkedDebuggerSetup != null) {
setupDebugForAllJvmForkedTasks(initScriptConsumer, forkedDebuggerSetup.getForkSocketPort());
}
else {
final String names = "[\"" + StringUtil.join(taskNames, "\", \"") + "\"]";
final String jvmArgs = Arrays.stream(ParametersListUtil.parseToArray(jvmParametersSetup))
.map(s -> '\'' + s.trim().replace("\\", "\\\\") + '\'').collect(Collectors.joining(" << "));
final String[] lines = {
"gradle.taskGraph.beforeTask { Task task ->",
" if (task instanceof JavaForkOptions && (" + names + ".contains(task.name) || " + names + ".contains(task.path))) {",
" def jvmArgs = task.jvmArgs.findAll{!it?.startsWith('-agentlib:jdwp') && !it?.startsWith('-Xrunjdwp')}",
" jvmArgs << " + jvmArgs,
" task.jvmArgs = jvmArgs",
" }" +
"}",
};
final String script = StringUtil.join(lines, SystemProperties.getLineSeparator());
initScriptConsumer.consume(script);
}
}
final String testEventListenerDefinition = loadTestEventListenerDefinition();
initScriptConsumer.consume(testEventListenerDefinition);
}
private String loadTestEventListenerDefinition() {
try (InputStream stream = getClass().getResourceAsStream("/org/jetbrains/plugins/gradle/IJTestLogger.groovy")) {
return StreamUtil.readText(stream, StandardCharsets.UTF_8);
@Override
public void enhanceTaskProcessing(@NotNull List<String> taskNames,
@NotNull Consumer<String> initScriptConsumer,
@NotNull Map<String, String> parameters) {
String dispatchPort = parameters.get(GradleProjectResolverExtension.DEBUG_DISPATCH_PORT_KEY);
if (dispatchPort == null) {
return;
}
catch (IOException e) {
LOG.info(e);
}
return "";
}
public void setupDebugForAllJvmForkedTasks(@NotNull Consumer<? super String> initScriptConsumer, int debugPort) {
// external-system-rt.jar
String debugOptions = parameters.get(GradleProjectResolverExtension.DEBUG_OPTIONS_KEY);
if (debugOptions == null) {
debugOptions = "";
}
List<String> lines = new ArrayList<>();
String esRtJarPath = PathUtil.getCanonicalPath(PathManager.getJarPathForClass(ExternalSystemSourceType.class));
final String[] lines = {
"initscript {",
" dependencies {",
" classpath files(\"" + esRtJarPath + "\")",
" }",
"}",
"gradle.taskGraph.beforeTask { Task task ->",
" if (task instanceof org.gradle.api.tasks.testing.Test) {",
" task.maxParallelForks = 1",
" task.forkEvery = 0",
" }",
" if (task instanceof JavaForkOptions) {",
" def jvmArgs = task.jvmArgs.findAll{!it?.startsWith('-agentlib:jdwp') && !it?.startsWith('-Xrunjdwp')}",
" jvmArgs << com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper.setupDebugger(task.path, " + debugPort + ")",
" task.jvmArgs = jvmArgs",
" }",
"}",
"gradle.taskGraph.afterTask { Task task ->",
" if (task instanceof JavaForkOptions) {",
" com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper.processFinished(task.path, " + debugPort + ")",
" }",
"}",
};
lines.add("initscript { dependencies { classpath files(\""+ esRtJarPath + "\") } }"); // bring external-system-rt.jar
for (DebuggerBackendExtension extension: DebuggerBackendExtension.EP_NAME.getExtensionList()) {
lines.addAll(extension.initializationCode(dispatchPort, debugOptions));
}
final String script = StringUtil.join(lines, SystemProperties.getLineSeparator());
initScriptConsumer.consume(script);
}
@@ -40,10 +40,7 @@ import org.jetbrains.plugins.gradle.GradleManager;
import org.jetbrains.plugins.gradle.model.ModelsHolder;
import org.jetbrains.plugins.gradle.model.ProjectImportModelProvider;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* Allows to enhance {@link GradleProjectResolver} processing.
@@ -205,18 +202,30 @@ public interface GradleProjectResolverExtension extends ParametersEnhancer {
*/
void enhanceTaskProcessing(@NotNull List<String> taskNames, @Nullable String jvmParametersSetup, @NotNull Consumer<String> initScriptConsumer);
// jvm configuration that will be applied to Gradle jvm
String JVM_PARAMETERS_SETUP_KEY = "JVM_PARAMETERS_SETUP";
// flag that shows if tasks will be treated as tests invocation by the IDE (e.g., test events are expected)
String TEST_EXECUTION_EXPECTED_KEY = "TEST_EXECUTION_EXPECTED";
// port for callbacks which Gradle tasks communicate to IDE
String DEBUG_DISPATCH_PORT_KEY = "DEBUG_DISPATCH_PORT";
// options passed from project to Gradle
String DEBUG_OPTIONS_KEY = "DEBUG_OPTIONS";
/**
* Allows extension to contribute to init script
* @param taskNames gradle task names to be executed
* @param jvmParametersSetup jvm configuration that will be applied to Gradle jvm
* @param initScriptConsumer consumer of init script text. Must be called to add script txt
* @param testExecutionExpected flag that shows if tasks will be treated as tests invocation by the IDE (e.g., test events are expected)
* @param parameters storage for passing optional named parameters
*/
@ApiStatus.Experimental
default void enhanceTaskProcessing(@NotNull List<String> taskNames,
@Nullable String jvmParametersSetup,
@NotNull Consumer<String> initScriptConsumer,
boolean testExecutionExpected) {
@NotNull Consumer<String> initScriptConsumer,
@NotNull Map<String, String> parameters) {
String jvmParametersSetup = parameters.get(JVM_PARAMETERS_SETUP_KEY);
enhanceTaskProcessing(taskNames, jvmParametersSetup, initScriptConsumer);
}
}
@@ -84,8 +84,11 @@ public class GradleTaskManager extends BaseExternalSystemTaskManager<GradleExecu
settings == null ? new GradleExecutionSettings(null, null, DistributionType.BUNDLED, false) : settings;
ForkedDebuggerConfiguration forkedDebuggerSetup = ForkedDebuggerConfiguration.parse(jvmParametersSetup);
if (forkedDebuggerSetup != null && isGradleScriptDebug(settings)) {
effectiveSettings.withVmOption(forkedDebuggerSetup.getJvmAgentSetup(isJdk9orLater(effectiveSettings.getJavaHome())));
if (forkedDebuggerSetup != null) {
if (isGradleScriptDebug(settings)) {
effectiveSettings.withVmOption(forkedDebuggerSetup.getJvmAgentSetup(isJdk9orLater(effectiveSettings.getJavaHome())));
}
effectiveSettings.putUserData(GradleRunConfiguration.DEBUGGER_DISPATCH_PORT_KEY, forkedDebuggerSetup.getForkSocketPort());
}
CancellationTokenSource cancellationTokenSource = GradleConnector.newCancellationTokenSource();
@@ -180,8 +183,23 @@ public class GradleTaskManager extends BaseExternalSystemTaskManager<GradleExecu
"//");
}
};
boolean isTestExecution = Boolean.TRUE == effectiveSettings.getUserData(GradleConstants.RUN_TASK_AS_TEST);
resolverExtension.enhanceTaskProcessing(taskNames, jvmParametersSetup, initScriptConsumer, isTestExecution);
Map<String, String> enhancementParameters = new HashMap<>();
enhancementParameters.put(GradleProjectResolverExtension.JVM_PARAMETERS_SETUP_KEY, jvmParametersSetup);
String isTestExecution = String.valueOf(Boolean.TRUE == effectiveSettings.getUserData(GradleConstants.RUN_TASK_AS_TEST));
enhancementParameters.put(GradleProjectResolverExtension.TEST_EXECUTION_EXPECTED_KEY, isTestExecution);
Integer debugDispatchPort = effectiveSettings.getUserData(GradleRunConfiguration.DEBUGGER_DISPATCH_PORT_KEY);
if (debugDispatchPort != null) {
enhancementParameters.put(GradleProjectResolverExtension.DEBUG_DISPATCH_PORT_KEY, String.valueOf(debugDispatchPort));
String debugOptions = effectiveSettings.getUserData(GradleRunConfiguration.DEBUGGER_PARAMETERS_KEY);
enhancementParameters.put(GradleProjectResolverExtension.DEBUG_OPTIONS_KEY, debugOptions);
}
resolverExtension.enhanceTaskProcessing(taskNames, initScriptConsumer, enhancementParameters);
}
if (!initScripts.isEmpty()) {