mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
Use `ExecService` `api.kt` to exec any binary and extensions from `execService.python/api.kt` for python-specific things (i.e helpers) GitOrigin-RevId: bb217798a9d1ee886c4b12220ec1f66a5ef08336
74 lines
3.2 KiB
Kotlin
74 lines
3.2 KiB
Kotlin
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
|
package com.jetbrains
|
|
|
|
import com.intellij.execution.processTools.getBareExecutionResult
|
|
import com.intellij.execution.processTools.getResultStdoutStr
|
|
import com.intellij.execution.processTools.mapFlat
|
|
import com.intellij.execution.target.*
|
|
import com.intellij.openapi.progress.EmptyProgressIndicator
|
|
import com.intellij.openapi.progress.ProgressIndicator
|
|
import com.intellij.openapi.project.Project
|
|
import com.intellij.openapi.projectRoots.Sdk
|
|
import com.intellij.util.concurrency.ThreadingAssertions
|
|
import com.jetbrains.python.PYTHON_VERSION_ARG
|
|
import com.jetbrains.python.run.PythonInterpreterTargetEnvironmentFactory
|
|
import com.jetbrains.python.sdk.configureBuilderToRunPythonOnTarget
|
|
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
|
|
import com.jetbrains.python.sdk.getOrCreateAdditionalData
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.withContext
|
|
import org.junit.Assert
|
|
|
|
|
|
internal suspend fun getPythonVersion(sdk: Sdk, request: TargetEnvironmentRequest): String? {
|
|
val commandLineBuilder = TargetedCommandLineBuilder(request)
|
|
sdk.configureBuilderToRunPythonOnTarget(commandLineBuilder)
|
|
val flavor = sdk.getOrCreateAdditionalData().flavor
|
|
return getPythonVersion(commandLineBuilder, flavor, request)
|
|
}
|
|
|
|
internal suspend fun getPythonVersion(commandLineBuilder: TargetedCommandLineBuilder,
|
|
flavor: PythonSdkFlavor<*>,
|
|
request: TargetEnvironmentRequest): String? {
|
|
commandLineBuilder.addParameter(PYTHON_VERSION_ARG)
|
|
val commandLine = commandLineBuilder.build()
|
|
val result = request
|
|
.prepareEnvironment(TargetProgressIndicator.EMPTY)
|
|
.createProcess(commandLine).getBareExecutionResult()
|
|
|
|
// Conda python may send version to stderr, check both
|
|
|
|
val err = result.stdErr.decodeToString()
|
|
val out = result.stdOut.decodeToString()
|
|
Assert.assertEquals(err, 0, result.exitCode)
|
|
val versionString = out.ifBlank { err }.trim()
|
|
return PythonSdkFlavor.getVersionStringFromOutput(versionString)
|
|
}
|
|
|
|
/**
|
|
* @return path to python binary on target
|
|
*/
|
|
suspend fun Sdk.getPythonBinaryPath(project: Project): Result<FullPathOnTarget> {
|
|
return getCommandOutput(project, EmptyProgressIndicator(), "import sys; print(sys.executable)").map { it.trim() }
|
|
}
|
|
|
|
/**
|
|
* Runs python [command] and returns stdout or error
|
|
*/
|
|
private suspend fun Sdk.getCommandOutput(project: Project, indicator: ProgressIndicator, command: String): Result<String> {
|
|
ThreadingAssertions.assertBackgroundThread()
|
|
|
|
val pyRequest = PythonInterpreterTargetEnvironmentFactory.findPythonTargetInterpreter(sdk = this, project)
|
|
val targetEnvRequest = pyRequest.targetEnvironmentRequest
|
|
|
|
val cmdBuilder = TargetedCommandLineBuilder(targetEnvRequest)
|
|
configureBuilderToRunPythonOnTarget(cmdBuilder)
|
|
cmdBuilder.addParameter("-c")
|
|
cmdBuilder.addParameter(command)
|
|
val cmd = cmdBuilder.build()
|
|
|
|
val environment = targetEnvRequest.prepareEnvironment(TargetProgressIndicatorAdapter(indicator))
|
|
return withContext(Dispatchers.IO) {
|
|
environment.createProcessWithResult(cmd).mapFlat { it.getResultStdoutStr() }
|
|
}
|
|
} |