support uv interpreter project configuration upon opening for the first time; PY-75983

(cherry picked from commit 44f133462ae29d6865a3ed5918a556d7d0a2cac7)

GitOrigin-RevId: d87fc8ae6076fb4fc3c20e8effaf5818c2f8ba20
This commit is contained in:
Aleksandr Sorotskii
2024-11-26 16:14:42 +01:00
committed by intellij-monorepo-bot
parent dc79f6b09c
commit 77157d6fe2
5 changed files with 92 additions and 9 deletions

View File

@@ -104,7 +104,10 @@
id="environmentYml"/>
<projectSdkConfigurationExtension implementation="com.intellij.pycharm.community.ide.impl.configuration.PyPipfileSdkConfiguration"
id="pipfile" order="before requirementsTxtOrSetupPy"/>
<projectSdkConfigurationExtension implementation="com.intellij.pycharm.community.ide.impl.configuration.PyPoetrySdkConfiguration"/>
<projectSdkConfigurationExtension implementation="com.intellij.pycharm.community.ide.impl.configuration.PyPoetrySdkConfiguration"
id="poetry"/>
<projectSdkConfigurationExtension implementation="com.intellij.pycharm.community.ide.impl.configuration.PyUvSdkConfiguration"
id="uv" order="after poetry"/>
</extensions>
<actions resource-bundle="messages.ActionsBundle">

View File

@@ -58,6 +58,8 @@ sdk.dialog.title.setting.up.poetry.environment=Setting Up Poetry Environment
sdk.notification.label.set.up.poetry.environment.from.pyproject.toml.dependencies=File pyproject.toml contains project dependencies. Would you like to set up a poetry environment?
notification.group.pro.advertiser=PyCharm Professional recommended
sdk.set.up.uv.environment=Set up an uv environment using {0}
new.project.python.group.name=Python
new.project.other.group.name=Other

View File

@@ -34,20 +34,29 @@ import javax.swing.JComponent
import javax.swing.JPanel
import kotlin.io.path.pathString
/**
* This source code is created by @koxudaxi Koudai Aono <koxudaxi@gmail.com>
*/
class PyPoetrySdkConfiguration : PyProjectSdkConfigurationExtension {
companion object {
private val LOGGER = Logger.getInstance(PyPoetrySdkConfiguration::class.java)
}
@RequiresBackgroundThread
override fun createAndAddSdkForConfigurator(module: Module): Sdk? = runBlockingCancellable { createAndAddSDk(module, false) }
override fun getIntention(module: Module): @IntentionName String? {
return runBlockingCancellable {
val toml = findAmongRoots(module, PY_PROJECT_TOML)
if (toml == null) {
return@runBlockingCancellable null
}
val isPoetry = getPyProjectTomlForPoetry(toml) != null
if (!isPoetry) {
return@runBlockingCancellable null
}
PyCharmCommunityCustomizationBundle.message("sdk.set.up.poetry.environment", toml.name)
}
}
@RequiresBackgroundThread
override fun getIntention(module: Module): @IntentionName String? = findAmongRoots(module, PY_PROJECT_TOML)?.let { PyCharmCommunityCustomizationBundle.message("sdk.set.up.poetry.environment", it.name) }
override fun createAndAddSdkForConfigurator(module: Module): Sdk? = runBlockingCancellable { createAndAddSDk(module, false) }
@RequiresBackgroundThread
override fun createAndAddSdkForInspection(module: Module): Sdk? = runBlockingCancellable { createAndAddSDk(module, true) }

View File

@@ -0,0 +1,69 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.pycharm.community.ide.impl.configuration
import com.intellij.codeInspection.util.IntentionName
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.module.Module
import com.intellij.openapi.progress.runBlockingCancellable
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
import com.intellij.pycharm.community.ide.impl.PyCharmCommunityCustomizationBundle
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
import com.jetbrains.python.sdk.*
import com.jetbrains.python.sdk.basePath
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfigurationExtension
import com.jetbrains.python.sdk.uv.PY_PROJECT_TOML
import com.jetbrains.python.sdk.uv.getUvExecutable
import com.jetbrains.python.sdk.uv.setupUvSdkUnderProgress
import java.io.FileNotFoundException
import java.nio.file.Path
class PyUvSdkConfiguration : PyProjectSdkConfigurationExtension {
companion object {
private val LOGGER = Logger.getInstance(PyUvSdkConfiguration::class.java)
}
@RequiresBackgroundThread
override fun getIntention(module: Module): @IntentionName String? {
return findAmongRoots(module, PY_PROJECT_TOML)?.let { toml ->
getUvExecutable()?.let { PyCharmCommunityCustomizationBundle.message("sdk.set.up.uv.environment", toml.name) }
}
}
@RequiresBackgroundThread
override fun createAndAddSdkForConfigurator(module: Module): Sdk? {
return runBlockingCancellable {
createUv(module).getOrElse {
LOGGER.warn(it)
null
}
}
}
@RequiresBackgroundThread
override fun createAndAddSdkForInspection(module: Module): Sdk? {
return runBlockingCancellable {
createUv(module).getOrElse {
LOGGER.warn(it)
null
}
}
}
override fun supportsHeadlessModel(): Boolean = true
private suspend fun createUv(module: Module): Result<Sdk> {
val basePath = module.basePath?.let { Path.of(it) }
if (basePath == null) {
return Result.failure(FileNotFoundException("Can't find module base path"))
}
val sdk = setupUvSdkUnderProgress(module, basePath, ProjectJdkTable.getInstance().allJdks.toList(), null)
sdk.onSuccess {
SdkConfigurationUtil.addSdk(it)
}
return sdk
}
}

View File

@@ -61,7 +61,7 @@ const val POETRY_DEFAULT_SOURCE_URL: String = "https://pypi.org/simple"
val LOGGER = Logger.getInstance("#com.jetbrains.python.sdk.poetry")
internal suspend fun getPyProjectTomlForPoetry(virtualFile: VirtualFile): VirtualFile? =
suspend fun getPyProjectTomlForPoetry(virtualFile: VirtualFile): VirtualFile? =
withContext(Dispatchers.IO) {
readAction {
try {