mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
PY-77381 Unable to select an existing Poetry environment as a project interpreter
Add PoetryExistingEnvironmentSelector (cherry picked from commit 4fc75a24669d8a2fc12b5ff963cc5715ebc6ab3a) GitOrigin-RevId: b5ed7b45a3b4e27786bf899ab42f9ffe757d7f9d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
18f5e952db
commit
1c33aab97d
@@ -551,6 +551,7 @@ sdk.create.tooltip.browse=Browse\u2026
|
|||||||
sdk.create.custom.venv.install.fix.title=Install {0} {1}
|
sdk.create.custom.venv.install.fix.title=Install {0} {1}
|
||||||
sdk.create.custom.venv.run.error.message= Error Running {0}
|
sdk.create.custom.venv.run.error.message= Error Running {0}
|
||||||
sdk.create.custom.venv.progress.title.detect.executable=Detect executable
|
sdk.create.custom.venv.progress.title.detect.executable=Detect executable
|
||||||
|
sdk.create.custom.existing.env.title ={0} env use
|
||||||
|
|
||||||
sdk.create.targets.local=Local Machine
|
sdk.create.targets.local=Local Machine
|
||||||
sdk.create.custom.virtualenv=Virtualenv
|
sdk.create.custom.virtualenv=Virtualenv
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
// 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.openapi.observable.properties.ObservableMutableProperty
|
||||||
|
import com.intellij.openapi.observable.util.notEqualsTo
|
||||||
|
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||||
|
import com.intellij.ui.dsl.builder.Align
|
||||||
|
import com.intellij.ui.dsl.builder.Panel
|
||||||
|
import com.jetbrains.python.PyBundle.message
|
||||||
|
import com.jetbrains.python.newProject.collector.InterpreterStatisticsInfo
|
||||||
|
import com.jetbrains.python.sdk.ModuleOrProject
|
||||||
|
import com.jetbrains.python.sdk.PySdkUtil
|
||||||
|
import com.jetbrains.python.sdk.PythonSdkUtil
|
||||||
|
import com.jetbrains.python.sdk.poetry.pyProjectToml
|
||||||
|
import com.jetbrains.python.statistics.InterpreterCreationMode
|
||||||
|
import com.jetbrains.python.statistics.InterpreterType
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.jetbrains.annotations.ApiStatus.Internal
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
@Internal
|
||||||
|
abstract class CustomExistingEnvironmentSelector(private val name: String, model: PythonMutableTargetAddInterpreterModel, protected val moduleOrProject: ModuleOrProject) : PythonExistingEnvironmentConfigurator(model) {
|
||||||
|
private lateinit var comboBox: PythonInterpreterComboBox
|
||||||
|
protected val existingEnvironments: MutableStateFlow<List<PythonSelectableInterpreter>> = MutableStateFlow(emptyList())
|
||||||
|
protected val selectedEnv: ObservableMutableProperty<PythonSelectableInterpreter?> = propertyGraph.property(null)
|
||||||
|
|
||||||
|
init {
|
||||||
|
model.scope.launch {
|
||||||
|
val modulePath = when (moduleOrProject) {
|
||||||
|
is ModuleOrProject.ProjectOnly -> moduleOrProject.project.basePath?.let { Path.of(it) }
|
||||||
|
is ModuleOrProject.ModuleAndProject -> pyProjectToml(moduleOrProject.module)?.let { Path.of(it.parent.path) }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modulePath != null) {
|
||||||
|
detectEnvironments(modulePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun buildOptions(panel: Panel, validationRequestor: DialogValidationRequestor) {
|
||||||
|
with(panel) {
|
||||||
|
executableSelector(
|
||||||
|
executable,
|
||||||
|
validationRequestor,
|
||||||
|
message("sdk.create.custom.venv.executable.path", name),
|
||||||
|
message("sdk.create.custom.venv.missing.text", name),
|
||||||
|
).component
|
||||||
|
|
||||||
|
row(message("sdk.create.custom.existing.env.title", name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() })) {
|
||||||
|
comboBox = pythonInterpreterComboBox(selectedEnv, model, { path -> addEnvByPath(path) }, model.interpreterLoading)
|
||||||
|
.align(Align.FILL)
|
||||||
|
.component
|
||||||
|
}.visibleIf(executable.notEqualsTo(""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onShown() {
|
||||||
|
comboBox.setItems(existingEnvironments)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createStatisticsInfo(target: PythonInterpreterCreationTargets): InterpreterStatisticsInfo {
|
||||||
|
val statisticsTarget = target.toStatisticsField()
|
||||||
|
|
||||||
|
return InterpreterStatisticsInfo(interpreterType,
|
||||||
|
statisticsTarget,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
InterpreterCreationMode.CUSTOM)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addEnvByPath(path: String) {
|
||||||
|
val languageLevel = PySdkUtil.getLanguageLevelForSdk(PythonSdkUtil.findSdkByKey(path))
|
||||||
|
val interpreter = ManuallyAddedSelectableInterpreter(path, languageLevel)
|
||||||
|
existingEnvironments.value += interpreter
|
||||||
|
}
|
||||||
|
|
||||||
|
internal abstract val executable: ObservableMutableProperty<String>
|
||||||
|
internal abstract val interpreterType: InterpreterType
|
||||||
|
internal abstract suspend fun detectEnvironments(modulePath: Path)
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// 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.openapi.observable.properties.ObservableMutableProperty
|
||||||
|
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||||
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
|
import com.jetbrains.python.sdk.ModuleOrProject
|
||||||
|
import com.jetbrains.python.sdk.poetry.detectPoetryEnvs
|
||||||
|
import com.jetbrains.python.sdk.poetry.isPoetry
|
||||||
|
import com.jetbrains.python.sdk.poetry.setupPoetrySdkUnderProgress
|
||||||
|
import com.jetbrains.python.statistics.InterpreterType
|
||||||
|
import com.jetbrains.python.statistics.version
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
|
class PoetryExistingEnvironmentSelector(model: PythonMutableTargetAddInterpreterModel, moduleOrProject: ModuleOrProject) : CustomExistingEnvironmentSelector("poetry", model, moduleOrProject) {
|
||||||
|
override val executable: ObservableMutableProperty<String> = model.state.poetryExecutable
|
||||||
|
override val interpreterType: InterpreterType = InterpreterType.POETRY
|
||||||
|
|
||||||
|
override suspend fun getOrCreateSdk(moduleOrProject: ModuleOrProject): Result<Sdk> {
|
||||||
|
val selectedInterpreter = selectedEnv.get()
|
||||||
|
ProjectJdkTable.getInstance().allJdks.find { sdk -> sdk.isPoetry && sdk.homePath == selectedInterpreter?.homePath }?.let { return Result.success(it) }
|
||||||
|
val module = when (moduleOrProject) {
|
||||||
|
is ModuleOrProject.ModuleAndProject -> {
|
||||||
|
moduleOrProject.module
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
return setupPoetrySdkUnderProgress(moduleOrProject.project, module, ProjectJdkTable.getInstance().allJdks.toList(), null, selectedInterpreter?.homePath, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun detectEnvironments(modulePath: Path) {
|
||||||
|
val existingEnvs = detectPoetryEnvs(null, null, modulePath.pathString).mapNotNull {
|
||||||
|
env -> env.homePath?.let { path -> DetectedSelectableInterpreter(path, env.version) }
|
||||||
|
}
|
||||||
|
|
||||||
|
existingEnvironments.value = existingEnvs
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,10 +34,11 @@ class PythonAddCustomInterpreter(val model: PythonMutableTargetAddInterpreterMod
|
|||||||
UV to EnvironmentCreatorUv(model, moduleOrProject),
|
UV to EnvironmentCreatorUv(model, moduleOrProject),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val existingInterpreterSelectors = mapOf(
|
private val existingInterpreterSelectors = buildMap {
|
||||||
PYTHON to PythonExistingEnvironmentSelector(model),
|
put(PYTHON, PythonExistingEnvironmentSelector(model))
|
||||||
CONDA to CondaExistingEnvironmentSelector(model, errorSink),
|
put(CONDA, CondaExistingEnvironmentSelector(model, errorSink))
|
||||||
)
|
if (moduleOrProject != null) put(POETRY, PoetryExistingEnvironmentSelector(model, moduleOrProject))
|
||||||
|
}
|
||||||
|
|
||||||
val currentSdkManager: PythonAddEnvironment
|
val currentSdkManager: PythonAddEnvironment
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
@@ -274,8 +274,6 @@ open class AddInterpreterState(propertyGraph: PropertyGraph) {
|
|||||||
* Use [PythonAddInterpreterModel.getBaseCondaOrError]
|
* Use [PythonAddInterpreterModel.getBaseCondaOrError]
|
||||||
*/
|
*/
|
||||||
val baseCondaEnv: ObservableMutableProperty<PyCondaEnv?> = propertyGraph.property(null)
|
val baseCondaEnv: ObservableMutableProperty<PyCondaEnv?> = propertyGraph.property(null)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MutableTargetState(propertyGraph: PropertyGraph) : AddInterpreterState(propertyGraph) {
|
class MutableTargetState(propertyGraph: PropertyGraph) : AddInterpreterState(propertyGraph) {
|
||||||
|
|||||||
@@ -154,9 +154,9 @@ internal fun runPoetryInBackground(module: Module, args: List<String>, @NlsSafe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal suspend fun detectPoetryEnvs(module: Module?, existingSdkPaths: Set<String>, projectPath: @SystemIndependent @NonNls String?): List<PyDetectedSdk> {
|
internal suspend fun detectPoetryEnvs(module: Module?, existingSdkPaths: Set<String>?, projectPath: @SystemIndependent @NonNls String?): List<PyDetectedSdk> {
|
||||||
val path = module?.basePath?.let { Path.of(it) } ?: projectPath?.let { Path.of(it) } ?: return emptyList()
|
val path = module?.basePath?.let { Path.of(it) } ?: projectPath?.let { Path.of(it) } ?: return emptyList()
|
||||||
return getPoetryEnvs(path).filter { existingSdkPaths.contains(getPythonExecutable(it)) }.map { PyDetectedSdk(getPythonExecutable(it)) }
|
return getPoetryEnvs(path).filter { existingSdkPaths?.contains(getPythonExecutable(it)) != false }.map { PyDetectedSdk(getPythonExecutable(it)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal suspend fun getPoetryVersion(): String? = runPoetry(null, "--version").getOrNull()?.split(' ')?.lastOrNull()
|
internal suspend fun getPoetryVersion(): String? = runPoetry(null, "--version").getOrNull()?.split(' ')?.lastOrNull()
|
||||||
|
|||||||
Reference in New Issue
Block a user