mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[python][poetry] don't create pyproject.toml if it already exists (PY-76274)
+ project.basePath -> module.basePath migrations GitOrigin-RevId: 8461d6d273f7482aca180abe63d958e551c3c7dd
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a3983498f8
commit
56fbdf6fee
+1
-1
@@ -43,7 +43,7 @@ internal class PyHatchSdkConfiguration : PyProjectSdkConfigurationExtension {
|
||||
val createdEnvironment = hatchService.createVirtualEnvironment().getOr { return@runWithModalBlockingOrInBackground it }
|
||||
|
||||
val hatchVenv = HatchVirtualEnvironment(HatchEnvironment.DEFAULT, createdEnvironment)
|
||||
val sdk = hatchVenv.createSdk(hatchService.getWorkingDirectoryPath(), module)
|
||||
val sdk = hatchVenv.createSdk(hatchService.getWorkingDirectoryPath())
|
||||
sdk
|
||||
}
|
||||
override suspend fun createAndAddSdkForConfigurator(module: Module): PyResult<Sdk> = createSdk(module)
|
||||
|
||||
+7
-7
@@ -16,13 +16,16 @@ import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.poetry.findPoetryLock
|
||||
import com.jetbrains.python.poetry.getPyProjectTomlForPoetry
|
||||
import com.jetbrains.python.resolvePythonBinary
|
||||
import com.jetbrains.python.sdk.PythonSdkType
|
||||
import com.jetbrains.python.sdk.PythonSdkUtil
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfigurationExtension
|
||||
import com.jetbrains.python.sdk.poetry.*
|
||||
import com.jetbrains.python.sdk.poetry.PyPoetrySdkAdditionalData
|
||||
import com.jetbrains.python.sdk.poetry.getPoetryExecutable
|
||||
import com.jetbrains.python.sdk.poetry.setupPoetry
|
||||
import com.jetbrains.python.sdk.poetry.suggestedSdkName
|
||||
import com.jetbrains.python.sdk.setAssociationToModule
|
||||
import com.jetbrains.python.venvReader.VirtualEnvReader
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.nio.file.Path
|
||||
@@ -64,11 +67,8 @@ internal class PyPoetrySdkConfiguration : PyProjectSdkConfigurationExtension {
|
||||
}
|
||||
val tomlFile = PyProjectToml.findFile(module)
|
||||
val poetry = setupPoetry(basePath, null, true, tomlFile == null).getOr { return@withBackgroundProgress it }
|
||||
|
||||
val path = withContext(Dispatchers.IO) { VirtualEnvReader.Instance.findPythonInPythonRoot(Path.of(poetry)) }
|
||||
if (path == null) {
|
||||
return@withBackgroundProgress PyResult.localizedError(PyBundle.message("cannot.find.executable", "python", poetry))
|
||||
}
|
||||
val path = poetry.resolvePythonBinary()
|
||||
?: return@withBackgroundProgress PyResult.localizedError(PyBundle.message("cannot.find.executable", "python", poetry))
|
||||
|
||||
val file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path.pathString)
|
||||
if (file == null) {
|
||||
|
||||
@@ -437,7 +437,7 @@ python.sdk.rendering.project.default.0=Project Default ({0})
|
||||
python.sdk.installation.notification.group=Python interpreter installation
|
||||
python.sdk.installation.balloon.error.message=<b>Python installation interrupted</b><br/>Download Python manually from python.org, install it and configure the project interpreter.
|
||||
python.sdk.installation.balloon.error.action=See the documentation
|
||||
python.sdk.directory.not.found=Directory {0} not found
|
||||
python.sdk.python.executable.not.found=Python executable {0} is missing
|
||||
python.sdk.failed.to.create.interpreter.title=Failed to create interpreter
|
||||
python.sdk.can.t.obtain.python.version=Can't obtain python version
|
||||
python.sdk.empty.version.string=Python interpreter returned the empty output as a version string
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.apache.tuweni.toml.TomlParseError
|
||||
import org.apache.tuweni.toml.TomlTable
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.isRegularFile
|
||||
|
||||
/**
|
||||
* Stores the file name of `pyproject.toml`.
|
||||
@@ -240,6 +242,9 @@ data class PyProjectToml(
|
||||
findAmongRoots(module, PY_PROJECT_TOML)
|
||||
}
|
||||
|
||||
suspend fun findInRoot(moduleBasePath: Path): Path? = withContext(Dispatchers.IO) {
|
||||
moduleBasePath.resolve(PY_PROJECT_TOML).takeIf { it.isRegularFile() }
|
||||
}
|
||||
|
||||
private fun TomlTable.parseContacts(
|
||||
key: String,
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
package com.jetbrains.python.hatch.sdk
|
||||
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.python.hatch.*
|
||||
import com.intellij.python.hatch.BasePythonExecutableNotFoundHatchError
|
||||
import com.intellij.python.hatch.HatchVirtualEnvironment
|
||||
import com.intellij.python.hatch.PythonVirtualEnvironment
|
||||
import com.intellij.python.hatch.getHatchEnvVirtualProjectPath
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.resolvePythonBinary
|
||||
@@ -19,7 +21,7 @@ import java.nio.file.Path
|
||||
import kotlin.io.path.name
|
||||
|
||||
@ApiStatus.Internal
|
||||
suspend fun HatchVirtualEnvironment.createSdk(workingDirectoryPath: Path, module: Module?): PyResult<Sdk> {
|
||||
suspend fun HatchVirtualEnvironment.createSdk(workingDirectoryPath: Path): PyResult<Sdk> {
|
||||
val existingPythonEnvironment = pythonVirtualEnvironment as? PythonVirtualEnvironment.Existing
|
||||
?: return Result.failure(BasePythonExecutableNotFoundHatchError(null as String?))
|
||||
val pythonHomePath = pythonVirtualEnvironment?.pythonHomePath
|
||||
@@ -29,9 +31,9 @@ suspend fun HatchVirtualEnvironment.createSdk(workingDirectoryPath: Path, module
|
||||
|
||||
val hatchSdkAdditionalData = HatchSdkAdditionalData(workingDirectoryPath, this.hatchEnvironment.name)
|
||||
val sdk = createSdk(
|
||||
sdkHomePath = pythonBinary,
|
||||
pythonBinaryPath = pythonBinary,
|
||||
existingSdks = PythonSdkUtil.getAllSdks(),
|
||||
associatedProjectPath = module?.project?.basePath,
|
||||
associatedProjectPath = workingDirectoryPath.toString(),
|
||||
suggestedSdkName = existingPythonEnvironment.suggestHatchSdkName(),
|
||||
sdkAdditionalData = hatchSdkAdditionalData
|
||||
).getOr { return it }
|
||||
|
||||
@@ -5,7 +5,10 @@ import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.execution.target.*
|
||||
import com.intellij.ide.projectView.actions.MarkRootsManager
|
||||
import com.intellij.openapi.application.*
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.application.runInEdt
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleUtil
|
||||
@@ -29,6 +32,7 @@ import com.intellij.platform.ide.progress.runWithModalProgressBlocking
|
||||
import com.intellij.util.PathUtil
|
||||
import com.intellij.webcore.packaging.PackagesNotificationPanel
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.isCondaVirtualEnv
|
||||
import com.jetbrains.python.isVirtualEnv
|
||||
@@ -188,7 +192,7 @@ fun createSdkByGenerateTask(
|
||||
val homeFile = try {
|
||||
val homePath = ProgressManager.getInstance().run(generateSdkHomePath)
|
||||
StandardFileSystems.local().refreshAndFindFileByPath(homePath) ?: throw ExecutionException(
|
||||
PyBundle.message("python.sdk.directory.not.found", homePath)
|
||||
PyBundle.message("python.sdk.python.executable.not.found", homePath)
|
||||
)
|
||||
}
|
||||
catch (e: ExecutionException) {
|
||||
@@ -218,19 +222,20 @@ fun createSdkByGenerateTask(
|
||||
|
||||
@Internal
|
||||
suspend fun createSdk(
|
||||
sdkHomePath: Path,
|
||||
pythonBinaryPath: PythonBinary,
|
||||
existingSdks: List<Sdk>,
|
||||
associatedProjectPath: String?,
|
||||
suggestedSdkName: String?,
|
||||
sdkAdditionalData: PythonSdkAdditionalData? = null,
|
||||
): PyResult<Sdk> {
|
||||
val homeFile = withContext(Dispatchers.IO) { StandardFileSystems.local().refreshAndFindFileByPath(sdkHomePath.pathString) }
|
||||
?: return PyResult.localizedError(PyBundle.message("python.sdk.directory.not.found", sdkHomePath.pathString))
|
||||
val pythonBinaryVirtualFile = withContext(Dispatchers.IO) {
|
||||
StandardFileSystems.local().refreshAndFindFileByPath(pythonBinaryPath.pathString)
|
||||
} ?: return PyResult.localizedError(PyBundle.message("python.sdk.python.executable.not.found", pythonBinaryPath.pathString))
|
||||
|
||||
val sdkName = suggestedSdkName ?: suggestAssociatedSdkName(homeFile.path, associatedProjectPath)
|
||||
val sdkName = suggestedSdkName ?: suggestAssociatedSdkName(pythonBinaryPath.pathString, associatedProjectPath)
|
||||
val sdk = SdkConfigurationUtil.setupSdk(
|
||||
existingSdks.toTypedArray(),
|
||||
homeFile,
|
||||
pythonBinaryVirtualFile,
|
||||
PythonSdkType.getInstance(),
|
||||
false,
|
||||
sdkAdditionalData,
|
||||
|
||||
@@ -1,9 +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
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||
@@ -13,6 +11,7 @@ import com.intellij.ui.components.ActionLink
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import com.jetbrains.python.PyBundle.message
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.errorProcessing.ErrorSink
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
@@ -69,19 +68,20 @@ internal abstract class CustomNewEnvironmentCreator(
|
||||
|
||||
// todo think about better error handling
|
||||
val selectedBasePython = model.state.baseInterpreter.get()!!
|
||||
val homePath = model.installPythonIfNeeded(selectedBasePython)
|
||||
val basePythonBinaryPath = model.installPythonIfNeeded(selectedBasePython)
|
||||
|
||||
val module = when (moduleOrProject) {
|
||||
is ModuleOrProject.ModuleAndProject -> moduleOrProject.module
|
||||
is ModuleOrProject.ProjectOnly -> null
|
||||
}
|
||||
val moduleBasePath = module?.basePath?.let { Path.of(it) }
|
||||
?: model.projectPathFlows.projectPath.first()
|
||||
?: error("module base path can't be recognized, both module and project are nulls")
|
||||
|
||||
val newSdk = setupEnvSdk(
|
||||
project = moduleOrProject.project,
|
||||
module = module,
|
||||
moduleBasePath = moduleBasePath,
|
||||
baseSdks = PythonSdkUtil.getAllSdks(),
|
||||
projectPath = model.projectPathFlows.projectPathWithDefault.first().toString(),
|
||||
homePath = homePath,
|
||||
basePythonBinaryPath = basePythonBinaryPath,
|
||||
installPackages = false
|
||||
).getOr { return it }
|
||||
|
||||
@@ -184,7 +184,7 @@ internal abstract class CustomNewEnvironmentCreator(
|
||||
*/
|
||||
internal abstract fun savePathToExecutableToProperties(path: Path?)
|
||||
|
||||
protected abstract suspend fun setupEnvSdk(project: Project, module: Module?, baseSdks: List<Sdk>, projectPath: String, homePath: String?, installPackages: Boolean): PyResult<Sdk>
|
||||
protected abstract suspend fun setupEnvSdk(moduleBasePath: Path, baseSdks: List<Sdk>, basePythonBinaryPath: PythonBinary?, installPackages: Boolean): PyResult<Sdk>
|
||||
|
||||
internal abstract suspend fun detectExecutable()
|
||||
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
package com.jetbrains.python.sdk.add.v2
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.util.text.nullize
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.errorProcessing.ErrorSink
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.sdk.pipenv.pipEnvPath
|
||||
@@ -24,8 +23,9 @@ internal class EnvironmentCreatorPip(model: PythonMutableTargetAddInterpreterMod
|
||||
PropertiesComponent.getInstance().pipEnvPath = savingPath
|
||||
}
|
||||
|
||||
override suspend fun setupEnvSdk(project: Project, module: Module?, baseSdks: List<Sdk>, projectPath: String, homePath: String?, installPackages: Boolean): PyResult<Sdk> =
|
||||
setupPipEnvSdkWithProgressReport(project, module, baseSdks, projectPath, homePath, installPackages)
|
||||
override suspend fun setupEnvSdk(moduleBasePath: Path, baseSdks: List<Sdk>, basePythonBinaryPath: PythonBinary?, installPackages: Boolean): PyResult<Sdk> {
|
||||
return setupPipEnvSdkWithProgressReport(moduleBasePath, baseSdks, basePythonBinaryPath, installPackages)
|
||||
}
|
||||
|
||||
override suspend fun detectExecutable() {
|
||||
model.detectPipEnvExecutable()
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ internal class HatchExistingEnvironmentSelector(
|
||||
else -> {
|
||||
val (project, module) = moduleOrProject.destructured
|
||||
val workingDirectory = resolveHatchWorkingDirectory(project, module).getOr { return it }
|
||||
environment.createSdk(workingDirectory, module).onSuccess { sdk ->
|
||||
environment.createSdk(workingDirectory).onSuccess { sdk ->
|
||||
module?.let { module -> sdk.setAssociationToModule(module) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.jetbrains.python.sdk.add.v2.hatch
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
@@ -11,9 +10,9 @@ import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.python.hatch.HatchConfiguration
|
||||
import com.intellij.python.hatch.HatchVirtualEnvironment
|
||||
import com.intellij.python.hatch.getHatchService
|
||||
import com.intellij.python.hatch.resolveHatchWorkingDirectory
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
import com.intellij.util.text.nullize
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.errorProcessing.ErrorSink
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
@@ -81,21 +80,20 @@ internal class HatchNewEnvironmentCreator(
|
||||
return Result.success(Unit)
|
||||
}
|
||||
|
||||
override suspend fun setupEnvSdk(project: Project, module: Module?, baseSdks: List<Sdk>, projectPath: String, homePath: String?, installPackages: Boolean): PyResult<Sdk> {
|
||||
override suspend fun setupEnvSdk(moduleBasePath: Path, baseSdks: List<Sdk>, basePythonBinaryPath: PythonBinary?, installPackages: Boolean): PyResult<Sdk> {
|
||||
val hatchEnv = hatchEnvironmentProperty.get()?.hatchEnvironment
|
||||
?: return Result.failure(HatchUIError.HatchEnvironmentIsNotSelected())
|
||||
|
||||
val hatchExecutablePath = executable.get().toPath().getOr { return it }
|
||||
val hatchWorkingDirectory = resolveHatchWorkingDirectory(project, module).getOr { return it }
|
||||
val hatchService = hatchWorkingDirectory.getHatchService(hatchExecutablePath = hatchExecutablePath).getOr { return it }
|
||||
val hatchService = moduleBasePath.getHatchService(hatchExecutablePath = hatchExecutablePath).getOr { return it }
|
||||
|
||||
val virtualEnvironment = hatchService.createVirtualEnvironment(
|
||||
basePythonBinaryPath = homePath?.let { Path.of(it) },
|
||||
basePythonBinaryPath = basePythonBinaryPath,
|
||||
envName = hatchEnv.name
|
||||
).getOr { return it }
|
||||
|
||||
val hatchVirtualEnv = HatchVirtualEnvironment(hatchEnv, virtualEnvironment)
|
||||
val createdSdk = hatchVirtualEnv.createSdk(hatchService.getWorkingDirectoryPath(), module).onSuccess {
|
||||
val createdSdk = hatchVirtualEnv.createSdk(hatchService.getWorkingDirectoryPath()).onSuccess {
|
||||
HatchConfiguration.persistPathForTarget(hatchExecutablePath = hatchExecutablePath)
|
||||
}
|
||||
return createdSdk
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
@@ -16,9 +15,12 @@ import com.intellij.ui.dsl.builder.Panel
|
||||
import com.intellij.ui.dsl.builder.bindSelected
|
||||
import com.intellij.util.text.nullize
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.errorProcessing.ErrorSink
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.newProjectWizard.collector.PythonNewProjectWizardCollector
|
||||
import com.jetbrains.python.poetry.PoetryPyProjectTomlPythonVersionsService
|
||||
import com.jetbrains.python.poetry.findPoetryToml
|
||||
import com.jetbrains.python.sdk.add.v2.CustomNewEnvironmentCreator
|
||||
import com.jetbrains.python.sdk.add.v2.PythonInterpreterSelectionMethod.SELECT_EXISTING
|
||||
import com.jetbrains.python.sdk.add.v2.PythonMutableTargetAddInterpreterModel
|
||||
@@ -29,10 +31,8 @@ import com.jetbrains.python.sdk.add.v2.VenvExistenceValidationState.Error
|
||||
import com.jetbrains.python.sdk.add.v2.VenvExistenceValidationState.Invisible
|
||||
import com.jetbrains.python.sdk.add.v2.getBasePath
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.poetry.PoetryPyProjectTomlPythonVersionsService
|
||||
import com.jetbrains.python.sdk.poetry.configurePoetryEnvironment
|
||||
import com.jetbrains.python.poetry.findPoetryToml
|
||||
import com.jetbrains.python.sdk.poetry.setupPoetrySdk
|
||||
import com.jetbrains.python.sdk.poetry.createNewPoetrySdk
|
||||
import com.jetbrains.python.statistics.InterpreterType
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -113,9 +113,9 @@ internal class EnvironmentCreatorPoetry(
|
||||
PropertiesComponent.getInstance().poetryPath = savingPath
|
||||
}
|
||||
|
||||
override suspend fun setupEnvSdk(project: Project, module: Module?, baseSdks: List<Sdk>, projectPath: String, homePath: String?, installPackages: Boolean): PyResult<Sdk> {
|
||||
override suspend fun setupEnvSdk(moduleBasePath: Path, baseSdks: List<Sdk>, basePythonBinaryPath: PythonBinary?, installPackages: Boolean): PyResult<Sdk> {
|
||||
module?.let { service<PoetryConfigService>().setInProjectEnv(it) }
|
||||
return setupPoetrySdk(project, module, baseSdks, projectPath, homePath, installPackages)
|
||||
return createNewPoetrySdk(moduleBasePath, baseSdks, basePythonBinaryPath, installPackages)
|
||||
}
|
||||
|
||||
override suspend fun detectExecutable() {
|
||||
|
||||
+14
-4
@@ -5,6 +5,7 @@ import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.observable.properties.ObservableMutableProperty
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.sdk.ModuleOrProject
|
||||
@@ -12,9 +13,10 @@ import com.jetbrains.python.sdk.PythonSdkUtil
|
||||
import com.jetbrains.python.sdk.add.v2.CustomExistingEnvironmentSelector
|
||||
import com.jetbrains.python.sdk.add.v2.DetectedSelectableInterpreter
|
||||
import com.jetbrains.python.sdk.add.v2.PythonMutableTargetAddInterpreterModel
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.poetry.createPoetrySdk
|
||||
import com.jetbrains.python.sdk.poetry.detectPoetryEnvs
|
||||
import com.jetbrains.python.sdk.poetry.isPoetry
|
||||
import com.jetbrains.python.sdk.poetry.setupPoetrySdk
|
||||
import com.jetbrains.python.statistics.InterpreterType
|
||||
import com.jetbrains.python.statistics.version
|
||||
import java.nio.file.Path
|
||||
@@ -25,16 +27,24 @@ internal class PoetryExistingEnvironmentSelector(model: PythonMutableTargetAddIn
|
||||
override val interpreterType: InterpreterType = InterpreterType.POETRY
|
||||
|
||||
override suspend fun getOrCreateSdk(moduleOrProject: ModuleOrProject): PyResult<Sdk> {
|
||||
val selectedInterpreter = selectedEnv.get()
|
||||
PythonSdkUtil.getAllSdks().find { sdk -> sdk.isPoetry && sdk.homePath == selectedInterpreter?.homePath }?.let { return Result.success(it) }
|
||||
val pythonBinaryPath = selectedEnv.get()?.let { Path.of(it.homePath) }
|
||||
?: return PyResult.localizedError(PyBundle.message("python.sdk.provided.path.is.invalid", selectedEnv.get()?.homePath))
|
||||
|
||||
PythonSdkUtil.getAllSdks().find { sdk -> sdk.isPoetry && sdk.homePath == pythonBinaryPath.pathString }?.let { return Result.success(it) }
|
||||
|
||||
val module = when (moduleOrProject) {
|
||||
is ModuleOrProject.ModuleAndProject -> {
|
||||
moduleOrProject.module
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
val moduleBasePath = module?.basePath?.let { Path.of(it) } ?: error("module base path is not valid: ${module?.basePath}")
|
||||
|
||||
return setupPoetrySdk(moduleOrProject.project, module, ProjectJdkTable.getInstance().allJdks.toList(), null, selectedInterpreter?.homePath, true)
|
||||
return createPoetrySdk(
|
||||
moduleBasePath,
|
||||
existingSdks = ProjectJdkTable.getInstance().allJdks.toList(),
|
||||
pythonBinaryPath = pythonBinaryPath
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun detectEnvironments(modulePath: Path): List<DetectedSelectableInterpreter> {
|
||||
|
||||
@@ -95,10 +95,11 @@ suspend fun PythonAddInterpreterModel.selectCondaEnvironment(base: Boolean): PyR
|
||||
}
|
||||
|
||||
|
||||
internal fun PythonAddInterpreterModel.installPythonIfNeeded(interpreter: PythonSelectableInterpreter): String? {
|
||||
internal fun PythonAddInterpreterModel.installPythonIfNeeded(interpreter: PythonSelectableInterpreter): Path? {
|
||||
// todo use target config
|
||||
return if (interpreter is InstallableSelectableInterpreter) {
|
||||
installBaseSdk(interpreter.sdk, existingSdks)?.homePath ?: return null
|
||||
val pathString = if (interpreter is InstallableSelectableInterpreter) {
|
||||
installBaseSdk(interpreter.sdk, existingSdks)?.homePath
|
||||
}
|
||||
else interpreter.homePath
|
||||
return pathString?.let { Path.of(it) }
|
||||
}
|
||||
@@ -5,7 +5,6 @@ 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.util.not
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.ui.ComboBox
|
||||
import com.intellij.openapi.ui.validation.DialogValidationRequestor
|
||||
@@ -19,6 +18,7 @@ import com.intellij.ui.dsl.listCellRenderer.textListCellRenderer
|
||||
import com.intellij.util.text.nullize
|
||||
import com.intellij.util.ui.AsyncProcessIcon
|
||||
import com.jetbrains.python.PyBundle.message
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.errorProcessing.ErrorSink
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.getOrNull
|
||||
@@ -30,13 +30,11 @@ import com.jetbrains.python.sdk.add.v2.PythonSupportedEnvironmentManagers.PYTHON
|
||||
import com.jetbrains.python.sdk.add.v2.PythonSupportedEnvironmentManagers.UV
|
||||
import com.jetbrains.python.sdk.add.v2.VenvExistenceValidationState
|
||||
import com.jetbrains.python.sdk.add.v2.executableSelector
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.uv.impl.createUvCli
|
||||
import com.jetbrains.python.sdk.uv.impl.createUvLowLevel
|
||||
import com.jetbrains.python.sdk.uv.impl.setUvExecutable
|
||||
import com.jetbrains.python.sdk.uv.setupNewUvSdkAndEnv
|
||||
import com.jetbrains.python.statistics.InterpreterType
|
||||
import com.jetbrains.python.venvReader.tryResolvePath
|
||||
import io.github.z4kn4fein.semver.Version
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -173,19 +171,12 @@ internal class EnvironmentCreatorUv(
|
||||
}
|
||||
|
||||
override suspend fun setupEnvSdk(
|
||||
project: Project,
|
||||
module: Module?,
|
||||
moduleBasePath: Path,
|
||||
baseSdks: List<Sdk>,
|
||||
projectPath: String,
|
||||
homePath: String?,
|
||||
installPackages: Boolean,
|
||||
basePythonBinaryPath: PythonBinary?,
|
||||
installPackages: Boolean
|
||||
): PyResult<Sdk> {
|
||||
val workingDir = module?.basePath?.let { tryResolvePath(it) } ?: project.basePath?.let { tryResolvePath(it) }
|
||||
if (workingDir == null) {
|
||||
return PyResult.localizedError(message("python.sdk.uv.working.dir.is.not.specified"))
|
||||
}
|
||||
|
||||
return setupNewUvSdkAndEnv(workingDir, baseSdks, pythonVersion.get())
|
||||
return setupNewUvSdkAndEnv(moduleBasePath, baseSdks, pythonVersion.get())
|
||||
}
|
||||
|
||||
override suspend fun detectExecutable() {
|
||||
|
||||
@@ -2,18 +2,16 @@
|
||||
package com.jetbrains.python.sdk.pipenv
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.progress.runBlockingCancellable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.platform.eel.provider.asNioPath
|
||||
import com.intellij.platform.eel.provider.localEel
|
||||
import com.intellij.platform.eel.where
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.getOrNull
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.createSdk
|
||||
import com.jetbrains.python.sdk.runExecutableWithProgress
|
||||
import com.jetbrains.python.venvReader.VirtualEnvReader
|
||||
@@ -22,6 +20,7 @@ import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import org.jetbrains.annotations.SystemDependent
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.pathString
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
|
||||
@Internal
|
||||
@@ -81,24 +80,19 @@ suspend fun getPipEnvExecutable(): PyResult<Path> =
|
||||
*/
|
||||
@Internal
|
||||
suspend fun setupPipEnvSdkWithProgressReport(
|
||||
project: Project?,
|
||||
module: Module?,
|
||||
moduleBasePath: Path,
|
||||
existingSdks: List<Sdk>,
|
||||
newProjectPath: String?,
|
||||
python: String?,
|
||||
basePythonBinaryPath: PythonBinary?,
|
||||
installPackages: Boolean,
|
||||
): PyResult<Sdk> {
|
||||
val projectPath = newProjectPath ?: module?.basePath ?: project?.basePath
|
||||
?: return PyResult.localizedError(PyBundle.message("python.sdk.provided.path.is.invalid", null))
|
||||
val actualProject = project ?: module?.project
|
||||
val pythonExecutablePath = if (actualProject != null) {
|
||||
setUpPipEnv(projectPath, python, installPackages)
|
||||
}
|
||||
else {
|
||||
setUpPipEnv(projectPath, python, installPackages)
|
||||
}.getOr { return it }
|
||||
val pythonExecutablePath = setUpPipEnv(moduleBasePath, basePythonBinaryPath, installPackages).getOr { return it }
|
||||
|
||||
return createSdk(pythonExecutablePath, existingSdks, projectPath, suggestedSdkName(projectPath), PyPipEnvSdkAdditionalData())
|
||||
return createSdk(
|
||||
pythonExecutablePath,
|
||||
existingSdks, moduleBasePath.pathString,
|
||||
suggestedSdkName(moduleBasePath.pathString),
|
||||
PyPipEnvSdkAdditionalData()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,23 +101,23 @@ suspend fun setupPipEnvSdkWithProgressReport(
|
||||
* @return the path to the pipenv environment.
|
||||
*/
|
||||
@Internal
|
||||
suspend fun setupPipEnv(projectPath: Path, python: String?, installPackages: Boolean): PyResult<@SystemDependent String> {
|
||||
suspend fun setupPipEnv(projectPath: Path, basePythonBinaryPath: PythonBinary?, installPackages: Boolean): PyResult<@SystemDependent String> {
|
||||
when {
|
||||
installPackages -> {
|
||||
val pythonArgs = if (python != null) listOf("--python", python) else emptyList()
|
||||
val pythonArgs = if (basePythonBinaryPath != null) listOf("--python", basePythonBinaryPath.pathString) else emptyList()
|
||||
val command = pythonArgs + listOf("install", "--dev")
|
||||
runPipEnv(projectPath, *command.toTypedArray()).getOr { return it }
|
||||
}
|
||||
python != null ->
|
||||
runPipEnv(projectPath, "--python", python).getOr { return it }
|
||||
basePythonBinaryPath != null ->
|
||||
runPipEnv(projectPath, "--python", basePythonBinaryPath.pathString).getOr { return it }
|
||||
else ->
|
||||
runPipEnv(projectPath, "run", "python", "-V").getOr { return it }
|
||||
}
|
||||
return runPipEnv(projectPath, "--venv")
|
||||
}
|
||||
|
||||
private suspend fun setUpPipEnv(projectPathString: String, python: String?, installPackages: Boolean): PyResult<Path> {
|
||||
val pipEnv = setupPipEnv(Path.of(projectPathString), python, installPackages).getOr { return it }
|
||||
private suspend fun setUpPipEnv(moduleBasePath: Path, basePythonBinaryPath: PythonBinary?, installPackages: Boolean): PyResult<Path> {
|
||||
val pipEnv = setupPipEnv(moduleBasePath, basePythonBinaryPath, installPackages).getOr { return it }
|
||||
val pipEnvExecutablePathString = withContext(Dispatchers.IO) {
|
||||
VirtualEnvReader.Instance.findPythonInPythonRoot(Path.of(pipEnv))?.toString()
|
||||
} ?: return PyResult.localizedError(PyBundle.message("python.sdk.provided.path.is.invalid", pipEnv))
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.jetbrains.python.sdk.pipenv.ui
|
||||
|
||||
import com.intellij.application.options.ModuleListCellRenderer
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.diagnostic.getOrLogException
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleUtil
|
||||
@@ -24,10 +23,13 @@ import com.intellij.util.ui.FormBuilder
|
||||
import com.jetbrains.python.*
|
||||
import com.jetbrains.python.newProject.collector.InterpreterStatisticsInfo
|
||||
import com.jetbrains.python.packaging.utils.PyPackageCoroutine
|
||||
import com.jetbrains.python.sdk.*
|
||||
import com.jetbrains.python.sdk.PySdkSettings
|
||||
import com.jetbrains.python.sdk.add.PyAddNewEnvPanel
|
||||
import com.jetbrains.python.sdk.add.PySdkPathChoosingComboBox
|
||||
import com.jetbrains.python.sdk.add.addBaseInterpretersAsync
|
||||
import com.jetbrains.python.sdk.associatedModulePath
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.installSdkIfNeeded
|
||||
import com.jetbrains.python.sdk.pipenv.*
|
||||
import com.jetbrains.python.statistics.InterpreterTarget
|
||||
import com.jetbrains.python.statistics.InterpreterType
|
||||
@@ -36,6 +38,7 @@ import kotlinx.coroutines.withContext
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Dimension
|
||||
import java.awt.event.ItemEvent
|
||||
import java.nio.file.Path
|
||||
import javax.swing.Icon
|
||||
import javax.swing.JComboBox
|
||||
import javax.swing.event.DocumentEvent
|
||||
@@ -128,12 +131,17 @@ class PyAddPipEnvPanel(
|
||||
@RequiresEdt
|
||||
override fun getOrCreateSdk(): Sdk? {
|
||||
PropertiesComponent.getInstance().pipEnvPath = pipEnvPathField.text.nullize()
|
||||
val baseSdk = installSdkIfNeeded(baseSdkField.selectedSdk, selectedModule, existingSdks, context).getOrLogException(LOGGER)?.homePath
|
||||
val baseSdk = installSdkIfNeeded(baseSdkField.selectedSdk, selectedModule, existingSdks, context).getOrThrow()
|
||||
|
||||
val moduleBasePath = module?.basePath?.let { Path.of(it) }
|
||||
?: error("module base path is invalid: ${module?.basePath}")
|
||||
|
||||
val basePythonBinaryPath = baseSdk.homePath?.let { Path.of(it) }
|
||||
?: error("base python binary path is invalid: ${baseSdk.homePath}")
|
||||
|
||||
return runWithModalProgressBlocking(ModalTaskOwner.guess(), PyBundle.message("python.sdk.setting.up.pipenv.title")) {
|
||||
setupPipEnvSdkWithProgressReport(project, selectedModule, existingSdks, newProjectPath,
|
||||
baseSdk, installPackagesCheckBox.isSelected).onSuccess {
|
||||
PySdkSettings.instance.preferredVirtualEnvBaseSdk = baseSdk
|
||||
setupPipEnvSdkWithProgressReport(moduleBasePath, existingSdks, basePythonBinaryPath, installPackagesCheckBox.isSelected).onSuccess {
|
||||
PySdkSettings.instance.preferredVirtualEnvBaseSdk = baseSdk.homePath
|
||||
}
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
@@ -16,11 +16,8 @@ import com.intellij.python.community.execService.execGetStdout
|
||||
import com.intellij.python.community.impl.poetry.poetryPath
|
||||
import com.intellij.python.pyproject.PY_PROJECT_TOML
|
||||
import com.intellij.util.SystemProperties
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.*
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.getOrNull
|
||||
import com.jetbrains.python.isSuccess
|
||||
import com.jetbrains.python.onFailure
|
||||
import com.jetbrains.python.packaging.PyPackage
|
||||
import com.jetbrains.python.packaging.PyRequirement
|
||||
import com.jetbrains.python.packaging.PyRequirementParser
|
||||
@@ -41,7 +38,6 @@ import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.annotations.SystemDependent
|
||||
import org.jetbrains.annotations.SystemIndependent
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.exists
|
||||
@@ -114,32 +110,30 @@ suspend fun runPoetryWithSdk(sdk: Sdk, vararg args: String): PyResult<String> {
|
||||
* @return the path to the poetry environment.
|
||||
*/
|
||||
@Internal
|
||||
suspend fun setupPoetry(projectPath: Path, python: String?, installPackages: Boolean, init: Boolean): PyResult<@SystemDependent String> {
|
||||
suspend fun setupPoetry(projectPath: Path, basePythonBinaryPath: PythonBinary?, installPackages: Boolean, init: Boolean): PyResult<PythonHomePath> {
|
||||
if (init) {
|
||||
runPoetry(projectPath, *listOf("init", "-n").toTypedArray())
|
||||
.getOr { return it }
|
||||
runPoetry(projectPath, *listOf("init", "-n").toTypedArray()).getOr { return it }
|
||||
|
||||
if (python != null) { // Replace a python version in toml
|
||||
ExecService().execGetStdout(BinOnEel(Path.of(python), workDir = projectPath), Args("-c", REPLACE_PYTHON_VERSION))
|
||||
.getOr { return it }
|
||||
if (basePythonBinaryPath != null) { // Replace a python version in toml
|
||||
ExecService().execGetStdout(
|
||||
binary = BinOnEel(path = basePythonBinaryPath, workDir = projectPath),
|
||||
args = Args("-c", REPLACE_PYTHON_VERSION)
|
||||
).getOr { return it }
|
||||
}
|
||||
}
|
||||
|
||||
val env = if (python != null) {
|
||||
runPoetry(projectPath, "env", "use", python)
|
||||
if (basePythonBinaryPath != null) {
|
||||
runPoetry(projectPath, "env", "use", basePythonBinaryPath.pathString).getOr { return it }
|
||||
}
|
||||
else {
|
||||
runPoetry(projectPath, "run", "python", "-V")
|
||||
runPoetry(projectPath, "run", "python", "-V").getOr { return it }
|
||||
}
|
||||
|
||||
env.onFailure { return PyResult.failure(it) }
|
||||
|
||||
if (installPackages) {
|
||||
runPoetry(projectPath, "install")
|
||||
.onFailure { return PyResult.failure(it) }
|
||||
runPoetry(projectPath, "install").getOr { return it }
|
||||
}
|
||||
|
||||
return runPoetry(projectPath, "env", "info", "-p")
|
||||
return runPoetry(projectPath, "env", "info", "-p").mapSuccess { Path.of(it) }
|
||||
}
|
||||
|
||||
internal suspend fun detectPoetryEnvs(module: Module?, existingSdkPaths: Set<String>?, projectPath: @SystemIndependent @NonNls String?): List<PyDetectedSdk> {
|
||||
|
||||
@@ -6,22 +6,18 @@ import com.intellij.openapi.module.ModuleUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.python.pyproject.PY_PROJECT_TOML
|
||||
import com.intellij.python.pyproject.PyProjectToml
|
||||
import com.intellij.util.PathUtil
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.PythonModuleTypeBase
|
||||
import com.jetbrains.python.errorProcessing.PyResult
|
||||
import com.jetbrains.python.icons.PythonIcons
|
||||
import com.jetbrains.python.packaging.common.PythonOutdatedPackage
|
||||
import com.jetbrains.python.poetry.getPyProjectTomlForPoetry
|
||||
import com.jetbrains.python.resolvePythonBinary
|
||||
import com.jetbrains.python.sdk.PythonSdkUtil
|
||||
import com.jetbrains.python.sdk.basePath
|
||||
import com.jetbrains.python.sdk.createSdk
|
||||
import com.jetbrains.python.sdk.getOrCreateAdditionalData
|
||||
import com.jetbrains.python.venvReader.tryResolvePath
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import java.nio.file.Path
|
||||
import java.util.regex.Pattern
|
||||
@@ -34,44 +30,32 @@ val POETRY_ICON: Icon = PythonIcons.Python.Origami
|
||||
@Internal
|
||||
fun suggestedSdkName(basePath: Path): @NlsSafe String = "Poetry (${PathUtil.getFileName(basePath.pathString)})"
|
||||
|
||||
/**
|
||||
* Sets up the poetry environment under the modal progress window.
|
||||
*
|
||||
* The poetry is associated with the first valid object from this list:
|
||||
*
|
||||
* 1. New project specified by [newProjectPath]
|
||||
* 2. Existing module specified by [module]
|
||||
* 3. Existing project specified by [project]
|
||||
*
|
||||
* @return the SDK for poetry, not stored in the SDK table yet.
|
||||
*/
|
||||
|
||||
@Internal
|
||||
suspend fun setupPoetrySdk(
|
||||
project: Project?,
|
||||
module: Module?,
|
||||
suspend fun createNewPoetrySdk(
|
||||
moduleBasePath: Path,
|
||||
existingSdks: List<Sdk>,
|
||||
newProjectPath: String?,
|
||||
python: String?,
|
||||
basePythonBinaryPath: PythonBinary?,
|
||||
installPackages: Boolean,
|
||||
poetryPath: String? = null,
|
||||
): PyResult<Sdk> {
|
||||
val pathString = newProjectPath ?: module?.basePath ?: project?.basePath
|
||||
val projectPath = pathString?.let { tryResolvePath(it) }
|
||||
?: return PyResult.localizedError(PyBundle.message("python.sdk.provided.path.is.invalid", pathString))
|
||||
val pythonBinaryPath = setUpPoetry(moduleBasePath, basePythonBinaryPath, installPackages).getOr { return it }
|
||||
|
||||
val pythonExecutablePath = setUpPoetry(projectPath, python, installPackages, poetryPath)
|
||||
.getOr { return it }
|
||||
|
||||
val result = createSdk(
|
||||
sdkHomePath = pythonExecutablePath,
|
||||
existingSdks = existingSdks,
|
||||
associatedProjectPath = projectPath.toString(),
|
||||
suggestedSdkName = suggestedSdkName(projectPath),
|
||||
sdkAdditionalData = PyPoetrySdkAdditionalData(projectPath)
|
||||
)
|
||||
return result
|
||||
return createPoetrySdk(moduleBasePath, existingSdks, pythonBinaryPath)
|
||||
}
|
||||
|
||||
@Internal
|
||||
suspend fun createPoetrySdk(
|
||||
moduleBasePath: Path,
|
||||
existingSdks: List<Sdk>,
|
||||
pythonBinaryPath: PythonBinary,
|
||||
): PyResult<Sdk> = createSdk(
|
||||
pythonBinaryPath = pythonBinaryPath,
|
||||
existingSdks = existingSdks,
|
||||
associatedProjectPath = moduleBasePath.toString(),
|
||||
suggestedSdkName = suggestedSdkName(moduleBasePath),
|
||||
sdkAdditionalData = PyPoetrySdkAdditionalData(moduleBasePath)
|
||||
)
|
||||
|
||||
internal val Sdk.isPoetry: Boolean
|
||||
get() {
|
||||
if (!PythonSdkUtil.isPythonSdk(this)) {
|
||||
@@ -91,21 +75,12 @@ internal fun allModules(project: Project?): List<Module> {
|
||||
}?.sortedBy { it.name } ?: emptyList()
|
||||
}
|
||||
|
||||
private suspend fun setUpPoetry(projectPath: Path, python: String?, installPackages: Boolean, poetryPath: String? = null): PyResult<Path> {
|
||||
val poetryExecutablePathString = when (poetryPath) {
|
||||
is String -> poetryPath
|
||||
else -> {
|
||||
val pyProjectToml = withContext(Dispatchers.IO) {
|
||||
StandardFileSystems.local().findFileByPath(projectPath.toString())?.findChild(PY_PROJECT_TOML)
|
||||
}
|
||||
val init = pyProjectToml?.let {
|
||||
getPyProjectTomlForPoetry(it)
|
||||
} == null
|
||||
setupPoetry(projectPath, python, installPackages, init).getOr { return it }
|
||||
}
|
||||
}
|
||||
|
||||
return PyResult.success(Path.of(getPythonExecutable(poetryExecutablePathString)))
|
||||
private suspend fun setUpPoetry(moduleBasePath: Path, basePythonBinaryPath: PythonBinary?, installPackages: Boolean): PyResult<PythonBinary> {
|
||||
val init = PyProjectToml.findInRoot(moduleBasePath) == null
|
||||
val pythonHomePath = setupPoetry(moduleBasePath, basePythonBinaryPath, installPackages, init).getOr { return it }
|
||||
val pythonBinaryPath = pythonHomePath.resolvePythonBinary()
|
||||
?: return PyResult.localizedError(PyBundle.message("python.sdk.cannot.setup.sdk", pythonHomePath))
|
||||
return PyResult.success(pythonBinaryPath)
|
||||
}
|
||||
|
||||
fun parsePoetryShowOutdated(input: String): Map<String, PythonOutdatedPackage> {
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jetbrains.python.sdk.poetry.*
|
||||
import com.jetbrains.python.ui.pyMayBeModalBlocking
|
||||
import com.jetbrains.python.util.runWithModalBlockingOrInBackground
|
||||
import java.awt.BorderLayout
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.swing.Icon
|
||||
|
||||
@@ -75,9 +76,15 @@ class PyAddExistingPoetryEnvPanel(
|
||||
return when (val sdk = sdkComboBox.selectedSdk) {
|
||||
is PyDetectedSdk -> {
|
||||
val mappedModule = sdkToModule[sdk.name] ?: module
|
||||
|
||||
runWithModalBlockingOrInBackground(project, msg = PyBundle.message("python.sdk.dialog.title.setting.up.poetry.environment")) {
|
||||
setupPoetrySdk(project, mappedModule, existingSdks, newProjectPath,
|
||||
getPythonExecutable(sdk.name), false, sdk.name).onSuccess {
|
||||
val moduleBasePath = mappedModule?.basePath?.let { Path.of(it) }
|
||||
?: error("module base path is invalid: ${mappedModule?.basePath}")
|
||||
|
||||
val basePythonBinaryPath = getPythonExecutable(sdk.name).let { Path.of(it) }
|
||||
?: error("base python binary path is invalid, home path is ${sdk.name}")
|
||||
|
||||
createPoetrySdk(moduleBasePath, existingSdks, basePythonBinaryPath).onSuccess {
|
||||
PySdkSettings.instance.preferredVirtualEnvBaseSdk = getPythonExecutable(sdk.name)
|
||||
}
|
||||
}.getOrNull()
|
||||
|
||||
@@ -42,6 +42,7 @@ import kotlinx.coroutines.withContext
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Dimension
|
||||
import java.awt.event.ItemEvent
|
||||
import java.nio.file.Path
|
||||
import javax.swing.Icon
|
||||
import javax.swing.JComboBox
|
||||
import javax.swing.event.DocumentEvent
|
||||
@@ -139,8 +140,11 @@ class PyAddNewPoetryPanel(
|
||||
override fun getOrCreateSdk(): Sdk? {
|
||||
PropertiesComponent.getInstance().poetryPath = poetryPathField.text.nullize()
|
||||
return pyModalBlocking {
|
||||
setupPoetrySdk(project, selectedModule, existingSdks, newProjectPath,
|
||||
baseSdkField.selectedSdk.homePath, installPackagesCheckBox.isSelected).onSuccess {
|
||||
val moduleBasePath = selectedModule?.basePath?.let { Path.of(it) }
|
||||
?: error("select module base path is invalid: ${selectedModule?.basePath}")
|
||||
val basePythonBinaryPath = baseSdkField.selectedSdk.homePath?.let { Path.of(it) }
|
||||
|
||||
createNewPoetrySdk(moduleBasePath, existingSdks, basePythonBinaryPath, installPackagesCheckBox.isSelected).onSuccess {
|
||||
PySdkSettings.instance.preferredVirtualEnvBaseSdk = baseSdkField.selectedSdk.homePath
|
||||
}
|
||||
}.getOrNull()
|
||||
|
||||
Reference in New Issue
Block a user