fix notification for installing packages via quickfix; #PY-72070 Fixed

(cherry picked from commit bee8b1c0431c186658c11b2f0fb33f4c26f95fee)

GitOrigin-RevId: 14417efa3be6f4785fbdf1b05505c7efd09f3a20
This commit is contained in:
Aleksandr Sorotskii
2025-01-09 19:06:02 +01:00
committed by intellij-monorepo-bot
parent c57369d4d2
commit 2873bad618
2 changed files with 42 additions and 28 deletions

View File

@@ -23,6 +23,7 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.packaging.management.PythonPackagesInstaller;
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -259,18 +260,23 @@ public final class PyPackageManagerUI {
@Override
protected @NotNull List<ExecutionException> runTask(@NotNull ProgressIndicator indicator) {
final List<ExecutionException> exceptions = new ArrayList<>();
if (myProject == null) {
// FIXME: proper error
return exceptions;
}
PythonPackagesInstallerAsync.Companion.installPackages(
var result = PythonPackagesInstaller.Companion.installPackages(
myProject,
myRequirements,
myExtraArgs,
indicator
);
// FIXME: use packaging tool window service for managing error dialog
if (result != null) {
exceptions.add(result);
}
return exceptions;
}

View File

@@ -1,62 +1,77 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.packaging
import com.intellij.execution.ExecutionException
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.runBlockingCancellable
import com.intellij.openapi.project.Project
import com.jetbrains.python.PyBundle
import com.jetbrains.python.packaging.common.PythonPackageSpecification
import com.jetbrains.python.packaging.PyRequirement
import com.jetbrains.python.packaging.common.PythonPackageSpecificationBase
import com.jetbrains.python.packaging.common.PythonSimplePackageSpecification
import com.jetbrains.python.packaging.toolwindow.PyPackagingToolWindowService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class PythonPackagesInstallerAsync {
class PythonPackagesInstaller {
companion object {
@JvmStatic
fun installPackages(
project: Project,
requirements: List<PyRequirement>?,
extraArgs: List<String>,
indicator: ProgressIndicator,
) {
val packageService = PyPackagingToolWindowService.getInstance(project)
): ExecutionException? {
runBlockingCancellable {
val manager = PythonPackageManager.forSdk(project, sdk)
// FIXME: encapsulate into forSdk
manager.repositoryManager.refreshCashes()
packageService.serviceScope.launch(Dispatchers.IO) {
if (requirements.isNullOrEmpty()) {
installWithoutRequirements(packageService, extraArgs, indicator)
return@runBlockingCancellable if (requirements.isNullOrEmpty()) {
installWithoutRequirements(manager, extraArgs, indicator)
}
else {
installWithRequirements(packageService, requirements, extraArgs, indicator)
installWithRequirements(manager, requirements, extraArgs, indicator)
}
}.exceptionOrNull()?.let {
return ExecutionException(it)
}
return null
}
private suspend fun installWithoutRequirements(
packageService: PyPackagingToolWindowService,
manager: PythonPackageManager,
extraArgs: List<String>,
indicator: ProgressIndicator,
) {
): Result<Unit> {
indicator.text = PyBundle.message("python.packaging.installing.packages")
indicator.isIndeterminate = true
// LAME: extra args seems to be package names - convert them
val emptySpecification = PythonPackageSpecificationBase("", null, null, null)
packageService.installPackage(emptySpecification, extraArgs)
manager.installPackage(emptySpecification, extraArgs).getOrElse {
return Result.failure(it)
}
return Result.success(Unit)
}
private suspend fun installWithRequirements(
packageService: PyPackagingToolWindowService,
manager: PythonPackageManager,
requirements: List<PyRequirement>,
extraArgs: List<String>,
indicator: ProgressIndicator,
) {
): Result<Unit> {
requirements.forEachIndexed { index, requirement ->
indicator.text = PyBundle.message("python.packaging.progress.text.installing.specific.package", requirement.presentableText)
updateProgress(indicator, index, requirements.size)
val specification = createSpecificationForRequirement(requirement)
packageService.installPackage(specification, extraArgs)
// FIXME: pass version???
val specification = PythonSimplePackageSpecification(requirement.name, null, null)
manager.installPackage(specification, extraArgs).onFailure {
return Result.failure(it)
}
}
return Result.success(Unit)
}
private fun updateProgress(indicator: ProgressIndicator, index: Int, total: Int) {
@@ -65,12 +80,5 @@ class PythonPackagesInstallerAsync {
indicator.fraction = index.toDouble() / total
}
}
private fun createSpecificationForRequirement(
requirement: PyRequirement,
): PythonPackageSpecification {
val packageName = requirement.name
return PythonSimplePackageSpecification(packageName, null, null)
}
}
}