mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
PY-85637 Persist tool path when selecting existing environment
GitOrigin-RevId: 9e10ee0c38a025286f53362cf834bfcce57b665f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
79d33d4b01
commit
cdfdd3e82f
@@ -4,7 +4,6 @@ package com.jetbrains.python.sdk.add.v2
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.observable.util.transform
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
import com.jetbrains.python.PyBundle.message
|
||||
@@ -19,8 +18,6 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
|
||||
|
||||
@Internal
|
||||
internal abstract class CustomExistingEnvironmentSelector<P : PathHolder>(
|
||||
@@ -52,7 +49,7 @@ internal abstract class CustomExistingEnvironmentSelector<P : PathHolder>(
|
||||
validationRequestor = validationRequestor,
|
||||
onPathSelected = model::addManuallyAddedInterpreter,
|
||||
) {
|
||||
visibleIf(toolState.backProperty.transform { it?.validationResult?.successOrNull != null })
|
||||
visibleIf(toolState.isValidationSuccessful)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,12 +87,6 @@ internal abstract class CustomExistingEnvironmentSelector<P : PathHolder>(
|
||||
)
|
||||
}
|
||||
|
||||
//private fun addEnvByPath(python: VanillaPythonWithLanguageLevel): PythonSelectableInterpreter {
|
||||
// val interpreter = ManuallyAddedSelectableInterpreter(python)
|
||||
// existingEnvironments.value = (existingEnvironments.value ?: emptyList()) + interpreter
|
||||
// return interpreter
|
||||
//}
|
||||
|
||||
internal abstract val toolState: PathValidator<Version, P, ValidatedPath.Executable<P>>
|
||||
internal abstract val interpreterType: InterpreterType
|
||||
internal abstract suspend fun detectEnvironments(modulePath: Path): List<DetectedSelectableInterpreter<P>>
|
||||
|
||||
@@ -71,8 +71,6 @@ internal abstract class CustomNewEnvironmentCreator<P : PathHolder>(
|
||||
}
|
||||
|
||||
override suspend fun getOrCreateSdk(moduleOrProject: ModuleOrProject): PyResult<Sdk> {
|
||||
savePathToExecutableToProperties(null)
|
||||
|
||||
// todo think about better error handling
|
||||
val selectedBasePython = model.state.baseInterpreter.get()!!
|
||||
val basePythonBinaryPath = model.installPythonIfNeeded(selectedBasePython)
|
||||
@@ -169,7 +167,7 @@ internal abstract class CustomNewEnvironmentCreator<P : PathHolder>(
|
||||
when (val r = installExecutableViaPythonScript(pythonExecutable, "-n", name, *versionArgs.toTypedArray())) {
|
||||
is Result.Success -> {
|
||||
val pathHolder = PathHolder.Eel(r.result)
|
||||
savePathToExecutableToProperties(pathHolder)
|
||||
savePathToExecutableToProperties(pathHolder as? P)
|
||||
}
|
||||
is Result.Failure -> {
|
||||
errorSink.emit(r.error)
|
||||
@@ -184,14 +182,6 @@ internal abstract class CustomNewEnvironmentCreator<P : PathHolder>(
|
||||
|
||||
internal open val installationVersion: String? = null
|
||||
|
||||
|
||||
/**
|
||||
* Saves the provided path to an executable in the properties of the environment
|
||||
*
|
||||
* @param [path] The path to the executable that needs to be saved. This may be null when tries to find automatically.
|
||||
*/
|
||||
internal abstract suspend fun savePathToExecutableToProperties(pathHolder: PathHolder?)
|
||||
|
||||
protected abstract suspend fun setupEnvSdk(moduleBasePath: Path, baseSdks: List<Sdk>, basePythonBinaryPath: P?, installPackages: Boolean): PyResult<Sdk>
|
||||
|
||||
internal open fun onVenvSelectExisting() {}
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.openapi.application.UI
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.observable.util.and
|
||||
import com.intellij.openapi.observable.util.not
|
||||
import com.intellij.openapi.observable.util.transform
|
||||
@@ -56,6 +57,9 @@ import kotlin.concurrent.atomics.AtomicBoolean
|
||||
import kotlin.concurrent.atomics.ExperimentalAtomicApi
|
||||
|
||||
interface PathValidator<T, P : PathHolder, VP : ValidatedPath<T, P>> {
|
||||
/**
|
||||
* [backProperty] should only be used in [PathValidator] and its inheritors
|
||||
*/
|
||||
val backProperty: ObservableMutableProperty<VP?>
|
||||
val isDirtyValue: ObservableMutableProperty<Boolean>
|
||||
val isValidationInProgress: Boolean
|
||||
@@ -64,6 +68,9 @@ interface PathValidator<T, P : PathHolder, VP : ValidatedPath<T, P>> {
|
||||
isDirtyValue.set(true)
|
||||
backProperty.set(null)
|
||||
}
|
||||
|
||||
val isValidationSuccessful: ObservableProperty<Boolean>
|
||||
get() = backProperty.transform { it?.validationResult?.successOrNull != null }
|
||||
}
|
||||
|
||||
private interface ValidationStatusExtension
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.openapi.diagnostic.getOrLogException
|
||||
import com.intellij.openapi.help.HelpManager
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.AtomicProperty
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
|
||||
@@ -63,6 +64,7 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.nio.file.Path
|
||||
import javax.swing.Icon
|
||||
|
||||
abstract class PythonAddEnvironment<P : PathHolder>(open val model: PythonAddInterpreterModel<P>) {
|
||||
@@ -73,6 +75,9 @@ abstract class PythonAddEnvironment<P : PathHolder>(open val model: PythonAddInt
|
||||
internal val propertyGraph
|
||||
get() = model.propertyGraph
|
||||
|
||||
protected abstract val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?>?
|
||||
protected abstract val toolExecutablePersister: suspend (P) -> Unit
|
||||
|
||||
abstract fun setupUI(panel: Panel, validationRequestor: DialogValidationRequestor)
|
||||
abstract fun onShown(scope: CoroutineScope)
|
||||
|
||||
@@ -84,6 +89,7 @@ abstract class PythonAddEnvironment<P : PathHolder>(open val model: PythonAddInt
|
||||
protected abstract suspend fun getOrCreateSdk(moduleOrProject: ModuleOrProject): PyResult<Sdk>
|
||||
|
||||
protected suspend fun setupSdk(moduleOrProject: ModuleOrProject): PyResult<Sdk> {
|
||||
savePathToExecutableToProperties(null)
|
||||
val sdk = getOrCreateSdk(moduleOrProject).getOr { return it }
|
||||
|
||||
moduleOrProject.project.excludeInnerVirtualEnv(sdk)
|
||||
@@ -110,6 +116,17 @@ abstract class PythonAddEnvironment<P : PathHolder>(open val model: PythonAddInt
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the provided path to an executable in the properties of the environment
|
||||
*
|
||||
* @param [pathHolder] The path holder of the path to the executable that needs to be saved. This may be null when we try to find the tool automatically.
|
||||
*/
|
||||
protected suspend fun savePathToExecutableToProperties(pathHolder: P?) {
|
||||
val savingPath = pathHolder ?: toolExecutable?.get()?.pathHolder ?: return
|
||||
if (!model.fileSystem.isLocal) return
|
||||
toolExecutablePersister(savingPath)
|
||||
}
|
||||
|
||||
open suspend fun createPythonModuleStructure(module: Module): PyResult<Unit> = Result.success(Unit)
|
||||
|
||||
abstract fun createStatisticsInfo(target: PythonInterpreterCreationTargets): InterpreterStatisticsInfo
|
||||
@@ -316,3 +333,10 @@ internal suspend fun BinaryToExec.getToolVersion(toolVersionPrefix: String): PyR
|
||||
PyResult.localizedError(message("selected.tool.is.wrong", toolVersionPrefix.trim(), versionPresentation))
|
||||
}
|
||||
}
|
||||
|
||||
internal fun savePathForEelOnly(pathHolder: PathHolder, pathPersister: (Path) -> Unit) {
|
||||
when (pathHolder) {
|
||||
is PathHolder.Eel -> pathPersister(pathHolder.path)
|
||||
is PathHolder.Target -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.jetbrains.python.sdk.add.v2.conda
|
||||
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.observable.properties.AtomicBooleanProperty
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.observable.util.transform
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.ui.ComboBox
|
||||
@@ -18,6 +19,7 @@ import com.intellij.ui.dsl.builder.bindItem
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.jetbrains.python.PyBundle.message
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.conda.saveLocalPythonCondaPath
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.newProject.collector.InterpreterStatisticsInfo
|
||||
import com.jetbrains.python.sdk.ModuleOrProject
|
||||
@@ -42,7 +44,10 @@ internal class CondaExistingEnvironmentSelector<P : PathHolder>(model: PythonAdd
|
||||
private lateinit var condaExecutable: ValidatedPathField<Version, P, ValidatedPath.Executable<P>>
|
||||
private lateinit var reloadLink: ActionLink
|
||||
private val isReloadLinkVisible = AtomicBooleanProperty(false)
|
||||
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?> = model.condaViewModel.condaExecutable
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { pathHolder ->
|
||||
savePathForEelOnly(pathHolder) { path -> saveLocalPythonCondaPath(path) }
|
||||
}
|
||||
|
||||
override fun setupUI(panel: Panel, validationRequestor: DialogValidationRequestor) {
|
||||
with(panel) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.jetbrains.python.sdk.add.v2.conda
|
||||
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.ui.ComboBox
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
@@ -10,6 +11,7 @@ import com.intellij.ui.dsl.builder.bindItem
|
||||
import com.intellij.ui.dsl.builder.bindText
|
||||
import com.intellij.ui.dsl.listCellRenderer.textListCellRenderer
|
||||
import com.jetbrains.python.PyBundle.message
|
||||
import com.jetbrains.python.conda.saveLocalPythonCondaPath
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.newProject.collector.InterpreterStatisticsInfo
|
||||
import com.jetbrains.python.psi.LanguageLevel
|
||||
@@ -22,11 +24,15 @@ import com.jetbrains.python.statistics.InterpreterType
|
||||
import com.jetbrains.python.ui.flow.bindText
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
internal class CondaNewEnvironmentCreator<P: PathHolder>(model: PythonMutableTargetAddInterpreterModel<P>) : PythonNewEnvironmentCreator<P>(model) {
|
||||
internal class CondaNewEnvironmentCreator<P : PathHolder>(model: PythonMutableTargetAddInterpreterModel<P>) : PythonNewEnvironmentCreator<P>(model) {
|
||||
|
||||
private lateinit var pythonVersion: ObservableMutableProperty<LanguageLevel>
|
||||
private lateinit var versionComboBox: ComboBox<LanguageLevel>
|
||||
private lateinit var condaExecutable: ValidatedPathField<Version, P, ValidatedPath.Executable<P>>
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?> = model.condaViewModel.condaExecutable
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { pathHolder ->
|
||||
savePathForEelOnly(pathHolder) { path -> saveLocalPythonCondaPath(path) }
|
||||
}
|
||||
|
||||
override fun setupUI(panel: Panel, validationRequestor: DialogValidationRequestor) {
|
||||
with(panel) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 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.python.sdk.add.v2.hatch
|
||||
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
import com.intellij.python.hatch.HatchConfiguration
|
||||
@@ -12,11 +13,11 @@ import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.hatch.sdk.createSdk
|
||||
import com.jetbrains.python.newProject.collector.InterpreterStatisticsInfo
|
||||
import com.jetbrains.python.onSuccess
|
||||
import com.jetbrains.python.sdk.impl.resolvePythonBinary
|
||||
import com.jetbrains.python.sdk.ModuleOrProject
|
||||
import com.jetbrains.python.sdk.legacy.PythonSdkUtil
|
||||
import com.jetbrains.python.sdk.add.v2.*
|
||||
import com.jetbrains.python.sdk.destructured
|
||||
import com.jetbrains.python.sdk.impl.resolvePythonBinary
|
||||
import com.jetbrains.python.sdk.legacy.PythonSdkUtil
|
||||
import com.jetbrains.python.sdk.setAssociationToModule
|
||||
import com.jetbrains.python.statistics.InterpreterCreationMode
|
||||
import com.jetbrains.python.statistics.InterpreterType
|
||||
@@ -24,12 +25,16 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
internal class HatchExistingEnvironmentSelector<P: PathHolder>(
|
||||
internal class HatchExistingEnvironmentSelector<P : PathHolder>(
|
||||
override val model: PythonMutableTargetAddInterpreterModel<P>,
|
||||
) : PythonExistingEnvironmentConfigurator<P>(model) {
|
||||
val interpreterType: InterpreterType = InterpreterType.HATCH
|
||||
|
||||
private lateinit var hatchFormFields: HatchFormFields<P>
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?> = model.hatchViewModel.hatchExecutable
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { pathHolder ->
|
||||
savePathForEelOnly(pathHolder) { path -> HatchConfiguration.persistPathForTarget(hatchExecutablePath = path) }
|
||||
}
|
||||
|
||||
override fun setupUI(panel: Panel, validationRequestor: DialogValidationRequestor) {
|
||||
hatchFormFields = panel.buildHatchFormFields(
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.jetbrains.python.sdk.add.v2.hatch
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
@@ -28,6 +29,10 @@ internal class HatchNewEnvironmentCreator<P : PathHolder>(
|
||||
override val interpreterType: InterpreterType = InterpreterType.HATCH
|
||||
override val toolValidator: ToolValidator<P> = model.hatchViewModel.toolValidator
|
||||
private lateinit var hatchFormFields: HatchFormFields<P>
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?> = model.hatchViewModel.hatchExecutable
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { pathHolder ->
|
||||
savePathForEelOnly(pathHolder) { path -> HatchConfiguration.persistPathForTarget(hatchExecutablePath = path) }
|
||||
}
|
||||
|
||||
override fun setupUI(panel: Panel, validationRequestor: DialogValidationRequestor) {
|
||||
hatchFormFields = panel.buildHatchFormFields(
|
||||
@@ -45,14 +50,8 @@ internal class HatchNewEnvironmentCreator<P : PathHolder>(
|
||||
hatchFormFields.onShown(scope, model, isFilterOnlyExisting = false)
|
||||
}
|
||||
|
||||
override suspend fun savePathToExecutableToProperties(pathHolder: PathHolder?) {
|
||||
val savingPath = pathHolder ?: toolValidator.backProperty.get()?.pathHolder ?: return
|
||||
val eelPath = (savingPath as? PathHolder.Eel)?.path ?: return
|
||||
HatchConfiguration.persistPathForTarget(hatchExecutablePath = eelPath)
|
||||
}
|
||||
|
||||
override suspend fun createPythonModuleStructure(module: Module): PyResult<Unit> {
|
||||
val hatchExecutablePath = (toolValidator.backProperty.get()?.pathHolder as? PathHolder.Eel)?.path
|
||||
val hatchExecutablePath = (model.hatchViewModel.hatchExecutable.get()?.pathHolder as? PathHolder.Eel)?.path
|
||||
?: return Result.failure(HatchUIError.HatchExecutablePathIsNotValid(null))
|
||||
|
||||
val hatchService = module.getHatchService(hatchExecutablePath).getOr { return it }
|
||||
@@ -78,7 +77,7 @@ internal class HatchNewEnvironmentCreator<P : PathHolder>(
|
||||
is PathHolder.Eel -> basePythonBinaryPath.path
|
||||
else -> return PyResult.localizedError(PyBundle.message("target.is.not.supported", basePythonBinaryPath))
|
||||
}
|
||||
val hatchExecutablePath = when (val hatchBinary = toolValidator.backProperty.get()?.pathHolder) {
|
||||
val hatchExecutablePath = when (val hatchBinary = model.hatchViewModel.hatchExecutable.get()?.pathHolder) {
|
||||
is PathHolder.Eel -> hatchBinary.path
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ internal data class HatchFormFields<P : PathHolder>(
|
||||
|
||||
with(validatedPathField) {
|
||||
initialize(scope)
|
||||
pathValidator.backProperty.afterChange { executable ->
|
||||
model.hatchViewModel.hatchExecutable.afterChange { executable ->
|
||||
if (executable != model.hatchViewModel.hatchExecutable.get()) {
|
||||
model.hatchViewModel.hatchExecutable.set(executable)
|
||||
}
|
||||
|
||||
@@ -2,17 +2,13 @@
|
||||
package com.jetbrains.python.sdk.add.v2.pipenv
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.platform.eel.LocalEelApi
|
||||
import com.intellij.python.community.impl.pipenv.pipenvPath
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.errorProcessing.ErrorSink
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.sdk.add.v2.CustomNewEnvironmentCreator
|
||||
import com.jetbrains.python.sdk.add.v2.FileSystem
|
||||
import com.jetbrains.python.sdk.add.v2.PathHolder
|
||||
import com.jetbrains.python.sdk.add.v2.PythonMutableTargetAddInterpreterModel
|
||||
import com.jetbrains.python.sdk.add.v2.ToolValidator
|
||||
import com.jetbrains.python.sdk.add.v2.*
|
||||
import com.jetbrains.python.sdk.pipenv.setupPipEnvSdkWithProgressReport
|
||||
import com.jetbrains.python.statistics.InterpreterType
|
||||
import java.nio.file.Path
|
||||
@@ -20,15 +16,9 @@ import java.nio.file.Path
|
||||
internal class EnvironmentCreatorPip<P : PathHolder>(model: PythonMutableTargetAddInterpreterModel<P>, errorSink: ErrorSink) : CustomNewEnvironmentCreator<P>("pipenv", model, errorSink) {
|
||||
override val interpreterType: InterpreterType = InterpreterType.PIPENV
|
||||
override val toolValidator: ToolValidator<P> = model.pipenvViewModel.toolValidator
|
||||
|
||||
override suspend fun savePathToExecutableToProperties(pathHolder: PathHolder?) {
|
||||
if ((model.fileSystem as? FileSystem.Eel)?.eelApi !is LocalEelApi) return
|
||||
|
||||
val savingPath = (pathHolder as? PathHolder.Eel)?.path
|
||||
?: (toolValidator.backProperty.get()?.pathHolder as? PathHolder.Eel)?.path
|
||||
savingPath?.let {
|
||||
PropertiesComponent.getInstance().pipenvPath = it.toString()
|
||||
}
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?> = model.pipenvViewModel.pipenvExecutable
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { pathHolder ->
|
||||
savePathForEelOnly(pathHolder) { path -> PropertiesComponent.getInstance().pipenvPath = path.toString() }
|
||||
}
|
||||
|
||||
override suspend fun setupEnvSdk(moduleBasePath: Path, baseSdks: List<Sdk>, basePythonBinaryPath: P?, installPackages: Boolean): PyResult<Sdk> {
|
||||
|
||||
@@ -5,10 +5,10 @@ import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.platform.eel.LocalEelApi
|
||||
import com.intellij.python.community.impl.poetry.common.poetryPath
|
||||
import com.intellij.python.pyproject.PyProjectToml
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
@@ -39,7 +39,7 @@ import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import kotlin.io.path.exists
|
||||
|
||||
internal class EnvironmentCreatorPoetry<P: PathHolder>(
|
||||
internal class EnvironmentCreatorPoetry<P : PathHolder>(
|
||||
model: PythonMutableTargetAddInterpreterModel<P>,
|
||||
private val module: Module?,
|
||||
errorSink: ErrorSink,
|
||||
@@ -47,6 +47,10 @@ internal class EnvironmentCreatorPoetry<P: PathHolder>(
|
||||
override val interpreterType: InterpreterType = InterpreterType.POETRY
|
||||
override val toolValidator: ToolValidator<P> = model.poetryViewModel.toolValidator
|
||||
override val installationVersion: String = "1.8.0"
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?> = model.poetryViewModel.poetryExecutable
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { pathHolder ->
|
||||
savePathForEelOnly(pathHolder) { path -> PropertiesComponent.getInstance().poetryPath = path.toString() }
|
||||
}
|
||||
|
||||
private val isInProjectEnvFlow = MutableStateFlow(service<PoetryConfigService>().state.isInProjectEnv)
|
||||
private val isInProjectEnvProp = propertyGraph.property(isInProjectEnvFlow.value)
|
||||
@@ -99,21 +103,10 @@ internal class EnvironmentCreatorPoetry<P: PathHolder>(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun savePathToExecutableToProperties(pathHolder: PathHolder?) {
|
||||
if ((model.fileSystem as? FileSystem.Eel)?.eelApi !is LocalEelApi) return
|
||||
|
||||
val savingPath = (pathHolder as? PathHolder.Eel)?.path
|
||||
?: (toolValidator.backProperty.get()?.pathHolder as? PathHolder.Eel)?.path
|
||||
|
||||
savingPath?.let {
|
||||
PropertiesComponent.getInstance().poetryPath = it.toString()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setupEnvSdk(moduleBasePath: Path, baseSdks: List<Sdk>, basePythonBinaryPath: P?, installPackages: Boolean): PyResult<Sdk> {
|
||||
module?.let { service<PoetryConfigService>().setInProjectEnv(it) }
|
||||
return when (basePythonBinaryPath) {
|
||||
is PathHolder.Eel -> createNewPoetrySdk(moduleBasePath, baseSdks, basePythonBinaryPath.path, installPackages)
|
||||
is PathHolder.Eel -> createNewPoetrySdk(moduleBasePath, baseSdks, basePythonBinaryPath.path, installPackages)
|
||||
else -> return PyResult.localizedError(PyBundle.message("target.is.not.supported", basePythonBinaryPath))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
// 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.python.sdk.add.v2.poetry
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.python.community.impl.poetry.common.poetryPath
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.PythonInfo
|
||||
import com.jetbrains.python.Result
|
||||
@@ -22,8 +25,12 @@ import java.nio.file.Path
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
internal class PoetryExistingEnvironmentSelector<P : PathHolder>(model: PythonMutableTargetAddInterpreterModel<P>, module: Module?) : CustomExistingEnvironmentSelector<P>("poetry", model, module) {
|
||||
override val toolState: PathValidator<Version, P, ValidatedPath.Executable<P>> = model.poetryViewModel.toolValidator
|
||||
override val interpreterType: InterpreterType = InterpreterType.POETRY
|
||||
override val toolState: ToolValidator<P> = model.poetryViewModel.toolValidator
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?> = model.poetryViewModel.poetryExecutable
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { pathHolder ->
|
||||
savePathForEelOnly(pathHolder) { path -> PropertiesComponent.getInstance().poetryPath = path.toString() }
|
||||
}
|
||||
|
||||
override suspend fun getOrCreateSdk(moduleOrProject: ModuleOrProject): PyResult<Sdk> {
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@ package com.jetbrains.python.sdk.add.v2.uv
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.AtomicBooleanProperty
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.observable.util.not
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.ui.ComboBox
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
import com.intellij.platform.eel.LocalEelApi
|
||||
import com.intellij.python.pyproject.PY_PROJECT_TOML
|
||||
import com.intellij.python.pyproject.PyProjectToml
|
||||
import com.intellij.ui.dsl.builder.AlignX
|
||||
@@ -66,11 +66,15 @@ internal class EnvironmentCreatorUv<P : PathHolder>(
|
||||
private val executableFlow = MutableStateFlow(model.uvViewModel.uvExecutable.get())
|
||||
private val pythonVersion: ObservableMutableProperty<Version?> = propertyGraph.property(null)
|
||||
private lateinit var versionComboBox: ComboBox<Version?>
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?> = model.uvViewModel.uvExecutable
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { pathHolder ->
|
||||
savePathForEelOnly(pathHolder) { path -> setUvExecutable(path) }
|
||||
}
|
||||
|
||||
private val loading = AtomicBooleanProperty(false)
|
||||
|
||||
init {
|
||||
toolValidator.backProperty.afterChange {
|
||||
model.uvViewModel.uvExecutable.afterChange {
|
||||
executableFlow.value = it
|
||||
}
|
||||
}
|
||||
@@ -176,16 +180,6 @@ internal class EnvironmentCreatorUv<P : PathHolder>(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun savePathToExecutableToProperties(pathHolder: PathHolder?) {
|
||||
if ((model.fileSystem as? FileSystem.Eel)?.eelApi !is LocalEelApi) return
|
||||
|
||||
val savingPath = (pathHolder as? PathHolder.Eel)?.path
|
||||
?: (toolValidator.backProperty.get()?.pathHolder as? PathHolder.Eel)?.path
|
||||
savingPath?.let {
|
||||
setUvExecutable(it)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setupEnvSdk(
|
||||
moduleBasePath: Path,
|
||||
baseSdks: List<Sdk>,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.jetbrains.python.sdk.add.v2.uv
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.python.community.execService.python.validatePythonAndGetInfo
|
||||
import com.jetbrains.python.PyBundle
|
||||
@@ -15,6 +16,7 @@ import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.impl.resolvePythonBinary
|
||||
import com.jetbrains.python.sdk.isAssociatedWithModule
|
||||
import com.jetbrains.python.sdk.legacy.PythonSdkUtil
|
||||
import com.jetbrains.python.sdk.uv.impl.setUvExecutable
|
||||
import com.jetbrains.python.sdk.uv.isUv
|
||||
import com.jetbrains.python.sdk.uv.setupExistingEnvAndSdk
|
||||
import com.jetbrains.python.statistics.InterpreterType
|
||||
@@ -29,8 +31,12 @@ import kotlin.io.path.pathString
|
||||
|
||||
internal class UvExistingEnvironmentSelector<P : PathHolder>(model: PythonMutableTargetAddInterpreterModel<P>, module: Module?)
|
||||
: CustomExistingEnvironmentSelector<P>("uv", model, module) {
|
||||
override val toolState: PathValidator<Version, P, ValidatedPath.Executable<P>> = model.uvViewModel.toolValidator
|
||||
override val interpreterType: InterpreterType = InterpreterType.UV
|
||||
override val toolState: ToolValidator<P> = model.uvViewModel.toolValidator
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?> = model.uvViewModel.uvExecutable
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { pathHolder ->
|
||||
savePathForEelOnly(pathHolder) { path -> setUvExecutable(path) }
|
||||
}
|
||||
|
||||
override suspend fun getOrCreateSdk(moduleOrProject: ModuleOrProject): PyResult<Sdk> {
|
||||
val sdkHomePath = selectedEnv.get()?.homePath
|
||||
|
||||
@@ -3,11 +3,14 @@ package com.jetbrains.python.sdk.add.v2.venv
|
||||
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.observable.util.isNotNull
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
import com.intellij.ui.components.ActionLink
|
||||
import com.intellij.ui.dsl.builder.*
|
||||
import com.intellij.ui.dsl.builder.Align
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
import com.intellij.ui.dsl.builder.bindSelected
|
||||
import com.intellij.ui.dsl.builder.components.validationTooltip
|
||||
import com.jetbrains.python.PyBundle.message
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
@@ -26,6 +29,8 @@ import kotlinx.coroutines.plus
|
||||
class EnvironmentCreatorVenv<P : PathHolder>(model: PythonMutableTargetAddInterpreterModel<P>) : PythonNewEnvironmentCreator<P>(model) {
|
||||
private lateinit var versionComboBox: PythonInterpreterComboBox<P>
|
||||
private lateinit var venvPathField: ValidatedPathField<Unit, P, ValidatedPath.Folder<P>>
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?>? = null
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { }
|
||||
|
||||
private val venvAlreadyExistsError = propertyGraph.property<VenvAlreadyExistsError<P>?>(null)
|
||||
private val venvAlreadyExistsErrorMessage: ObservableMutableProperty<String> = propertyGraph.property("")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.jetbrains.python.sdk.add.v2.venv
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableProperty
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
@@ -9,24 +10,16 @@ import com.jetbrains.python.PyBundle.message
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.newProject.collector.InterpreterStatisticsInfo
|
||||
import com.jetbrains.python.sdk.ModuleOrProject
|
||||
import com.jetbrains.python.sdk.add.v2.PathHolder
|
||||
import com.jetbrains.python.sdk.add.v2.PythonAddInterpreterModel
|
||||
import com.jetbrains.python.sdk.add.v2.PythonExistingEnvironmentConfigurator
|
||||
import com.jetbrains.python.sdk.add.v2.PythonInterpreterComboBox
|
||||
import com.jetbrains.python.sdk.add.v2.PythonInterpreterCreationTargets
|
||||
import com.jetbrains.python.sdk.add.v2.existingSdks
|
||||
import com.jetbrains.python.sdk.add.v2.pythonInterpreterComboBox
|
||||
import com.jetbrains.python.sdk.add.v2.setupSdk
|
||||
import com.jetbrains.python.sdk.add.v2.sortForExistingEnvironment
|
||||
import com.jetbrains.python.sdk.add.v2.toStatisticsField
|
||||
import com.jetbrains.python.sdk.add.v2.*
|
||||
import com.jetbrains.python.statistics.InterpreterCreationMode
|
||||
import com.jetbrains.python.statistics.InterpreterType
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class PythonExistingEnvironmentSelector<P: PathHolder>(model: PythonAddInterpreterModel<P>, private val module: Module?) : PythonExistingEnvironmentConfigurator<P>(model) {
|
||||
|
||||
class PythonExistingEnvironmentSelector<P : PathHolder>(model: PythonAddInterpreterModel<P>, private val module: Module?) : PythonExistingEnvironmentConfigurator<P>(model) {
|
||||
private lateinit var comboBox: PythonInterpreterComboBox<P>
|
||||
override val toolExecutable: ObservableProperty<ValidatedPath.Executable<P>?>? = null
|
||||
override val toolExecutablePersister: suspend (P) -> Unit = { }
|
||||
|
||||
override fun setupUI(panel: Panel, validationRequestor: DialogValidationRequestor) {
|
||||
with(panel) {
|
||||
|
||||
Reference in New Issue
Block a user