From 4c4e4d1a634471a691bf76aa489a68ab4e681ea7 Mon Sep 17 00:00:00 2001 From: Alexander Koshevoy Date: Wed, 20 Jun 2018 12:09:28 +0300 Subject: [PATCH] PY-18029 Extract Python console script interaction to a separate class Create `PydevConsoleCli` with setup methods for client and server modes of Python console script. --- .../python/console/PydevConsoleCli.kt | 84 +++++++++++++++++++ .../console/PydevConsoleRunnerImpl.java | 9 +- 2 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 python/src/com/jetbrains/python/console/PydevConsoleCli.kt diff --git a/python/src/com/jetbrains/python/console/PydevConsoleCli.kt b/python/src/com/jetbrains/python/console/PydevConsoleCli.kt new file mode 100644 index 000000000000..a5691cb8eda6 --- /dev/null +++ b/python/src/com/jetbrains/python/console/PydevConsoleCli.kt @@ -0,0 +1,84 @@ +@file:JvmName("PydevConsoleCli") + +// Copyright 2000-2018 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.jetbrains.python.console + +import com.intellij.execution.ExecutionException +import com.intellij.execution.configurations.GeneralCommandLine +import com.intellij.execution.configurations.ParamsGroup +import com.jetbrains.python.PythonHelper +import com.jetbrains.python.run.PythonCommandLineState + +const val MODE_OPTION = "mode" +const val MODE_OPTION_SERVER_VALUE = "server" +const val MODE_OPTION_CLIENT_VALUE = "client" + +const val PORT_OPTION = "port" + +private fun getOptionString(name: String, value: Any): String = "--$name=$value" + +/** + * Adds new or replaces existing [PythonCommandLineState.GROUP_SCRIPT] + * parameters of [this] command line with the path to Python console script + * (*pydevconsole.py*) and parameters required for running it in the *client* + * mode. + * + * @param port the port that Python console script will connect to + * + * @see PythonHelper.CONSOLE + */ +fun GeneralCommandLine.setupPythonConsoleScriptInClientMode(port: Int) { + initializePydevConsoleScriptGroup().appendClientModeParameters(port) +} + +/** + * Adds new or replaces existing [PythonCommandLineState.GROUP_SCRIPT] + * parameters of [this] command line with the path to Python console script + * (*pydevconsole.py*) and parameters required for running it in the *server* + * mode. + * + * @param port the optional port that Python console script will listen at + * + * @see PythonHelper.CONSOLE + */ +@JvmOverloads +fun GeneralCommandLine.setupPythonConsoleScriptInServerMode(port: Int? = null) { + initializePydevConsoleScriptGroup().appendServerModeParameters(port) +} + +private fun GeneralCommandLine.initializePydevConsoleScriptGroup(): ParamsGroup { + val group: ParamsGroup = parametersList.getParamsGroup(PythonCommandLineState.GROUP_SCRIPT)?.apply { parametersList.clearAll() } + ?: parametersList.addParamsGroup(PythonCommandLineState.GROUP_SCRIPT) + + PythonHelper.CONSOLE.addToGroup(group, this) + + return group +} + +private fun ParamsGroup.appendServerModeParameters(port: Int? = null) { + addParameter(getOptionString(MODE_OPTION, MODE_OPTION_SERVER_VALUE)) + port?.let { addParameter(getOptionString(PORT_OPTION, it)) } +} + +private fun ParamsGroup.appendClientModeParameters(port: Int) { + addParameter(getOptionString(MODE_OPTION, MODE_OPTION_CLIENT_VALUE)) + addParameter(getOptionString(PORT_OPTION, port)) +} + +/** + * Waits for Python console server to be started. The indication for this is + * the server port that Python console script outputs to *stdout* when the + * server socket is bound to the port and it is listening to it. + * + * The connection to Python console script server should be established *after* + * this method finishes. + * + * @throws ExecutionException if timeout occurred or an other error + * + * @see PydevConsoleRunnerImpl.PORTS_WAITING_TIMEOUT + * @see PydevConsoleRunnerImpl.getRemotePortFromProcess + */ +@Throws(ExecutionException::class) +fun waitForPythonConsoleServerToBeStarted(process: Process) { + PydevConsoleRunnerImpl.getRemotePortFromProcess(process) +} \ No newline at end of file diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunnerImpl.java b/python/src/com/jetbrains/python/console/PydevConsoleRunnerImpl.java index 20b1697b6c49..5ca6b400efa3 100644 --- a/python/src/com/jetbrains/python/console/PydevConsoleRunnerImpl.java +++ b/python/src/com/jetbrains/python/console/PydevConsoleRunnerImpl.java @@ -69,7 +69,6 @@ import com.intellij.xdebugger.XDebugProcess; import com.intellij.xdebugger.XDebugProcessStarter; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerManager; -import com.jetbrains.python.PythonHelper; import com.jetbrains.python.console.actions.ShowVarsAction; import com.jetbrains.python.console.pydev.ConsoleCommunicationListener; import com.jetbrains.python.debugger.PyDebugRunner; @@ -361,13 +360,7 @@ public class PydevConsoleRunnerImpl implements PydevConsoleRunner { exeGroup.addParametersString(runParams.getInterpreterOptions()); } - ParamsGroup group = cmd.getParametersList().getParamsGroup(PythonCommandLineState.GROUP_SCRIPT); - if (group == null) { - group = cmd.getParametersList().addParamsGroup(PythonCommandLineState.GROUP_SCRIPT); - } - PythonHelper.CONSOLE.addToGroup(group, cmd); - - group.addParameters("--mode=client", "--port=" + port); + PydevConsoleCli.setupPythonConsoleScriptInClientMode(cmd, port); return cmd; }