[python] (PY-78749) single dialog for all types of Python SDKs

+ old dialogs were removed

GitOrigin-RevId: 00ed85ba578c6419373d8605ed50954e7aa58f0a
This commit is contained in:
Vitaly Legchilkin
2025-10-13 22:54:32 +00:00
committed by intellij-monorepo-bot
parent ab8455f916
commit 5e2028d129
99 changed files with 2693 additions and 3331 deletions
+3
View File
@@ -65,6 +65,7 @@ jvm_library(
"//platform/non-modal-welcome-screen",
"//python/common",
"//platform/non-modal-welcome-screen/backend",
"//python/python-exec-service:community-execService",
],
runtime_deps = ["//python/python-features-trainer:featuresTrainer"],
plugins = ["@lib//:compose-plugin"]
@@ -135,6 +136,8 @@ jvm_library(
"//platform/non-modal-welcome-screen",
"//python/common",
"//platform/non-modal-welcome-screen/backend",
"//python/python-exec-service:community-execService",
"//python/python-exec-service:community-execService_test_lib",
],
plugins = ["@lib//:compose-plugin"]
)
@@ -79,5 +79,6 @@
<orderEntry type="module" module-name="intellij.platform.ide.nonModalWelcomeScreen" />
<orderEntry type="module" module-name="intellij.python.common" />
<orderEntry type="module" module-name="intellij.platform.ide.nonModalWelcomeScreen.backend" />
<orderEntry type="module" module-name="intellij.python.community.execService" />
</component>
</module>
@@ -8,6 +8,7 @@ import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
import com.intellij.openapi.ui.ValidationInfo
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.pycharm.community.ide.impl.PyCharmCommunityCustomizationBundle
import com.intellij.pycharm.community.ide.impl.configuration.PySdkConfigurationCollector
@@ -15,12 +16,17 @@ import com.intellij.pycharm.community.ide.impl.configuration.PySdkConfigurationC
import com.intellij.pycharm.community.ide.impl.configuration.PySdkConfigurationCollector.InputData
import com.intellij.pycharm.community.ide.impl.configuration.PySdkConfigurationCollector.Source
import com.intellij.pycharm.community.ide.impl.configuration.ui.PyAddNewCondaEnvFromFilePanel
import com.intellij.python.community.execService.BinOnEel
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
import com.jetbrains.python.PyBundle
import com.jetbrains.python.configuration.PyConfigurableInterpreterList
import com.jetbrains.python.errorProcessing.PyResult
import com.jetbrains.python.getOrNull
import com.jetbrains.python.onSuccess
import com.jetbrains.python.packaging.conda.environmentYml.CondaEnvironmentYmlSdkUtils
import com.jetbrains.python.pathValidation.PlatformAndRoot
import com.jetbrains.python.pathValidation.ValidationRequest
import com.jetbrains.python.pathValidation.validateExecutableFile
import com.jetbrains.python.run.PythonInterpreterTargetEnvironmentFactory
import com.jetbrains.python.sdk.PythonSdkUpdater
import com.jetbrains.python.sdk.basePath
@@ -29,7 +35,6 @@ import com.jetbrains.python.sdk.conda.createCondaSdkAlongWithNewEnv
import com.jetbrains.python.sdk.conda.suggestCondaPath
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfigurationExtension
import com.jetbrains.python.sdk.findAmongRoots
import com.jetbrains.python.sdk.flavors.conda.CondaEnvSdkFlavor
import com.jetbrains.python.sdk.flavors.conda.NewCondaEnvRequest
import com.jetbrains.python.sdk.flavors.conda.PyCondaCommand
import com.jetbrains.python.sdk.flavors.conda.PyCondaEnv
@@ -38,6 +43,7 @@ import com.jetbrains.python.util.ShowingMessageErrorSync
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.SystemDependent
import java.nio.file.Path
@@ -83,7 +89,7 @@ class PyEnvironmentYmlSdkConfiguration : PyProjectSdkConfigurationExtension {
// Again: only local conda is supported for now
val condaExecutable = suggestCondaPath()?.let { LocalFileSystem.getInstance().findFileByPath(it) }
if (source == Source.INSPECTION && CondaEnvSdkFlavor.validateCondaPath(condaExecutable?.path, PlatformAndRoot.local) == null) {
if (source == Source.INSPECTION && validateCondaPath(condaExecutable?.path, PlatformAndRoot.local) == null) {
PySdkConfigurationCollector.logCondaEnvDialogSkipped(module.project, source, executableToEventField(condaExecutable?.path))
return@withContext PyAddNewCondaEnvFromFilePanel.Data(condaExecutable!!.path, environmentYml.path)
}
@@ -130,7 +136,8 @@ class PyEnvironmentYmlSdkConfiguration : PyProjectSdkConfigurationExtension {
}
private suspend fun createCondaEnv(project: Project, condaExecutable: String, environmentYml: String): Sdk? {
val existingEnvs = PyCondaEnv.getEnvs(condaExecutable).getOrNull() ?: emptyList()
val binaryToExec = BinOnEel(Path.of(condaExecutable))
val existingEnvs = PyCondaEnv.getEnvs(binaryToExec).getOrNull() ?: emptyList()
val existingSdks = PyConfigurableInterpreterList.getInstance(project).model.sdks
val newCondaEnvInfo = NewCondaEnvRequest.LocalEnvByLocalEnvironmentFile(Path.of(environmentYml),
@@ -147,4 +154,19 @@ class PyEnvironmentYmlSdkConfiguration : PyProjectSdkConfigurationExtension {
PySdkConfigurationCollector.logCondaEnv(project, CondaEnvResult.CREATED)
return sdk
}
}
@RequiresBackgroundThread
@ApiStatus.Internal
fun validateCondaPath(
condaExecutable: @SystemDependent String?,
platformAndRoot: PlatformAndRoot,
): ValidationInfo? {
return validateExecutableFile(
ValidationRequest(
condaExecutable,
PyBundle.message("python.add.sdk.conda.executable.path.is.empty"),
platformAndRoot,
null
))
}
@@ -12,19 +12,22 @@ import com.intellij.openapi.util.NlsSafe
import com.intellij.openapi.util.UserDataHolderBase
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.ui.FormBuilder
import com.jetbrains.python.PyBundle
import com.jetbrains.python.sdk.impl.PySdkBundle
import com.jetbrains.python.PythonFileType
import com.jetbrains.python.pathValidation.PlatformAndRoot
import com.jetbrains.python.sdk.PySdkSettings
import com.jetbrains.python.sdk.add.PyAddSdkPanel
import com.jetbrains.python.sdk.add.PyAddSdkPanel.Companion.validateSdkComboBox
import com.jetbrains.python.sdk.add.PySdkPathChoosingComboBox
import com.jetbrains.python.sdk.add.addBaseInterpretersAsync
import com.intellij.pycharm.community.ide.impl.configuration.ui.PyAddNewEnvCollector.InputData
import com.intellij.pycharm.community.ide.impl.configuration.ui.PyAddNewEnvCollector.RequirementsTxtOrSetupPyData
import com.intellij.util.concurrency.annotations.RequiresEdt
import com.intellij.util.ui.FormBuilder
import com.jetbrains.python.PyBundle
import com.jetbrains.python.PythonFileType
import com.jetbrains.python.pathValidation.PlatformAndRoot
import com.jetbrains.python.pathValidation.ValidationRequest
import com.jetbrains.python.pathValidation.validateEmptyDir
import com.jetbrains.python.sdk.PySdkSettings
import com.jetbrains.python.sdk.add.validateSdkComboBox
import com.jetbrains.python.sdk.add.PySdkPathChoosingComboBox
import com.jetbrains.python.sdk.add.addBaseInterpretersAsync
import com.jetbrains.python.sdk.basePath
import com.jetbrains.python.sdk.impl.PySdkBundle
import com.jetbrains.python.ui.pyModalBlocking
import org.jetbrains.annotations.SystemDependent
import org.jetbrains.annotations.SystemIndependent
import java.awt.BorderLayout
@@ -83,7 +86,7 @@ class PyAddNewVirtualEnvFromFilePanel(
}
fun validateAll(@NlsContexts.Button defaultButtonName: String): List<ValidationInfo> =
listOfNotNull(PyAddSdkPanel.validateEnvironmentDirectoryLocation(pathField, PlatformAndRoot.local),
listOfNotNull(validateEnvironmentDirectoryLocation(pathField, PlatformAndRoot.local),
validateSdkComboBox(baseSdkField, defaultButtonName))
/**
@@ -166,3 +169,19 @@ class PyAddNewVirtualEnvFromFilePanel(
val requirementsTxtOrSetupPyPath: @NlsSafe @SystemDependent String,
)
}
@RequiresEdt
fun validateEnvironmentDirectoryLocation(field: TextFieldWithBrowseButton, platformAndRoot: PlatformAndRoot): ValidationInfo? {
val path = field.text
return pyModalBlocking {
validateEmptyDir(
ValidationRequest(
path = path,
fieldIsEmpty = PySdkBundle.message("python.venv.location.field.empty"),
platformAndRoot = platformAndRoot
),
notADirectory = PySdkBundle.message("python.venv.location.field.not.directory"),
directoryNotEmpty = PySdkBundle.message("python.venv.location.directory.not.empty")
)
}
}