/python/src/com/jetbrains/python/console/PydevConsoleCli.kt
https://github.com/JetBrains/intellij-community · Kotlin · 140 lines · 78 code · 17 blank · 45 comment · 0 complexity · a155aae6696069fc3a0cd1737294107c MD5 · raw file
- // 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.
- @file:JvmName("PydevConsoleCli")
- package com.jetbrains.python.console
- import com.intellij.execution.ExecutionException
- import com.intellij.execution.configurations.GeneralCommandLine
- import com.intellij.execution.configurations.ParamsGroup
- import com.intellij.execution.target.HostPort
- import com.intellij.execution.target.TargetEnvironment
- import com.intellij.execution.target.value.TargetEnvironmentFunction
- import com.intellij.openapi.projectRoots.Sdk
- import com.intellij.openapi.projectRoots.SdkAdditionalData
- import com.jetbrains.python.PythonHelper
- import com.jetbrains.python.run.PythonCommandLineState
- import com.jetbrains.python.run.PythonExecution
- import com.jetbrains.python.run.prepareHelperScriptExecution
- import com.jetbrains.python.run.target.HelpersAwareTargetEnvironmentRequest
- import com.jetbrains.python.sdk.PythonEnvUtil
- import com.jetbrains.python.sdk.PythonSdkAdditionalData
- import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
- import java.io.File
- import java.util.function.Function
- const val MODE_OPTION = "mode"
- const val MODE_OPTION_SERVER_VALUE = "server"
- const val MODE_OPTION_CLIENT_VALUE = "client"
- const val HOST_OPTION = "host"
- const val PORT_OPTION = "port"
- private fun getOptionString(name: String, value: Any): String = "--$name=$value"
- private fun getOptionString(name: String, value: TargetEnvironmentFunction<*>): TargetEnvironmentFunction<String> =
- value.andThen { it: Any? -> "--$name=$it" }
- /**
- * 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(sdk: Sdk, port: Int) {
- initializePydevConsoleScriptGroup(PythonSdkFlavor.getFlavor(sdk)).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.
- *
- * Updates Python path according to the flavor defined in [sdkAdditionalData].
- *
- * @param sdkAdditionalData the additional data where [PythonSdkFlavor] is taken
- * from
- * @param port the optional port that Python console script will listen at
- *
- * @see PythonHelper.CONSOLE
- */
- @JvmOverloads
- fun GeneralCommandLine.setupPythonConsoleScriptInServerMode(sdkAdditionalData: SdkAdditionalData, port: Int? = null) {
- initializePydevConsoleScriptGroup((sdkAdditionalData as? PythonSdkAdditionalData)?.flavor).appendServerModeParameters(port)
- }
- private fun GeneralCommandLine.initializePydevConsoleScriptGroup(pythonSdkFlavor: PythonSdkFlavor?): ParamsGroup {
- val group: ParamsGroup = parametersList.getParamsGroup(PythonCommandLineState.GROUP_SCRIPT)?.apply { parametersList.clearAll() }
- ?: parametersList.addParamsGroup(PythonCommandLineState.GROUP_SCRIPT)
- val pythonPathEnv = hashMapOf<String, String>()
- PythonHelper.CONSOLE.addToPythonPath(pythonPathEnv)
- val consolePythonPath = pythonPathEnv[PythonEnvUtil.PYTHONPATH]
- // here we get Python console path for the system interpreter
- // let us convert it to the project interpreter path
- consolePythonPath?.split(File.pathSeparator)?.let { pythonPathList ->
- pythonSdkFlavor?.initPythonPath(pythonPathList, false, environment) ?: PythonEnvUtil.addToPythonPath(environment, pythonPathList)
- }
- group.addParameter(PythonHelper.CONSOLE.asParamString())
- // fix `AttributeError` when running Python Console on IronPython
- pythonSdkFlavor?.extraDebugOptions?.let { extraDebugOptions ->
- val exeGroup = parametersList.getParamsGroup(PythonCommandLineState.GROUP_EXE_OPTIONS)
- extraDebugOptions.forEach { exeGroup?.addParameter(it) }
- }
- 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)
- }
- fun createPythonConsoleScriptInServerMode(serverPort: Int,
- helpersAwareTargetRequest: HelpersAwareTargetEnvironmentRequest): PythonExecution {
- val pythonScriptExecution = prepareHelperScriptExecution(PythonHelper.CONSOLE, helpersAwareTargetRequest)
- pythonScriptExecution.addParameter(getOptionString(MODE_OPTION, MODE_OPTION_SERVER_VALUE))
- pythonScriptExecution.addParameter(getOptionString(PORT_OPTION, serverPort))
- return pythonScriptExecution
- }
- /**
- * @param ideServerPort the host and port where the IDE being Python
- * Console frontend listens for the connection
- */
- fun createPythonConsoleScriptInClientMode(ideServerPort: Function<TargetEnvironment, HostPort>,
- helpersAwareTargetRequest: HelpersAwareTargetEnvironmentRequest): PythonExecution {
- val pythonScriptExecution = prepareHelperScriptExecution(PythonHelper.CONSOLE, helpersAwareTargetRequest)
- pythonScriptExecution.addParameter(getOptionString(MODE_OPTION, MODE_OPTION_CLIENT_VALUE))
- pythonScriptExecution.addParameter(getOptionString(HOST_OPTION, ideServerPort.andThen(HostPort::host)))
- pythonScriptExecution.addParameter(getOptionString(PORT_OPTION, ideServerPort.andThen(HostPort::port)))
- return pythonScriptExecution
- }