mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
PY-87441 Use existing environment even if another tool fits better
Before the changes, if there's a multi-module project, we used information about tools from pyproject.toml collected by workspace tools. That led to an effect when an existing environment wouldn't be used if it wasn't part of preferred tools. This change prioritizes existing environment over anything else with the only exception of uv workspaces. (cherry picked from commit 5ae899ba4c2541cbb4eab5e393b4f3ca26e3f626) IJ-MR-192963 GitOrigin-RevId: 001775336af7f155b7ecfc5871ce792afb054258
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b10d38571b
commit
3a6ae5cccf
@@ -39,16 +39,22 @@ suspend fun Module.getModuleInfo(
|
||||
configuratorsByTool: Map<ToolId, PyProjectSdkConfigurationExtension> = PyProjectSdkConfigurationExtension.createMap(),
|
||||
): ModuleCreateInfo? { // Save on module level
|
||||
val venvsInModule = findPythonVirtualEnvironments()
|
||||
val bestProposalFromTools = PyProjectSdkConfigurationExtension.findAllSortedForModule(this, venvsInModule).firstOrNull()
|
||||
|
||||
val suggestedByPyProjectToml = when (val suggestedSdk = suggestSdk()) {
|
||||
is SuggestedSdk.PyProjectIndependent -> {
|
||||
configuratorsByTool
|
||||
.filter { it.key in suggestedSdk.preferTools }
|
||||
.firstNotNullOfOrNull { (toolId, extension) ->
|
||||
extension.asPyProjectTomlSdkConfigurationExtension()?.createSdkWithoutPyProjectTomlChecks(this, venvsInModule)?.let {
|
||||
CreateSdkInfoWithTool(it, toolId).asDTO(suggestedSdk.moduleDir)
|
||||
}
|
||||
when (bestProposalFromTools?.createSdkInfo) {
|
||||
is CreateSdkInfo.ExistingEnv -> bestProposalFromTools.asDTO(suggestedSdk.moduleDir)
|
||||
is CreateSdkInfo.WillCreateEnv, is CreateSdkInfo.WillInstallTool, null -> {
|
||||
configuratorsByTool
|
||||
.filter { it.key in suggestedSdk.preferTools }
|
||||
.firstNotNullOfOrNull { (toolId, extension) ->
|
||||
extension.asPyProjectTomlSdkConfigurationExtension()?.createSdkWithoutPyProjectTomlChecks(this, venvsInModule)?.let {
|
||||
CreateSdkInfoWithTool(it, toolId).asDTO(suggestedSdk.moduleDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is SuggestedSdk.SameAs -> {
|
||||
ModuleCreateInfo.SameAs(suggestedSdk.parentModule)
|
||||
@@ -58,8 +64,6 @@ suspend fun Module.getModuleInfo(
|
||||
suggestedByPyProjectToml?.let { return it }
|
||||
|
||||
// No tools or not pyproject.toml at all? Use EP as a fallback
|
||||
val bestProposalFromTools = PyProjectSdkConfigurationExtension.findAllSortedForModule(this, venvsInModule).firstOrNull()
|
||||
|
||||
return bestProposalFromTools?.let {
|
||||
CreateSdkInfoWithTool(it.createSdkInfo, it.toolId).asDTO(guessModuleDir()?.toNioPath())
|
||||
}
|
||||
|
||||
@@ -8,6 +8,11 @@ import com.jetbrains.python.PythonBinary
|
||||
import com.jetbrains.python.sdk.baseDir
|
||||
import com.jetbrains.python.venvReader.VirtualEnvReader
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.CheckReturnValue
|
||||
@@ -34,6 +39,7 @@ suspend fun Module.findPythonVirtualEnvironments(): List<PythonBinary> {
|
||||
interface PyProjectSdkConfigurationExtension {
|
||||
companion object {
|
||||
private val EP_NAME: ExtensionPointName<PyProjectSdkConfigurationExtension> = ExtensionPointName.create("Pythonid.projectSdkConfigurationExtension")
|
||||
private val CONCURRENCY_LIMIT = Semaphore(permits = 5)
|
||||
|
||||
/**
|
||||
* EPs associated by tool id
|
||||
@@ -46,13 +52,21 @@ interface PyProjectSdkConfigurationExtension {
|
||||
*/
|
||||
suspend fun findAllSortedForModule(module: Module, venvsInModule: List<PythonBinary>): List<CreateSdkInfoWithTool> {
|
||||
return EP_NAME.extensionsIfPointIsRegistered
|
||||
.mapNotNull { e -> e.checkEnvironmentAndPrepareSdkCreator(module, venvsInModule)?.let { CreateSdkInfoWithTool(it, e.toolId) } }
|
||||
.concurrentMapNotNull { e -> e.checkEnvironmentAndPrepareSdkCreator(module, venvsInModule)?.let { CreateSdkInfoWithTool(it, e.toolId) } }
|
||||
.sortedBy { it.createSdkInfo }
|
||||
}
|
||||
|
||||
suspend fun findAllSortedForModule(module: Module): List<CreateSdkInfoWithTool> {
|
||||
return findAllSortedForModule(module, module.findPythonVirtualEnvironments())
|
||||
}
|
||||
|
||||
private suspend fun <A, B> Iterable<A>.concurrentMapNotNull(f: suspend (A) -> B?): List<B> = coroutineScope {
|
||||
map {
|
||||
async {
|
||||
CONCURRENCY_LIMIT.withPermit { f(it) }
|
||||
}
|
||||
}.awaitAll().filterNotNull()
|
||||
}
|
||||
}
|
||||
|
||||
val toolId: ToolId
|
||||
|
||||
Reference in New Issue
Block a user