mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-78749 Packages: refactor install(String) from PyPM
Signed-off-by: Nikita.Ashihmin <nikita.ashihmin@jetbrains.com> GitOrigin-RevId: 7d537581c6190d7a434d162854ac5db739909c59
This commit is contained in:
committed by
intellij-monorepo-bot
parent
05c98fc8d6
commit
50d6856ce5
@@ -3,9 +3,7 @@ package com.jetbrains.python.packaging;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.util.messages.Topic;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -18,7 +16,6 @@ import java.util.List;
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public abstract class PyPackageManager implements Disposable {
|
||||
public static final Key<Boolean> RUNNING_PACKAGING_TASKS = Key.create("PyPackageRequirementsInspection.RunningPackagingTasks");
|
||||
|
||||
public static final String USE_USER_SITE = "--user";
|
||||
@Topic.AppLevel
|
||||
@@ -62,8 +59,6 @@ public abstract class PyPackageManager implements Disposable {
|
||||
|
||||
public abstract boolean hasManagement() throws ExecutionException;
|
||||
|
||||
public abstract void install(@NotNull String requirementString) throws ExecutionException;
|
||||
|
||||
public abstract void install(@Nullable List<PyRequirement> requirements, @NotNull List<String> extraArgs) throws ExecutionException;
|
||||
|
||||
public abstract void uninstall(@NotNull List<PyPackage> packages) throws ExecutionException;
|
||||
@@ -76,8 +71,6 @@ public abstract class PyPackageManager implements Disposable {
|
||||
|
||||
public abstract @NotNull List<PyPackage> refreshAndGetPackages(boolean alwaysRefresh) throws ExecutionException;
|
||||
|
||||
public abstract @Nullable List<PyRequirement> getRequirements(@NotNull Module module);
|
||||
|
||||
public interface Listener {
|
||||
void packagesRefreshed(@NotNull Sdk sdk);
|
||||
}
|
||||
|
||||
@@ -2,35 +2,20 @@
|
||||
package com.jetbrains.python.newProject;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyPsiPackageUtil;
|
||||
import com.jetbrains.python.packaging.PyPackage;
|
||||
import com.jetbrains.python.packaging.PyPackageManager;
|
||||
import com.jetbrains.python.packaging.PyPackageUtil;
|
||||
import com.jetbrains.python.packaging.PyPackagesNotificationPanel;
|
||||
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
|
||||
import com.jetbrains.python.sdk.PreferredSdkComparator;
|
||||
import com.jetbrains.python.sdk.PySdkExtKt;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import com.jetbrains.python.sdk.PythonSdkUtil;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
|
||||
/**
|
||||
@@ -43,20 +28,6 @@ import java.util.concurrent.Future;
|
||||
public final class DeprecatedUtils {
|
||||
private DeprecatedUtils() {
|
||||
}
|
||||
/**
|
||||
* @param sdkAndException if you have SDK and execution exception provide them here (both must not be null).
|
||||
*/
|
||||
private static void reportPackageInstallationFailure(final @NotNull String frameworkName,
|
||||
final @Nullable Pair<Sdk, ExecutionException> sdkAndException) {
|
||||
|
||||
final PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription =
|
||||
getErrorDescription(sdkAndException, frameworkName);
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
app.invokeLater(() -> {
|
||||
PyPackagesNotificationPanel.showPackageInstallationError(PyBundle.message("python.new.project.install.failed.title", frameworkName),
|
||||
errorDescription);
|
||||
});
|
||||
}
|
||||
|
||||
private static @NotNull PyPackageManagementService.PyPackageInstallationErrorDescription getErrorDescription(final @Nullable Pair<Sdk, ExecutionException> sdkAndException,
|
||||
@NotNull String packageName) {
|
||||
@@ -80,90 +51,6 @@ public final class DeprecatedUtils {
|
||||
|
||||
//TODO: Support for plugin also
|
||||
|
||||
/**
|
||||
* Installs framework and runs callback on success.
|
||||
* Installation runs in modal dialog and callback is posted to AWT thread.
|
||||
* <p>
|
||||
* If "forceInstallFramework" is passed then installs framework in any case.
|
||||
* If SDK is remote then checks if it has interpreter and installs if missing
|
||||
*
|
||||
* @param frameworkName user-readable framework name (i.e. "Django")
|
||||
* @param requirement name of requirement to install (i.e. "django")
|
||||
* @param forceInstallFramework pass true if you are sure required framework is missing
|
||||
* @param callback to be called after installation (or instead of is framework is installed) on AWT thread
|
||||
* @return future to be used instead of callback.
|
||||
*/
|
||||
public static @NotNull Future<Void> installFrameworkIfNeeded(final @NotNull Project project,
|
||||
final @NotNull String frameworkName,
|
||||
final @NotNull String requirement,
|
||||
final @NotNull Sdk sdk,
|
||||
final boolean forceInstallFramework,
|
||||
final @Nullable Runnable callback) {
|
||||
|
||||
var future = new CompletableFuture<Void>();
|
||||
|
||||
// For remote SDK we are not sure if framework exists or not, so we'll check it anyway
|
||||
if (forceInstallFramework || PythonSdkUtil.isRemote(sdk)) {
|
||||
|
||||
ProgressManager.getInstance()
|
||||
.run(new Task.Modal(project, PyBundle.message("python.install.framework.ensure.installed", frameworkName), false) {
|
||||
@Override
|
||||
public void run(final @NotNull ProgressIndicator indicator) {
|
||||
installPackages(frameworkName, forceInstallFramework, indicator, requirement, sdk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThrowable(@NotNull Throwable error) {
|
||||
future.completeExceptionally(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
future.complete(null);
|
||||
// Installed / checked successfully, call callback on AWT
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
future.complete(null);
|
||||
// No need to install, but still need to call callback on AWT
|
||||
if (callback != null) {
|
||||
assert SwingUtilities.isEventDispatchThread();
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
private static void installPackages(final @NotNull String frameworkName,
|
||||
boolean forceInstallFramework,
|
||||
@NotNull ProgressIndicator indicator,
|
||||
final @NotNull String requirement,
|
||||
final @NotNull Sdk sdk) {
|
||||
final PyPackageManager packageManager = PyPackageManager.getInstance(sdk);
|
||||
boolean installed = false;
|
||||
if (!forceInstallFramework) {
|
||||
// First check if we need to do it
|
||||
indicator.setText(PyBundle.message("python.install.framework.checking.is.installed", frameworkName));
|
||||
final List<PyPackage> packages = PyPackageUtil.refreshAndGetPackagesModally(sdk);
|
||||
installed = PyPsiPackageUtil.findPackage(packages, requirement) != null;
|
||||
}
|
||||
|
||||
if (!installed) {
|
||||
indicator.setText(PyBundle.message("python.install.framework.installing", frameworkName));
|
||||
try {
|
||||
packageManager.install(requirement);
|
||||
packageManager.refresh();
|
||||
}
|
||||
catch (final ExecutionException e) {
|
||||
reportPackageInstallationFailure(requirement, Pair.create(sdk, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Migrate to interpreter service
|
||||
public static @NotNull List<Sdk> getValidPythonSdks(@NotNull List<Sdk> existingSdks) {
|
||||
return StreamEx
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.jetbrains.python.packaging
|
||||
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.progress.runBlockingMaybeCancellable
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.openapi.project.getOpenedProjects
|
||||
@@ -68,9 +67,5 @@ internal open class PyPackageManagerBridge(sdk: Sdk) : PyTargetEnvironmentPackag
|
||||
return packageManagerUI.manager.listInstalledPackagesSnapshot().map { PyPackage(it.name, it.version) }
|
||||
}
|
||||
|
||||
override fun getRequirements(module: Module): List<PyRequirement>? {
|
||||
return packageManager.getDependencyManager()?.getDependencies()
|
||||
}
|
||||
|
||||
private fun guessProject() = getOpenedProjects().firstOrNull() ?: ProjectManager.getInstance().defaultProject
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ import static com.jetbrains.python.sdk.PySdkExtKt.showSdkExecutionException;
|
||||
* @deprecated This class and all its inheritors are deprecated. Everything should work via {@link PyTargetEnvironmentPackageManager}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class PyPackageManagerImpl extends PyPackageManagerImplBase {
|
||||
public abstract class PyPackageManagerImpl extends PyPackageManagerImplBase {
|
||||
private static final Logger LOG = Logger.getInstance(PyPackageManagerImpl.class);
|
||||
|
||||
@Override
|
||||
@@ -61,11 +61,6 @@ public class PyPackageManagerImpl extends PyPackageManagerImplBase {
|
||||
super(sdk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void install(@NotNull String requirementString) throws ExecutionException {
|
||||
install(Collections.singletonList(PyRequirementParser.fromLine(requirementString)), Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void install(@Nullable List<PyRequirement> requirements, @NotNull List<String> extraArgs) throws ExecutionException {
|
||||
install(requirements, extraArgs, null);
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -31,7 +30,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -166,13 +168,6 @@ public abstract class PyPackageManagerImplBase extends PyPackageManager {
|
||||
return PythonSdkType.getLanguageLevelForSdk(sdk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<PyRequirement> getRequirements(@NotNull Module module) {
|
||||
return Optional
|
||||
.ofNullable(PyPackageUtil.getRequirementsFromTxt(module))
|
||||
.orElseGet(() -> PyPackageUtil.findSetupPyRequires(module));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<PyPackage> refreshAndGetPackages(boolean alwaysRefresh) throws ExecutionException {
|
||||
final List<PyPackage> currentPackages = myPackagesCache;
|
||||
|
||||
@@ -69,11 +69,6 @@ public abstract class PyTargetEnvironmentPackageManager extends PyPackageManager
|
||||
super(sdk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void install(@NotNull String requirementString) throws ExecutionException {
|
||||
install(Collections.singletonList(PyRequirementParser.fromLine(requirementString)), Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void install(@Nullable List<PyRequirement> requirements, @NotNull List<String> extraArgs) throws ExecutionException {
|
||||
install(requirements, extraArgs, null);
|
||||
|
||||
@@ -46,7 +46,7 @@ class PythonPackageManagerUI(val manager: PythonPackageManager, val sink: ErrorS
|
||||
/**
|
||||
* @return List of all installed packages or null if the operation was failed.
|
||||
*/
|
||||
suspend fun installPackagesBackground(
|
||||
suspend fun installPackagesRequestBackground(
|
||||
installRequest: PythonPackageInstallRequest,
|
||||
options: List<String> = emptyList(),
|
||||
): List<PythonPackage>? {
|
||||
|
||||
+17
-2
@@ -68,8 +68,23 @@ suspend fun PythonPackageManagerUI.installPyRequirementsBackground(
|
||||
val specifications = packages.mapNotNull {
|
||||
manager.findPackageSpecificationWithVersionSpec(it.name, it.versionSpecs.firstOrNull())
|
||||
}
|
||||
return installPackagesBackground(PythonPackageInstallRequest.ByRepositoryPythonPackageSpecifications(specifications),
|
||||
options = options)
|
||||
return installPackagesRequestBackground(PythonPackageInstallRequest.ByRepositoryPythonPackageSpecifications(specifications),
|
||||
options = options)
|
||||
}
|
||||
|
||||
|
||||
@ApiStatus.Internal
|
||||
suspend fun PythonPackageManagerUI.installPackagesBackground(
|
||||
packages: List<String>,
|
||||
options: List<String> = emptyList(),
|
||||
): List<PythonPackage>? {
|
||||
//Wait here to load spec
|
||||
manager.waitForInit()
|
||||
val specifications = packages.mapNotNull {
|
||||
manager.findPackageSpecificationWithVersionSpec(it, null)
|
||||
}
|
||||
return installPackagesRequestBackground(PythonPackageInstallRequest.ByRepositoryPythonPackageSpecifications(specifications),
|
||||
options = options)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-3
@@ -51,7 +51,7 @@ class PyPackagingToolWindowService(val project: Project, val serviceScope: Corou
|
||||
internal var currentSdk: Sdk? = null
|
||||
private lateinit var managerUI: PythonPackageManagerUI
|
||||
|
||||
private val manager: PythonPackageManager?
|
||||
private val manager: PythonPackageManager
|
||||
get() = managerUI.manager
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ class PyPackagingToolWindowService(val project: Project, val serviceScope: Corou
|
||||
|
||||
suspend fun installPackage(installRequest: PythonPackageInstallRequest, options: List<String> = emptyList()) {
|
||||
PythonPackagesToolwindowStatisticsCollector.installPackageEvent.log(project)
|
||||
managerUI.installPackagesBackground(installRequest, options)?.let {
|
||||
managerUI.installPackagesRequestBackground(installRequest, options)?.let {
|
||||
handleActionCompleted(message("python.packaging.notification.installed", installRequest.title))
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,7 @@ class PyPackagingToolWindowService(val project: Project, val serviceScope: Corou
|
||||
suspend fun installPackage(pkg: PythonPackage, options: List<String> = emptyList()) {
|
||||
val installRequest = manager?.findPackageSpecification(pkg.name, pkg.version)?.toInstallRequest() ?: return
|
||||
PythonPackagesToolwindowStatisticsCollector.installPackageEvent.log(project)
|
||||
managerUI.installPackagesBackground(installRequest, options)?.let {
|
||||
managerUI.installPackagesRequestBackground(installRequest, options)?.let {
|
||||
handleActionCompleted(message("python.packaging.notification.installed", installRequest.title))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
import com.jetbrains.python.extensions.getSdk
|
||||
import com.jetbrains.python.packaging.PyPIPackageCache
|
||||
import com.jetbrains.python.packaging.PyPackageManager
|
||||
import com.jetbrains.python.packaging.management.PythonPackageManager
|
||||
import com.jetbrains.python.packaging.normalizePackageName
|
||||
import com.jetbrains.python.sdk.PythonSdkAdditionalData
|
||||
@@ -49,7 +48,8 @@ internal class PyPackageVersionUsagesCollector : ProjectUsagesCollector() {
|
||||
val sdk = module.getSdk() ?: continue
|
||||
if (!PythonSdkUtil.isPythonSdk(sdk)) continue
|
||||
val usageData = getPythonSpecificInfo(sdk)
|
||||
PyPackageManager.getInstance(sdk).getRequirements(module).orEmpty()
|
||||
val requirements = PythonPackageManager.forSdk(project, sdk).getDependencyManager()?.getDependencies().orEmpty()
|
||||
requirements
|
||||
.filter { pypiPackages.containsPackage(it.name) }
|
||||
.forEach { req ->
|
||||
ProgressManager.checkCanceled()
|
||||
|
||||
Reference in New Issue
Block a user