mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 06:39:38 +07:00
[python] support python dependencies in pyproject.toml (PY-59844)
- completion for package names in `dependencies` and `install-requires` - completion for build-backends - if a package is not installed, provide a quickfix to install it / run `pip install -e .` GitOrigin-RevId: cad88e4058a45f6db717b8da8fd7f6c456008998
This commit is contained in:
committed by
intellij-monorepo-bot
parent
03a517b29d
commit
2180aa6230
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports unsatisfied dependencies, declared [project.dependencies] table in pyproject.toml.
|
||||
<p>
|
||||
Shows a quick-fix to install missing packages.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1297,6 +1297,15 @@ conda.packaging.error.rendering.description=<html><head></head><body><p class="e
|
||||
conda.packaging.exception.timeout=Time out
|
||||
conda.packaging.exception.non.zero=Non-zero exit code
|
||||
|
||||
# pyproject.toml
|
||||
INSP.NAME.pyproject.packages=Depencencies in pyproject.toml
|
||||
python.pyproject.package.completion.tail=Python package
|
||||
python.pyproject.package.not.installed=Package {0} is not installed
|
||||
python.pyproject.install.package=Install package {0}
|
||||
python.pyproject.install.self.as.editable=Run 'pip install -e .'
|
||||
python.pyproject.install.self.as.editable.progress=Running 'pip install -e .'
|
||||
python.pyproject.install.self.error=Error Running 'pip install -e .'
|
||||
|
||||
# Python Packages toolwindow
|
||||
python.toolwindow.packages.installed.label=Installed
|
||||
python.toolwindow.packages.custom.repo.searched={0} ({1} found)
|
||||
|
||||
@@ -489,6 +489,19 @@
|
||||
<notificationGroup id="pyproject.toml Watcher" displayType="STICKY_BALLOON" isLogByDefault="true" bundle="messages.PyBundle"
|
||||
key="python.sdk.poetry.pip.file.watcher"/>
|
||||
|
||||
<completion.contributor language="TOML"
|
||||
implementationClass="com.jetbrains.python.packaging.pyproject.PyprojectPackageCompletionContributor"/>
|
||||
<completion.contributor language="TOML"
|
||||
implementationClass="com.jetbrains.python.packaging.pyproject.PyprojectMetadataCompletionContributor"/>
|
||||
<localInspection language="TOML"
|
||||
shortName="PyprojectInspection"
|
||||
suppressId="PyprojectInspection"
|
||||
bundle="messages.PyBundle"
|
||||
groupKey="INSP.GROUP.python"
|
||||
key="INSP.NAME.pyproject.packages"
|
||||
level="WARNING"
|
||||
enabledByDefault="true"
|
||||
implementationClass="com.jetbrains.python.packaging.pyproject.PyprojectPackageInspection"/>
|
||||
<toolWindow id="Python Packages" anchor="bottom"
|
||||
icon="PythonIcons.Python.PythonPackages"
|
||||
factoryClass="com.jetbrains.python.packaging.toolwindow.PyPackagesToolWindowFactory"/>
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.jetbrains.python.packaging.repository.PyEmptyPackagePackageRepository
|
||||
import com.jetbrains.python.packaging.repository.PyPIPackageRepository
|
||||
import com.jetbrains.python.packaging.repository.PyPackageRepository
|
||||
import com.jetbrains.python.packaging.requirement.PyRequirementRelation
|
||||
import org.jetbrains.annotations.Nls
|
||||
|
||||
open class PythonPackage(val name: String, val version: String) {
|
||||
@@ -56,9 +57,10 @@ interface PythonPackageSpecification {
|
||||
val name: String
|
||||
val version: String?
|
||||
val repository: PyPackageRepository?
|
||||
val relation: PyRequirementRelation?
|
||||
|
||||
fun buildInstallationString(): List<String> = buildList {
|
||||
val versionString = if (version != null) "==$version" else ""
|
||||
val versionString = if (version != null) "${relation?.presentableText ?: "=="}$version" else ""
|
||||
add("$name$versionString")
|
||||
if (repository == PyEmptyPackagePackageRepository) {
|
||||
thisLogger().warn("PyEmptyPackagePackageRepository used as source repository for package installation!")
|
||||
@@ -79,12 +81,15 @@ interface PythonLocationBasedPackageSpecification : PythonPackageSpecification {
|
||||
get() = null
|
||||
override val repository: PyPackageRepository?
|
||||
get() = null
|
||||
override val relation: PyRequirementRelation?
|
||||
get() = null
|
||||
override fun buildInstallationString(): List<String> = if (editable) listOf("-e", "$prefix$location") else listOf("$prefix$location")
|
||||
}
|
||||
|
||||
data class PythonSimplePackageSpecification(override val name: String,
|
||||
override val version: String?,
|
||||
override val repository: PyPackageRepository?) : PythonPackageSpecification
|
||||
override val repository: PyPackageRepository?,
|
||||
override val relation: PyRequirementRelation? = null) : PythonPackageSpecification
|
||||
|
||||
data class PythonLocalPackageSpecification(override val name: String,
|
||||
override val location: String,
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.jetbrains.python.packaging.common.PythonPackage
|
||||
import com.jetbrains.python.packaging.common.PythonPackageDetails
|
||||
import com.jetbrains.python.packaging.common.PythonPackageSpecification
|
||||
import com.jetbrains.python.packaging.repository.PyPackageRepository
|
||||
import com.jetbrains.python.packaging.requirement.PyRequirementRelation
|
||||
|
||||
class CondaPackage(name: String, version: String, val installedWithPip: Boolean = false) : PythonPackage(name, version) {
|
||||
override fun toString(): String {
|
||||
@@ -13,7 +14,8 @@ class CondaPackage(name: String, version: String, val installedWithPip: Boolean
|
||||
}
|
||||
|
||||
class CondaPackageSpecification(override val name: String,
|
||||
override val version: String?) : PythonPackageSpecification {
|
||||
override val version: String?,
|
||||
override val relation: PyRequirementRelation? = null) : PythonPackageSpecification {
|
||||
override val repository: PyPackageRepository = CondaPackageRepository
|
||||
|
||||
override fun buildInstallationString(): List<String> {
|
||||
@@ -34,7 +36,7 @@ class CondaPackageDetails(override val name: String,
|
||||
}
|
||||
|
||||
object CondaPackageRepository : PyPackageRepository("Conda", "", "") {
|
||||
override fun createPackageSpecification(packageName: String, version: String?): PythonPackageSpecification {
|
||||
return CondaPackageSpecification(packageName, version)
|
||||
override fun createPackageSpecification(packageName: String, version: String?, relation: PyRequirementRelation?): PythonPackageSpecification {
|
||||
return CondaPackageSpecification(packageName, version, relation)
|
||||
}
|
||||
}
|
||||
@@ -5,17 +5,18 @@ package com.jetbrains.python.packaging.management
|
||||
import com.intellij.execution.RunCanceledByUserException
|
||||
import com.intellij.execution.process.CapturingProcessHandler
|
||||
import com.intellij.execution.target.TargetProgressIndicator
|
||||
import com.intellij.execution.target.value.constant
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.withBackgroundProgressIndicator
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.progress.*
|
||||
import com.intellij.openapi.project.guessProjectDir
|
||||
import com.intellij.util.net.HttpConfigurable
|
||||
import com.jetbrains.python.PySdkBundle
|
||||
import com.jetbrains.python.PythonHelper
|
||||
import com.jetbrains.python.packaging.PyExecutionException
|
||||
import com.jetbrains.python.packaging.common.PythonPackageSpecification
|
||||
import com.jetbrains.python.packaging.repository.PyPackageRepository
|
||||
import com.jetbrains.python.packaging.requirement.PyRequirementRelation
|
||||
import com.jetbrains.python.run.PythonInterpreterTargetEnvironmentFactory
|
||||
import com.jetbrains.python.run.buildTargetedCommandLine
|
||||
import com.jetbrains.python.run.prepareHelperScriptExecution
|
||||
@@ -36,6 +37,9 @@ suspend fun PythonPackageManager.runPackagingTool(operation: String, arguments:
|
||||
val pythonExecution = prepareHelperScriptExecution(PythonHelper.PACKAGING_TOOL, helpersAwareTargetRequest)
|
||||
|
||||
// todo[akniazev]: check applyWorkingDir: PyTargetEnvironmentPackageManager.java:133
|
||||
project.guessProjectDir()?.path?.let {
|
||||
pythonExecution.workingDir = constant(it)
|
||||
}
|
||||
|
||||
pythonExecution.addParameter(operation)
|
||||
if (operation == "install") {
|
||||
@@ -72,8 +76,8 @@ suspend fun PythonPackageManager.runPackagingTool(operation: String, arguments:
|
||||
thisLogger().debug("Running python packaging tool. Operation: $operation")
|
||||
val handler = CapturingProcessHandler(process, targetedCommandLine.charset, commandLineString)
|
||||
|
||||
val result = withBackgroundProgressIndicator(project, text, cancellable = true) {
|
||||
handler.runProcess(10 * 60 * 1000)
|
||||
val result = withBackgroundProgress(project, text, cancellable = true) {
|
||||
handler.runProcess(10 * 60 * 1000)
|
||||
}
|
||||
|
||||
if (result.isCancelled) throw RunCanceledByUserException()
|
||||
@@ -82,7 +86,7 @@ suspend fun PythonPackageManager.runPackagingTool(operation: String, arguments:
|
||||
val helperPath = commandLine.firstOrNull() ?: ""
|
||||
val args: List<String> = commandLine.subList(min(1, commandLine.size), commandLine.size)
|
||||
if (exitCode != 0) {
|
||||
val message = if (StringUtil.isEmptyOrSpaces(result.stdout) && StringUtil.isEmptyOrSpaces(result.stderr)) PySdkBundle.message(
|
||||
val message = if (result.stdout.isBlank() && result.stderr.isBlank()) PySdkBundle.message(
|
||||
"python.conda.permission.denied")
|
||||
else PySdkBundle.message("python.sdk.packaging.non.zero.exit.code", exitCode)
|
||||
throw PyExecutionException(message, helperPath, args, result)
|
||||
@@ -107,4 +111,13 @@ private val proxyString: String?
|
||||
|
||||
fun PythonRepositoryManager.packagesByRepository(): Sequence<Pair<PyPackageRepository, List<String>>> {
|
||||
return repositories.asSequence().map { it to packagesFromRepository(it) }
|
||||
}
|
||||
|
||||
fun PythonPackageManager.isInstalled(name: String): Boolean {
|
||||
return installedPackages.any { it.name.lowercase() == name.lowercase() }
|
||||
}
|
||||
|
||||
fun PythonRepositoryManager.createSpecification(name: String, version: String? = null, relation: PyRequirementRelation? = null): PythonPackageSpecification {
|
||||
val repository = packagesByRepository().first { it.second.any { pkg -> pkg.lowercase() == name.lowercase() } }.first
|
||||
return repository.createPackageSpecification(name, version, relation)
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.packaging.pyproject
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.codeInspection.LocalQuickFix
|
||||
import com.intellij.codeInspection.ProblemDescriptor
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.packaging.PyRequirementParser
|
||||
import com.jetbrains.python.packaging.management.PythonPackageManager
|
||||
import com.jetbrains.python.packaging.management.createSpecification
|
||||
import com.jetbrains.python.packaging.toolwindow.PyPackagingToolWindowService
|
||||
import com.jetbrains.python.sdk.pythonSdk
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class PyInstallPackageQuickFix(val packageName: String) : LocalQuickFix {
|
||||
|
||||
|
||||
override fun getFamilyName(): String {
|
||||
return PyBundle.message("python.pyproject.install.package", packageName)
|
||||
}
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val element = descriptor.psiElement
|
||||
val file = descriptor.psiElement.containingFile ?: return
|
||||
val sdk = ModuleUtilCore.findModuleForPsiElement(element)?.pythonSdk ?: return
|
||||
val manager = PythonPackageManager.forSdk(project, sdk)
|
||||
val requirement = PyRequirementParser.fromLine(element.text.removeSurrounding("\"")) ?: return
|
||||
|
||||
project.service<PyPackagingToolWindowService>().serviceScope.launch(Dispatchers.IO) {
|
||||
val versionSpec = requirement.versionSpecs.firstOrNull()
|
||||
val specification = manager.repositoryManager.createSpecification(requirement.name, versionSpec?.version, versionSpec?.relation)
|
||||
manager.installPackage(specification)
|
||||
DaemonCodeAnalyzer.getInstance(project).restart(file)
|
||||
}
|
||||
}
|
||||
|
||||
override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo {
|
||||
return IntentionPreviewInfo.EMPTY
|
||||
}
|
||||
|
||||
override fun startInWriteAction(): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.packaging.pyproject
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.codeInspection.LocalQuickFix
|
||||
import com.intellij.codeInspection.ProblemDescriptor
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.findDocument
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.packaging.common.runPackagingOperationOrShowErrorDialog
|
||||
import com.jetbrains.python.packaging.management.PythonPackageManager
|
||||
import com.jetbrains.python.packaging.management.runPackagingTool
|
||||
import com.jetbrains.python.packaging.toolwindow.PyPackagingToolWindowService
|
||||
import com.jetbrains.python.sdk.pythonSdk
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class PyInstallProjectAsEditableQuickfix : LocalQuickFix {
|
||||
|
||||
override fun getFamilyName(): String {
|
||||
return PyBundle.message("python.pyproject.install.self.as.editable")
|
||||
}
|
||||
|
||||
@Suppress("DialogTitleCapitalization")
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val element = descriptor.psiElement
|
||||
val file = descriptor.psiElement.containingFile ?: return
|
||||
val sdk = ModuleUtilCore.findModuleForPsiElement(element)?.pythonSdk ?: return
|
||||
val manager = PythonPackageManager.forSdk(project, sdk)
|
||||
FileDocumentManager.getInstance().saveDocument(file.virtualFile.findDocument() ?: return)
|
||||
|
||||
project.service<PyPackagingToolWindowService>().serviceScope.launch {
|
||||
runPackagingOperationOrShowErrorDialog(sdk, PyBundle.message("python.pyproject.install.self.error"), null) {
|
||||
manager.runPackagingTool("install", listOf("-e", "."), PyBundle.message("python.pyproject.install.self.as.editable.progress"))
|
||||
manager.refreshPaths()
|
||||
manager.reloadPackages()
|
||||
}
|
||||
DaemonCodeAnalyzer.getInstance(project).restart(file)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun startInWriteAction(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo {
|
||||
return IntentionPreviewInfo.EMPTY
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.packaging.pyproject
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionContributor
|
||||
import com.intellij.codeInsight.completion.CompletionParameters
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import com.intellij.psi.util.elementType
|
||||
import com.intellij.psi.util.parentOfType
|
||||
import icons.PythonIcons
|
||||
import org.toml.lang.psi.TOML_STRING_LITERALS
|
||||
import org.toml.lang.psi.TomlKeyValue
|
||||
import org.toml.lang.psi.ext.name
|
||||
|
||||
class PyprojectMetadataCompletionContributor : CompletionContributor() {
|
||||
|
||||
|
||||
private val knownBackends = listOf("setuptools.build_meta",
|
||||
"setuptools.build_meta:__legacy__",
|
||||
"poetry.core.masonry.api",
|
||||
"flit_core.buildapi",
|
||||
"pdm.backend",
|
||||
"hatchling.build")
|
||||
|
||||
override fun fillCompletionVariants(parameters: CompletionParameters, result: CompletionResultSet) {
|
||||
if (parameters.originalFile.name != "pyproject.toml") return
|
||||
val position = parameters.position
|
||||
val parent = position.parent
|
||||
|
||||
if (TOML_STRING_LITERALS.contains(parent.elementType) && parent.parentOfType<TomlKeyValue>()?.key?.name == "build-backend") {
|
||||
knownBackends.map {
|
||||
LookupElementBuilder.create(it).withIcon(PythonIcons.Python.Python)
|
||||
}
|
||||
.forEach { result.addElement(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.packaging.pyproject
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionContributor
|
||||
import com.intellij.codeInsight.completion.CompletionParameters
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet
|
||||
import com.intellij.codeInsight.completion.PrioritizedLookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.psi.util.elementType
|
||||
import com.intellij.psi.util.parentOfType
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.packaging.pip.PypiPackageCache
|
||||
import icons.PythonIcons
|
||||
import org.toml.lang.psi.TOML_STRING_LITERALS
|
||||
import org.toml.lang.psi.TomlArray
|
||||
import org.toml.lang.psi.TomlKeyValue
|
||||
import org.toml.lang.psi.ext.name
|
||||
|
||||
class PyprojectPackageCompletionContributor : CompletionContributor() {
|
||||
|
||||
private val completionLocations = listOf("dependencies", "requires")
|
||||
override fun fillCompletionVariants(parameters: CompletionParameters, result: CompletionResultSet) {
|
||||
if (parameters.originalFile.name != "pyproject.toml") return
|
||||
val position = parameters.position
|
||||
val parent = position.parent
|
||||
|
||||
val key = parent.parentOfType<TomlKeyValue>()?.key?.name
|
||||
if (TOML_STRING_LITERALS.contains(position.elementType)
|
||||
&& parent.parent is TomlArray
|
||||
&& key in completionLocations) {
|
||||
val cache = service<PypiPackageCache>()
|
||||
val maxPriority = cache.packages.size
|
||||
cache.packages.asSequence()
|
||||
.map { LookupElementBuilder.create(it.lowercase()).withTypeText(PyBundle.message("python.pyproject.package.completion.tail")).withIcon(PythonIcons.Python.Python) }
|
||||
.mapIndexed { index, lookupElementBuilder ->
|
||||
PrioritizedLookupElement.withPriority(lookupElementBuilder, (maxPriority - index).toDouble())
|
||||
}
|
||||
.forEach { result.addElement(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.packaging.pyproject
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionTool
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.util.elementType
|
||||
import com.intellij.psi.util.parentOfType
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.packaging.PyRequirementParser
|
||||
import com.jetbrains.python.packaging.management.PythonPackageManager
|
||||
import com.jetbrains.python.packaging.management.isInstalled
|
||||
import com.jetbrains.python.sdk.pythonSdk
|
||||
import org.toml.lang.psi.*
|
||||
import org.toml.lang.psi.ext.name
|
||||
|
||||
class PyprojectPackageInspection : LocalInspectionTool() {
|
||||
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
|
||||
return object : TomlVisitor() {
|
||||
override fun visitLiteral(element: TomlLiteral) {
|
||||
if (element.parent is TomlArray && TOML_STRING_LITERALS.contains(element.firstChild.elementType)) {
|
||||
if (element.parentOfType<TomlKeyValue>()?.key?.name == "dependencies") {
|
||||
val elementText = element.text.removeSurrounding("'").removeSurrounding("\"")
|
||||
val requirement = PyRequirementParser.fromLine(elementText) ?: return
|
||||
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(element.originalElement) ?: return
|
||||
val packageManager = PythonPackageManager.forSdk(element.project, module.pythonSdk ?: return)
|
||||
|
||||
if (!packageManager.isInstalled(requirement.name)) {
|
||||
holder.registerProblem(element, PyBundle.message("python.pyproject.package.not.installed", requirement.name), PyInstallPackageQuickFix(requirement.name), PyInstallProjectAsEditableQuickfix())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.components.BaseState
|
||||
import com.intellij.util.xmlb.annotations.Transient
|
||||
import com.jetbrains.python.packaging.common.PythonPackageSpecification
|
||||
import com.jetbrains.python.packaging.common.PythonSimplePackageSpecification
|
||||
import com.jetbrains.python.packaging.requirement.PyRequirementRelation
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@@ -59,7 +60,8 @@ open class PyPackageRepository() : BaseState() {
|
||||
}
|
||||
|
||||
open fun createPackageSpecification(packageName: String,
|
||||
version: String? = null): PythonPackageSpecification {
|
||||
return PythonSimplePackageSpecification(packageName, version, this)
|
||||
version: String? = null,
|
||||
relation: PyRequirementRelation? = null): PythonPackageSpecification {
|
||||
return PythonSimplePackageSpecification(packageName, version, this, relation)
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import com.intellij.execution.target.TargetProgressIndicator
|
||||
import com.intellij.notification.NotificationGroupManager
|
||||
import com.intellij.notification.NotificationType
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
@@ -25,7 +24,6 @@ import com.intellij.openapi.roots.ModuleRootListener
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.childScope
|
||||
import com.jetbrains.python.PyBundle.*
|
||||
import com.jetbrains.python.PythonHelper
|
||||
import com.jetbrains.python.PythonHelpersLocator
|
||||
@@ -50,8 +48,8 @@ import kotlinx.coroutines.*
|
||||
import org.intellij.plugins.markdown.ui.preview.html.MarkdownUtil
|
||||
import org.jetbrains.annotations.Nls
|
||||
|
||||
@Service
|
||||
class PyPackagingToolWindowService(val project: Project) : Disposable {
|
||||
@Service(Service.Level.PROJECT)
|
||||
class PyPackagingToolWindowService(val project: Project, val serviceScope: CoroutineScope) : Disposable {
|
||||
|
||||
private var toolWindowPanel: PyPackagingToolWindowPanel? = null
|
||||
lateinit var manager: PythonPackageManager
|
||||
@@ -59,7 +57,6 @@ class PyPackagingToolWindowService(val project: Project) : Disposable {
|
||||
internal var currentSdk: Sdk? = null
|
||||
private var searchJob: Job? = null
|
||||
private var currentQuery: String = ""
|
||||
private val serviceScope = ApplicationManager.getApplication().coroutineScope.childScope(Dispatchers.Default)
|
||||
|
||||
private val invalidRepositories: List<PyInvalidRepositoryViewData>
|
||||
get() = service<PyPackageRepositories>().invalidRepositories.map(::PyInvalidRepositoryViewData)
|
||||
|
||||
Reference in New Issue
Block a user