PY-87266: uv: workspace roots are also workspace members.

Not only `members` table declared in the root, but also root itself is member, and can depend on its members.

GitOrigin-RevId: b1ff05222ae240fac20b5d8bc69f06ff89f51fad
This commit is contained in:
Ilya.Kazakevich
2026-01-30 05:00:01 +00:00
committed by intellij-monorepo-bot
parent 042430fea2
commit d37f3aeefa
2 changed files with 28 additions and 6 deletions
@@ -1,5 +1,6 @@
package com.intellij.python.pyproject.model.internal
import com.intellij.openapi.diagnostic.fileLogger
import com.intellij.openapi.module.Module
import com.intellij.platform.backend.workspace.virtualFile
import com.intellij.platform.backend.workspace.workspaceModel
@@ -15,13 +16,29 @@ internal val Module.isPyProjectTomlBasedImpl: Boolean get() = findModuleEntity()
internal suspend fun suggestSdkImpl(module: Module): SuggestedSdk? = withContext(Dispatchers.Default) {
val entity = module.findModuleEntity()?.pyProjectTomlEntity ?: return@withContext null
val storage = module.project.workspaceModel.currentSnapshot
val toolWithWorkspace = entity.participatedTools.firstNotNullOfOrNull { (tool, moduleId) ->
val module = moduleId?.resolve(storage)?.findModule(storage)
if (module != null) Pair(tool, module) else null
val moduleId = module.findModuleEntity(storage)?.symbolicId
if (moduleId == null) {
logger.warn("Module $module doesn't exist in a storage, no SDK could be suggested")
return@withContext null
}
val toolWithWorkspace = entity.participatedTools.firstNotNullOfOrNull { (tool, workspaceRootModuleId) ->
if (workspaceRootModuleId == moduleId) {
null // This module is a workspace root and can't be `SameAs()` itself
}
else {
val workspaceRootModule = workspaceRootModuleId?.resolve(storage)?.findModule(storage)
if (workspaceRootModule != null) {
Pair(tool, workspaceRootModule)
}
else {
null
}
}
}
if (toolWithWorkspace != null) {
val (tool, module) = toolWithWorkspace
SuggestedSdk.SameAs(module, tool)
val (tool, workspaceRootModule) = toolWithWorkspace
assert(workspaceRootModule != module) { "$module is a workspace root, can't point to itself" }
SuggestedSdk.SameAs(workspaceRootModule, tool)
}
else {
val tools = entity.participatedTools.keys
@@ -33,3 +50,4 @@ internal suspend fun suggestSdkImpl(module: Module): SuggestedSdk? = withContext
}
}
private val logger = fileLogger()
@@ -45,11 +45,15 @@ internal class UvTool : Tool {
val memberToWorkspace = HashMap<ProjectName, MutableSet<ProjectName>>()
for ((workspaceRoot, matchersAndName) in workspaces) {
val (matchers, workspaceName) = matchersAndName
// From the uv doc: every workspace needs a root, which is also a workspace member.
val workspaceMembers = mutableSetOf(workspaceName)
workspaceToMembers[workspaceName] = workspaceMembers
memberToWorkspace[workspaceName] = mutableSetOf(workspaceName)
for ((memberRoot, memberName) in dirToProjectName) {
if (!memberRoot.startsWith(workspaceRoot)) continue
if (matchers.match(memberRoot.relativeTo(workspaceRoot).normalize())) {
workspaceToMembers.getOrPut(workspaceName) { HashSet() }.add(memberName)
workspaceMembers.add(memberName)
memberToWorkspace.getOrPut(memberName) { HashSet() }.add(workspaceName)
}