mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
Python: Make createVirtualenv suspend, process error and cover with tests.
We now fail silently in case of any error. This commit fixes it. GitOrigin-RevId: 76977843a892dd450d8292378a7cefb522cb78c1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
42f7566596
commit
ae6bda01df
@@ -572,7 +572,7 @@ remote.interpreter.feature.is.not.available=Remote interpreter feature is not av
|
||||
|
||||
# What to display of user entered junk
|
||||
commandLine.commandNotFound={0}: command not found
|
||||
commandLine.directoryCantBeAccessed={0}: bad directory
|
||||
commandLine.directoryCantBeAccessed={0}: Directory couldn't be found or doesn't contain virtual env
|
||||
|
||||
# Window with actions
|
||||
# "X" button title
|
||||
@@ -1115,6 +1115,8 @@ pure.python.project=Pure Python
|
||||
project.cannot.be.generated=Project cannot be generated
|
||||
error.in.project.generation=Error in Project Generation
|
||||
|
||||
sdk.venv.process=Creating virtual env
|
||||
sdk.venv.error=Error creating virtual env: {0}
|
||||
sdk.has.been.configured.as.the.project.interpreter={0} has been configured as a project interpreter
|
||||
sdk.has.been.configured.notification.name=Python interpreter configured
|
||||
configuring.interpreters.link=Configure Interpreters
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
package com.jetbrains.python.sdk.add.v2
|
||||
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.writeAction
|
||||
import com.intellij.openapi.module.ModuleUtil
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
@@ -23,7 +22,6 @@ import com.jetbrains.python.sdk.flavors.conda.PyCondaCommand
|
||||
import com.jetbrains.python.sdk.suggestAssociatedSdkName
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.nio.file.InvalidPathException
|
||||
import java.nio.file.Path
|
||||
|
||||
|
||||
@@ -31,32 +29,28 @@ import java.nio.file.Path
|
||||
suspend fun PythonMutableTargetAddInterpreterModel.setupVirtualenv(venvPath: Path, projectPath: Path): Result<Sdk> {
|
||||
val baseSdk = state.baseInterpreter.get()!!
|
||||
|
||||
val venvPathOnTarget = venvPath.convertToPathOnTarget(targetEnvironmentConfiguration)
|
||||
|
||||
val baseSdkPath = when (baseSdk) {
|
||||
is InstallableSelectableInterpreter -> installBaseSdk(baseSdk.sdk, this.existingSdks)?.homePath // todo handle errors
|
||||
is ExistingSelectableInterpreter -> baseSdk.sdk.homePath
|
||||
is DetectedSelectableInterpreter, is ManuallyAddedSelectableInterpreter -> baseSdk.homePath
|
||||
}
|
||||
val baseSdkPath = Path.of(when (baseSdk) {
|
||||
is InstallableSelectableInterpreter -> installBaseSdk(baseSdk.sdk, this.existingSdks)?.homePath // todo handle errors
|
||||
is ExistingSelectableInterpreter -> baseSdk.sdk.homePath
|
||||
is DetectedSelectableInterpreter, is ManuallyAddedSelectableInterpreter -> baseSdk.homePath
|
||||
}!!)
|
||||
|
||||
|
||||
withContext(Dispatchers.EDT) {
|
||||
createVirtualenv(baseSdkPath!!,
|
||||
venvPathOnTarget,
|
||||
try {
|
||||
createVirtualenv(baseSdkPath,
|
||||
venvPath,
|
||||
projectPath,
|
||||
inheritSitePackages = state.inheritSitePackages.get())
|
||||
}
|
||||
|
||||
if (targetEnvironmentConfiguration != null) error("Remote targets aren't supported")
|
||||
val dir = try {
|
||||
Path.of(venvPathOnTarget)
|
||||
}
|
||||
catch (e: InvalidPathException) {
|
||||
catch (e: ExecutionException) {
|
||||
return Result.failure(e)
|
||||
}
|
||||
val venvPython = VirtualEnvReader.Instance.findPythonInPythonRoot(dir)
|
||||
|
||||
if (targetEnvironmentConfiguration != null) error("Remote targets aren't supported")
|
||||
val venvPython = VirtualEnvReader.Instance.findPythonInPythonRoot(venvPath)
|
||||
if (venvPython == null) {
|
||||
return failure(message("commandLine.directoryCantBeAccessed", venvPathOnTarget))
|
||||
return failure(message("commandLine.directoryCantBeAccessed", venvPath))
|
||||
}
|
||||
|
||||
val homeFile = try {
|
||||
@@ -69,7 +63,7 @@ suspend fun PythonMutableTargetAddInterpreterModel.setupVirtualenv(venvPath: Pat
|
||||
return Result.failure(e)
|
||||
}
|
||||
if (homeFile == null) {
|
||||
return failure(message("commandLine.directoryCantBeAccessed", venvPathOnTarget))
|
||||
return failure(message("commandLine.directoryCantBeAccessed", venvPath))
|
||||
}
|
||||
|
||||
// "suggest name" calls external process and can't be called from EDT
|
||||
|
||||
@@ -1,49 +1,54 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.sdk.add.v2
|
||||
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.execution.process.CapturingProcessHandler
|
||||
import com.intellij.execution.target.TargetProgressIndicator
|
||||
import com.intellij.execution.target.TargetedCommandLineBuilder
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.platform.ide.progress.ModalTaskOwner
|
||||
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import com.intellij.platform.ide.progress.TaskCancellation
|
||||
import com.intellij.platform.ide.progress.withModalProgress
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.PythonHelper
|
||||
import com.jetbrains.python.run.PythonExecution
|
||||
import com.jetbrains.python.run.prepareHelperScriptExecution
|
||||
import com.jetbrains.python.run.target.HelpersAwareLocalTargetEnvironmentRequest
|
||||
import com.jetbrains.python.sdk.PySdkSettings
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import java.nio.file.Path
|
||||
|
||||
@RequiresEdt // There is runBlockingModel down the code
|
||||
fun createVirtualenv(
|
||||
baseInterpreterPath: String,
|
||||
venvRoot: String,
|
||||
/**
|
||||
* Creates a Python virtual environment, throws [ExecutionException] if creation process failed
|
||||
*/
|
||||
@Throws(ExecutionException::class)
|
||||
@Internal
|
||||
suspend fun createVirtualenv(
|
||||
baseInterpreterPath: Path,
|
||||
venvRoot: Path,
|
||||
projectBasePath: Path,
|
||||
inheritSitePackages: Boolean = false,
|
||||
) {
|
||||
|
||||
// todo find request for targets (need sdk, maybe can work around it )
|
||||
//PythonInterpreterTargetEnvironmentFactory.findPythonTargetInterpreter()
|
||||
val request = HelpersAwareLocalTargetEnvironmentRequest()
|
||||
//val targetRequest = request.targetEnvironmentRequest
|
||||
|
||||
val execution = prepareHelperScriptExecution(PythonHelper.VIRTUALENV_ZIPAPP, request) // todo what about legacy pythons?
|
||||
if (inheritSitePackages) {
|
||||
execution.addParameter("--system-site-packages")
|
||||
}
|
||||
|
||||
execution.addParameter(venvRoot)
|
||||
execution.addParameter(venvRoot.toString())
|
||||
request.preparePyCharmHelpers()
|
||||
|
||||
val targetEnvironment = request.targetEnvironmentRequest.prepareEnvironment(TargetProgressIndicator.EMPTY)
|
||||
|
||||
//val targetedCommandLine = execution.buildTargetedCommandLine(targetEnvironment, sdk = null, emptyList())
|
||||
|
||||
|
||||
val commandLineBuilder = TargetedCommandLineBuilder(targetEnvironment.request)
|
||||
commandLineBuilder.setWorkingDirectory(projectBasePath.toString())
|
||||
|
||||
commandLineBuilder.setExePath(baseInterpreterPath)
|
||||
commandLineBuilder.setExePath(baseInterpreterPath.toString())
|
||||
|
||||
execution.pythonScriptPath?.let { commandLineBuilder.addParameter(it.apply(targetEnvironment)) }
|
||||
?: throw IllegalArgumentException("Python script path must be set")
|
||||
@@ -72,9 +77,16 @@ fun createVirtualenv(
|
||||
|
||||
val handler = CapturingProcessHandler(process, targetedCommandLine.charset, targetedCommandLine.getCommandPresentation(targetEnvironment))
|
||||
|
||||
val output = runWithModalProgressBlocking(ModalTaskOwner.guess(), "creating venv") {
|
||||
handler.runProcess(60 * 1000)
|
||||
val result = withModalProgress(ModalTaskOwner.guess(), PyBundle.message("sdk.venv.process"), TaskCancellation.nonCancellable()) {
|
||||
withContext(Dispatchers.IO) {
|
||||
handler.runProcess()
|
||||
}
|
||||
}
|
||||
if (result.exitCode != 0) {
|
||||
throw ExecutionException(PyBundle.message("sdk.venv.error", result.stderr))
|
||||
}
|
||||
|
||||
PySdkSettings.instance.preferredVirtualEnvBaseSdk = baseInterpreterPath
|
||||
withContext(Dispatchers.EDT) {
|
||||
PySdkSettings.instance.preferredVirtualEnvBaseSdk = baseInterpreterPath.toString()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user