cleanup [python]: rename Tool to PyProjectManager

(cherry picked from commit fc0c4714d6431c915d4197969e1eda97b57a0cf6)

GitOrigin-RevId: 3c9781741f0eb0125ece7097a2f9e2cf53241063
This commit is contained in:
Ilya.Kazakevich
2026-06-28 18:45:35 +00:00
committed by intellij-monorepo-bot
parent 0e36c07080
commit 2b3812da08
10 changed files with 42 additions and 42 deletions
@@ -19,7 +19,7 @@
implementation="com.intellij.python.hatch.sdk.evolution.HatchSelectSdkProvider"/>
</extensions>
<extensions defaultExtensionNs="com.intellij.python.pyproject.model">
<tool implementation="com.intellij.python.hatch.impl.HatchTool"/>
<pyprojectmanager implementation="com.intellij.python.hatch.impl.HatchPyProjectManager"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<python.community.common.toolToIconMapper implementation="com.intellij.python.hatch.impl.HatchIdMapper"/>
@@ -8,7 +8,7 @@ import com.intellij.python.pyproject.model.internal.pyProjectToml.TomlDependency
import com.intellij.python.pyproject.model.spi.ProjectName
import com.intellij.python.pyproject.model.spi.ProjectStructureInfo
import com.intellij.python.pyproject.model.spi.PyProjectTomlProject
import com.intellij.python.pyproject.model.spi.Tool
import com.intellij.python.pyproject.model.spi.PyProjectManager
import com.jetbrains.python.PyToolUIInfo
import com.jetbrains.python.venvReader.Directory
import org.apache.tuweni.toml.TomlTable
@@ -18,7 +18,7 @@ import org.jetbrains.annotations.ApiStatus
val HATCH_TOOL_ID: ToolId = ToolId("hatch")
val HATCH_UI_INFO: PyToolUIInfo = PyToolUIInfo("Hatch", PythonHatchIcons.Logo)
internal class HatchTool : Tool {
internal class HatchPyProjectManager : PyProjectManager {
override val id: ToolId = HATCH_TOOL_ID
override val ui: PyToolUIInfo = HATCH_UI_INFO
@@ -9,6 +9,6 @@
<module name="intellij.python.community.common"/>
</dependencies>
<extensions defaultExtensionNs="com.intellij.python.pyproject.model">
<tool implementation="com.intellij.python.community.impl.poetry.backend.PoetryTool"/>
<pyprojectmanager implementation="com.intellij.python.community.impl.poetry.backend.PoetryPyProjectManager"/>
</extensions>
</idea-plugin>
@@ -10,12 +10,12 @@ import com.intellij.python.pyproject.model.internal.pyProjectToml.TomlDependency
import com.intellij.python.pyproject.model.spi.ProjectName
import com.intellij.python.pyproject.model.spi.ProjectStructureInfo
import com.intellij.python.pyproject.model.spi.PyProjectTomlProject
import com.intellij.python.pyproject.model.spi.Tool
import com.intellij.python.pyproject.model.spi.PyProjectManager
import com.jetbrains.python.PyToolUIInfo
import com.jetbrains.python.venvReader.Directory
import org.apache.tuweni.toml.TomlTable
internal class PoetryTool : Tool {
internal class PoetryPyProjectManager : PyProjectManager {
override val id: ToolId = POETRY_TOOL_ID
override val ui: PyToolUIInfo = POETRY_UI_INFO
@@ -33,7 +33,7 @@
</extensions>
<extensionPoints>
<extensionPoint qualifiedName="com.intellij.python.pyproject.model.tool" interface="com.intellij.python.pyproject.model.spi.Tool"
<extensionPoint qualifiedName="com.intellij.python.pyproject.model.pyprojectmanager" interface="com.intellij.python.pyproject.model.spi.PyProjectManager"
dynamic="true"/>
</extensionPoints>
@@ -39,7 +39,7 @@ import com.intellij.python.pyproject.model.internal.pyProjectToml.FSWalkInfoWith
import com.intellij.python.pyproject.model.internal.pyProjectToml.getDependenciesFromToml
import com.intellij.python.pyproject.model.spi.ProjectName
import com.intellij.python.pyproject.model.spi.PyProjectTomlProject
import com.intellij.python.pyproject.model.spi.Tool
import com.intellij.python.pyproject.model.spi.PyProjectManager
import com.intellij.python.pyproject.model.spi.WorkspaceName
import com.intellij.python.pyproject.model.spi.plus
import com.intellij.workspaceModel.ide.legacyBridge.LegacyBridgeJpsEntitySourceFactory
@@ -59,7 +59,7 @@ private val logger = fileLogger()
/** Collect all excluded folder paths from the workspace model. */
internal fun collectExcludedPaths(project: Project): Set<Path> {
return project.workspaceModel.currentSnapshot.entities<ContentRootEntity>()
.flatMap { cr -> cr.excludedUrls.asSequence().mapNotNull { it.url.toPath() } }
.flatMap { cr -> cr.excludedUrls.asSequence().map { it.url.toPath() } }
.toSet()
}
@@ -447,10 +447,10 @@ private suspend fun generatePyProjectTomlEntries(
existingPythonNames: Map<Path, String>,
allModuleNames: Set<String>,
): Set<PyProjectTomlBasedEntryImpl> = withContext(Dispatchers.Default) {
val tools = Tool.EP.extensionList
val rawEntries = parseRawEntries(fsInfo, tools)
val pyProjectManagers = PyProjectManager.EP.extensionList
val rawEntries = parseRawEntries(fsInfo, pyProjectManagers)
val entries = assignNames(rawEntries, existingPythonNames, allModuleNames)
resolveDependencies(entries, tools)
resolveDependencies(entries, pyProjectManagers)
return@withContext entries.toSet()
}
@@ -465,44 +465,44 @@ private data class RawEntry(
)
/** Parse pyproject.toml files into raw entries with natural names (no dedup). */
private suspend fun parseRawEntries(fsInfo: FSWalkInfoWithToml, tools: List<Tool>): List<RawEntry> {
private suspend fun parseRawEntries(fsInfo: FSWalkInfoWithToml, pyProjectManagers: List<PyProjectManager>): List<RawEntry> {
val rawEntries = ArrayList<RawEntry>()
for ((tomlFile, toml) in fsInfo.tomlFiles.entries.sortedBy { it.key }) {
val participatedTools = mutableSetOf<ToolId>()
val participatedManagers = mutableSetOf<ToolId>()
val root = tomlFile.parent
var projectNameAsString = toml.project?.name
if (projectNameAsString == null) {
val toolAndName = tools.getNameFromEP(toml)
if (toolAndName != null) {
projectNameAsString = toolAndName.second
participatedTools.add(toolAndName.first.id)
val managerAndName = pyProjectManagers.getNameFromEP(toml)
if (managerAndName != null) {
projectNameAsString = managerAndName.second
participatedManagers.add(managerAndName.first.id)
}
}
if (projectNameAsString == null) {
projectNameAsString = root.name
}
val sourceRootsAndTools = tools.flatMap { tool -> tool.getSrcRoots(toml.toml, root).map { Pair(tool, it) } }.toSet()
val sourceRootsAndTools = pyProjectManagers.flatMap { tool -> tool.getSrcRoots(toml.toml, root).map { Pair(tool, it) } }.toSet()
val sourceRoots = sourceRootsAndTools.map { it.second }.toSet() + findSrc(root)
participatedTools.addAll(sourceRootsAndTools.map { it.first.id })
if (participatedTools.isEmpty()) {
for (tool in tools) {
participatedManagers.addAll(sourceRootsAndTools.map { it.first.id })
if (participatedManagers.isEmpty()) {
for (tool in pyProjectManagers) {
if (toml.toml.contains("tool.${tool.id.id}")) {
participatedTools.add(tool.id)
participatedManagers.add(tool.id)
}
}
}
if (participatedTools.isEmpty()) {
if (participatedManagers.isEmpty()) {
toml.toml.getString("build-system.build-backend")?.let { buildBackend ->
tools.firstOrNull { it.id.id in buildBackend }?.let { buildTool ->
participatedTools.add(buildTool.id)
pyProjectManagers.firstOrNull { it.id.id in buildBackend }?.let { buildTool ->
participatedManagers.add(buildTool.id)
}
}
}
val relationsWithTools: MutableSet<PyProjectTomlToolRelation> = participatedTools.mapTo(mutableSetOf()) {
val relationsWithTools: MutableSet<PyProjectTomlToolRelation> = participatedManagers.mapTo(mutableSetOf()) {
PyProjectTomlToolRelation.SimpleRelation(it)
}
rawEntries.add(RawEntry(tomlFile, root, projectNameAsString, participatedTools, toml, sourceRoots, relationsWithTools))
rawEntries.add(RawEntry(tomlFile, root, projectNameAsString, participatedManagers, toml, sourceRoots, relationsWithTools))
}
return rawEntries
}
@@ -576,25 +576,25 @@ private fun assignNames(
}
/** Resolve inter-module dependencies and workspace membership from tools. */
private suspend fun resolveDependencies(entries: List<PyProjectTomlBasedEntryImpl>, tools: List<Tool>) {
private suspend fun resolveDependencies(entries: List<PyProjectTomlBasedEntryImpl>, pyProjectManagers: List<PyProjectManager>) {
val entriesByName = entries.associateBy { it.name }
val namesByDir = entries.associate { Pair(it.root, it.name) }
val allNames = entriesByName.keys
var dependencies = getDependenciesFromToml(entriesByName, namesByDir, tools.flatMap { it.getTomlDependencySpecifications() })
for (tool in tools) {
val toolSpecificInfo = tool.getProjectStructure(entriesByName, namesByDir)
var dependencies = getDependenciesFromToml(entriesByName, namesByDir, pyProjectManagers.flatMap { it.getTomlDependencySpecifications() })
for (pyProjectManager in pyProjectManagers) {
val toolSpecificInfo = pyProjectManager.getProjectStructure(entriesByName, namesByDir)
if (toolSpecificInfo != null) {
dependencies += toolSpecificInfo.dependencies
for (entityName in toolSpecificInfo.dependencies.map.keys) {
val entity = entriesByName[entityName] ?: error("returned broken name $entityName")
entity.relationsWithTools.add(PyProjectTomlToolRelation.SimpleRelation(tool.id))
entity.relationsWithTools.add(PyProjectTomlToolRelation.SimpleRelation(pyProjectManager.id))
}
}
val workspaceMembers = toolSpecificInfo?.membersToWorkspace ?: emptyMap()
for ((member, workspace) in workspaceMembers) {
entriesByName[member]!!.relationsWithTools.add(PyProjectTomlToolRelation.WorkspaceMember(tool.id, workspace))
entriesByName[workspace]!!.relationsWithTools.add(PyProjectTomlToolRelation.SimpleRelation(tool.id))
entriesByName[member]!!.relationsWithTools.add(PyProjectTomlToolRelation.WorkspaceMember(pyProjectManager.id, workspace))
entriesByName[workspace]!!.relationsWithTools.add(PyProjectTomlToolRelation.SimpleRelation(pyProjectManager.id))
}
}
for ((name, deps) in dependencies.map) {
@@ -605,7 +605,7 @@ private suspend fun resolveDependencies(entries: List<PyProjectTomlBasedEntryImp
}
}
private suspend fun Iterable<Tool>.getNameFromEP(projectToml: PyProjectToml): Pair<Tool, @NlsSafe String>? =
private suspend fun Iterable<PyProjectManager>.getNameFromEP(projectToml: PyProjectToml): Pair<PyProjectManager, @NlsSafe String>? =
withContext(Dispatchers.Default) {
firstNotNullOfOrNull { tool -> tool.getProjectName(projectToml.toml)?.let { Pair(tool, it) } }
}
@@ -8,9 +8,9 @@ import com.jetbrains.python.PyToolUIInfo
import com.jetbrains.python.venvReader.Directory
import org.apache.tuweni.toml.TomlTable
interface Tool {
interface PyProjectManager {
companion object {
internal val EP = ExtensionPointName.create<Tool>("com.intellij.python.pyproject.model.tool")
internal val EP = ExtensionPointName.create<PyProjectManager>("com.intellij.python.pyproject.model.pyprojectmanager")
}
val id: ToolId
@@ -1,5 +1,5 @@
/**
* Implement {@link com.intellij.python.pyproject.model.spi.Tool} and register it
* Implement {@link com.intellij.python.pyproject.model.spi.PyProjectManager} and register it
*/
@ApiStatus.Internal
package com.intellij.python.pyproject.model.spi;
@@ -13,6 +13,6 @@
<!-- endregion -->
</dependencies>
<extensions defaultExtensionNs="com.intellij.python.pyproject.model">
<tool implementation="com.intellij.python.uv.backend.UvTool"/>
<pyprojectmanager implementation="com.intellij.python.uv.backend.UvPyProjectManager"/>
</extensions>
</idea-plugin>
@@ -11,7 +11,7 @@ import com.intellij.python.pyproject.model.spi.ProjectDependencies
import com.intellij.python.pyproject.model.spi.ProjectName
import com.intellij.python.pyproject.model.spi.ProjectStructureInfo
import com.intellij.python.pyproject.model.spi.PyProjectTomlProject
import com.intellij.python.pyproject.model.spi.Tool
import com.intellij.python.pyproject.model.spi.PyProjectManager
import com.intellij.python.uv.common.UV_TOOL_ID
import com.intellij.python.uv.common.UV_UI_INFO
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
@@ -28,7 +28,7 @@ import java.nio.file.PathMatcher
import kotlin.io.path.relativeTo
internal class UvTool : Tool {
internal class UvPyProjectManager : PyProjectManager {
override val id: ToolId = UV_TOOL_ID