PY-17447 PyRemoteDebugSessionCreator extension point with PyDockerDebugSessionCreator implementation that uses new Python debugger connection strategy introduced

This commit is contained in:
Alexander Koshevoy
2016-10-18 18:42:38 +03:00
parent cccb586b94
commit dec36415af
3 changed files with 94 additions and 16 deletions
@@ -630,6 +630,7 @@
<extensionPoint qualifiedName="Pythonid.pyCustomSdkUiProvider" interface="com.jetbrains.python.sdk.PyCustomSdkUiProvider"/>
<extensionPoint qualifiedName="Pythonid.pep8ProblemSuppressor" interface="com.jetbrains.python.validation.Pep8ProblemSuppressor"/>
<extensionPoint qualifiedName="Pythonid.pythonFlavorProvider" interface="com.jetbrains.python.sdk.flavors.PythonFlavorProvider"/>
<extensionPoint qualifiedName="Pythonid.pyRemoteDebugSessionCreator" interface="com.jetbrains.python.debugger.PyRemoteDebugSessionCreator"/>
</extensionPoints>
<extensions defaultExtensionNs="Pythonid">
@@ -33,6 +33,7 @@ import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.remote.RemoteSdkAdditionalData;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugProcessStarter;
import com.intellij.xdebugger.XDebugSession;
@@ -69,6 +70,7 @@ public class PyDebugRunner extends GenericProgramRunner {
public static final String PORT_PARAM = "--port";
public static final String FILE_PARAM = "--file";
public static final String MODULE_PARAM = "--module";
public static final String MULTIPROCESS_PARAM = "--multiprocess";
public static final String IDE_PROJECT_ROOTS = "IDE_PROJECT_ROOTS";
public static final String LIBRARY_ROOTS = "LIBRARY_ROOTS";
public static final String PYTHON_ASYNCIO_DEBUG = "PYTHONASYNCIODEBUG";
@@ -121,6 +123,16 @@ public class PyDebugRunner extends GenericProgramRunner {
FileDocumentManager.getInstance().saveAllDocuments();
final PythonCommandLineState pyState = (PythonCommandLineState)state;
Sdk sdk = pyState.getSdk();
if (sdk != null && sdk.getSdkAdditionalData() instanceof RemoteSdkAdditionalData) {
RemoteSdkAdditionalData remoteSdkAdditionalData = (RemoteSdkAdditionalData)sdk.getSdkAdditionalData();
PyRemoteDebugSessionCreator sessionCreator = PyRemoteDebugSessionCreator.findExtension(remoteSdkAdditionalData);
if (sessionCreator != null) {
return sessionCreator.createSession(this, pyState, environment);
}
}
final ServerSocket serverSocket = PythonCommandLineState.createServerSocket();
final int serverLocalPort = serverSocket.getLocalPort();
RunProfile profile = environment.getRunProfile();
@@ -215,7 +227,7 @@ public class PyDebugRunner extends GenericProgramRunner {
}
@Nullable
private static CommandLinePatcher createRunConfigPatcher(RunProfileState state, RunProfile profile) {
public static CommandLinePatcher createRunConfigPatcher(RunProfileState state, RunProfile profile) {
CommandLinePatcher runConfigPatcher = null;
if (state instanceof PythonCommandLineState && profile instanceof AbstractPythonRunConfiguration) {
runConfigPatcher = (AbstractPythonRunConfiguration)profile;
@@ -283,10 +295,10 @@ public class PyDebugRunner extends GenericProgramRunner {
}
private void fillDebugParameters(@NotNull Project project,
@NotNull ParamsGroup debugParams,
int serverLocalPort,
@NotNull PythonCommandLineState pyState,
@NotNull GeneralCommandLine cmd) {
@NotNull ParamsGroup debugParams,
int serverLocalPort,
@NotNull PythonCommandLineState pyState,
@NotNull GeneralCommandLine cmd) {
PythonHelper.DEBUGGER.addToGroup(debugParams, cmd);
configureDebugParameters(project, debugParams, pyState, cmd);
@@ -294,14 +306,7 @@ public class PyDebugRunner extends GenericProgramRunner {
configureDebugEnvironment(project, cmd.getEnvironment());
final String[] debuggerArgs = new String[]{
CLIENT_PARAM, "127.0.0.1",
PORT_PARAM, String.valueOf(serverLocalPort),
FILE_PARAM
};
for (String s : debuggerArgs) {
debugParams.addParameter(s);
}
configureDebugConnectionParameters(debugParams, serverLocalPort);
}
public static void configureDebugEnvironment(@NotNull Project project, Map<String, String> environment) {
@@ -324,14 +329,19 @@ public class PyDebugRunner extends GenericProgramRunner {
}
protected void configureDebugParameters(@NotNull Project project,
@NotNull ParamsGroup debugParams,
@NotNull PythonCommandLineState pyState,
@NotNull GeneralCommandLine cmd) {
@NotNull ParamsGroup debugParams,
@NotNull PythonCommandLineState pyState,
@NotNull GeneralCommandLine cmd) {
if (pyState.isMultiprocessDebug()) {
//noinspection SpellCheckingInspection
debugParams.addParameter("--multiproc");
}
configureCommonDebugParameters(project, debugParams);
}
public static void configureCommonDebugParameters(@NotNull Project project,
@NotNull ParamsGroup debugParams) {
if (isModule) {
debugParams.addParameter("--module");
}
@@ -349,6 +359,17 @@ public class PyDebugRunner extends GenericProgramRunner {
}
}
private static void configureDebugConnectionParameters(@NotNull ParamsGroup debugParams, int serverLocalPort) {
final String[] debuggerArgs = new String[]{
CLIENT_PARAM, "127.0.0.1",
PORT_PARAM, String.valueOf(serverLocalPort),
FILE_PARAM
};
for (String s : debuggerArgs) {
debugParams.addParameter(s);
}
}
private static void addProjectRootsToEnv(@NotNull Project project, @NotNull Map<String, String> environment) {
List<String> roots = Lists.newArrayList();
@@ -0,0 +1,56 @@
/*
* Copyright 2000-2016 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.jetbrains.python.debugger;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.remote.RemoteSdkAdditionalData;
import com.intellij.xdebugger.XDebugSession;
import com.jetbrains.python.run.PythonCommandLineState;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Alexander Koshevoy
*/
public abstract class PyRemoteDebugSessionCreator {
public static final ExtensionPointName<PyRemoteDebugSessionCreator> EP_NAME
= ExtensionPointName.create("Pythonid.pyRemoteDebugSessionCreator");
protected abstract boolean appliesTo(@NotNull RemoteSdkAdditionalData remoteSdkAdditionalData);
@NotNull
public abstract XDebugSession createSession(@NotNull PyDebugRunner runner,
@NotNull PythonCommandLineState state,
@NotNull ExecutionEnvironment environment)
throws ExecutionException;
@Contract("null -> null")
@Nullable
public static PyRemoteDebugSessionCreator findExtension(@Nullable RemoteSdkAdditionalData remoteSdkAdditionalData) {
if (remoteSdkAdditionalData == null) {
return null;
}
for (PyRemoteDebugSessionCreator sessionCreator : EP_NAME.getExtensions()) {
if (sessionCreator.appliesTo(remoteSdkAdditionalData)) {
return sessionCreator;
}
}
return null;
}
}