mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 10:20:15 +07:00
PY-50160 Implement the redesigned dialog for package installation failures
IJ-CR-13328 GitOrigin-RevId: 2cfa6c468411391772639441f0d2aeda4fddc435
This commit is contained in:
committed by
intellij-monorepo-bot
parent
590618ec71
commit
18d0c28655
@@ -175,7 +175,12 @@ public class InstalledPackagesPanel extends JPanel {
|
||||
myPackagesTable.clearSelection();
|
||||
doUpdatePackages(myPackageManagementService);
|
||||
}
|
||||
});
|
||||
}, createNotificationPanel());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected PackagesNotificationPanel createNotificationPanel() {
|
||||
return new PackagesNotificationPanel();
|
||||
}
|
||||
|
||||
private void upgradeAction() {
|
||||
|
||||
@@ -78,6 +78,12 @@ public class ManagePackagesDialog extends DialogWrapper {
|
||||
|
||||
public ManagePackagesDialog(@NotNull Project project, final PackageManagementService packageManagementService,
|
||||
@Nullable final PackageManagementService.Listener packageListener) {
|
||||
this(project, packageManagementService, packageListener, new PackagesNotificationPanel());
|
||||
}
|
||||
|
||||
public ManagePackagesDialog(@NotNull Project project, final PackageManagementService packageManagementService,
|
||||
@Nullable final PackageManagementService.Listener packageListener,
|
||||
@NotNull final PackagesNotificationPanel notificationPanel) {
|
||||
super(project, true);
|
||||
myProject = project;
|
||||
myController = packageManagementService;
|
||||
@@ -86,7 +92,7 @@ public class ManagePackagesDialog extends DialogWrapper {
|
||||
init();
|
||||
setTitle(IdeBundle.message("available.packages.dialog.title"));
|
||||
myPackages = new JBList();
|
||||
myNotificationArea = new PackagesNotificationPanel();
|
||||
myNotificationArea = notificationPanel;
|
||||
myNotificationsAreaPlaceholder.add(myNotificationArea.getComponent(), BorderLayout.CENTER);
|
||||
|
||||
final AnActionButton reloadButton =
|
||||
|
||||
@@ -16,6 +16,7 @@ import javax.swing.event.HyperlinkEvent;
|
||||
import java.awt.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
|
||||
public class PackagesNotificationPanel {
|
||||
@@ -25,6 +26,10 @@ public class PackagesNotificationPanel {
|
||||
private PackageManagementService.ErrorDescription myErrorDescription;
|
||||
|
||||
public PackagesNotificationPanel() {
|
||||
this(PackagesNotificationPanel::showError);
|
||||
}
|
||||
|
||||
public PackagesNotificationPanel(@NotNull BiConsumer<String, PackageManagementService.ErrorDescription> showErrorFunction) {
|
||||
myHtmlViewer = SwingHelper.createHtmlViewer(true, null, null, null);
|
||||
myHtmlViewer.setVisible(false);
|
||||
myHtmlViewer.setOpaque(true);
|
||||
@@ -36,7 +41,7 @@ public class PackagesNotificationPanel {
|
||||
handler.run();
|
||||
}
|
||||
else if (myErrorTitle != null && myErrorDescription != null) {
|
||||
showError(myErrorTitle, myErrorDescription);
|
||||
showErrorFunction.accept(myErrorTitle, myErrorDescription);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -35,7 +35,7 @@ public class PyManagePackagesDialog extends DialogWrapper {
|
||||
final JComboBox sdkComboBox = new JComboBox(new CollectionComboBoxModel(sdks, sdk));
|
||||
sdkComboBox.setRenderer(new PySdkListCellRenderer());
|
||||
|
||||
PackagesNotificationPanel notificationPanel = new PackagesNotificationPanel();
|
||||
PackagesNotificationPanel notificationPanel = new PyPackagesNotificationPanel();
|
||||
final PyInstalledPackagesPanel packagesPanel = new PyInstalledPackagesPanel(project, notificationPanel);
|
||||
packagesPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
|
||||
packagesPanel.updatePackages(PyPackageManagers.getInstance().getManagementService(project, sdk));
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.webcore.packaging.PackagesNotificationPanel;
|
||||
import com.jetbrains.python.packaging.PyPackageManagers;
|
||||
import com.jetbrains.python.packaging.PyPackagesNotificationPanel;
|
||||
import com.jetbrains.python.packaging.ui.PyInstalledPackagesPanel;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -45,7 +46,7 @@ public class PythonSdkEditorAdditionalOptionsProvider extends SdkEditorAdditiona
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createComponent() {
|
||||
final PackagesNotificationPanel notificationsArea = new PackagesNotificationPanel();
|
||||
final PackagesNotificationPanel notificationsArea = new PyPackagesNotificationPanel();
|
||||
final JComponent notificationsComponent = notificationsArea.getComponent();
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
|
||||
@@ -18,6 +18,7 @@ python.sdk.packaging.package.management.for.python.not.supported=Package managem
|
||||
python.sdk.packaging.invalid.output.format=Invalid output format
|
||||
python.sdk.packaging.tools.not.found=Python packaging tools not found
|
||||
python.sdk.packaging.enter.your.password.to.make.changes=Please enter your password to make changes in system packages:
|
||||
python.sdk.packaging.unknown.package.data=Unknown
|
||||
python.sdk.use.python.version.supported.by.this.package=Make sure that you use a version of Python supported by this package. Currently, you are using Python {0}.
|
||||
python.sdk.check.python.development.packages.installed=Make sure that you have installed Python development packages for your operating system.
|
||||
python.sdk.try.to.run.command.from.system.terminal=Try to run this command from the system terminal. Make sure that you use the correct version of ''pip'' installed for your Python interpreter located at ''{0}''.
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.webcore.packaging.PackagesNotificationPanel;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.packaging.PyPackageManagers;
|
||||
import com.jetbrains.python.packaging.PyPackagesNotificationPanel;
|
||||
import com.jetbrains.python.packaging.ui.PyInstalledPackagesPanel;
|
||||
import com.jetbrains.python.sdk.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -104,7 +105,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
|
||||
|
||||
mySdkCombo = buildSdkComboBox(this::onShowAllSelected, this::onSdkSelected);
|
||||
|
||||
final PackagesNotificationPanel packagesNotificationPanel = new PackagesNotificationPanel();
|
||||
final PackagesNotificationPanel packagesNotificationPanel = new PyPackagesNotificationPanel();
|
||||
myPackagesPanel = new PyInstalledPackagesPanel(myProject, packagesNotificationPanel);
|
||||
myPackagesPanel.setShowGrid(false);
|
||||
|
||||
|
||||
@@ -36,18 +36,13 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.platform.DirectoryProjectGeneratorBase;
|
||||
import com.intellij.util.BooleanFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.webcore.packaging.PackageManagementService.ErrorDescription;
|
||||
import com.intellij.webcore.packaging.PackagesNotificationPanel;
|
||||
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.*;
|
||||
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
|
||||
import com.jetbrains.python.remote.*;
|
||||
import com.jetbrains.python.sdk.PyLazySdk;
|
||||
import com.jetbrains.python.sdk.PythonSdkUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -298,25 +293,31 @@ public abstract class PythonProjectGenerator<T extends PyNewProjectSettings> ext
|
||||
protected static void reportPackageInstallationFailure(@NotNull final String frameworkName,
|
||||
@Nullable final Pair<Sdk, ExecutionException> sdkAndException) {
|
||||
|
||||
final ErrorDescription errorDescription = getErrorDescription(sdkAndException);
|
||||
final PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription =
|
||||
getErrorDescription(sdkAndException, frameworkName);
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
app.invokeLater(() -> PackagesNotificationPanel.showError(PyBundle.message("python.new.project.install.failed.title", frameworkName),
|
||||
errorDescription));
|
||||
app.invokeLater(() -> {
|
||||
PyPackagesNotificationPanel.showPackageInstallationError(PyBundle.message("python.new.project.install.failed.title", frameworkName),
|
||||
errorDescription);
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ErrorDescription getErrorDescription(@Nullable final Pair<Sdk, ExecutionException> sdkAndException) {
|
||||
ErrorDescription errorDescription = null;
|
||||
private static PyPackageManagementService.PyPackageInstallationErrorDescription getErrorDescription(@Nullable final Pair<Sdk, ExecutionException> sdkAndException,
|
||||
@NotNull String packageName) {
|
||||
PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription = null;
|
||||
if (sdkAndException != null) {
|
||||
final ExecutionException exception = sdkAndException.second;
|
||||
errorDescription = PyPackageManagementService.toErrorDescription(Collections.singletonList(exception), sdkAndException.first);
|
||||
errorDescription =
|
||||
PyPackageManagementService.toErrorDescription(Collections.singletonList(exception), sdkAndException.first, packageName);
|
||||
if (errorDescription == null) {
|
||||
errorDescription = ErrorDescription.fromMessage(exception.getMessage());
|
||||
errorDescription = PyPackageManagementService.PyPackageInstallationErrorDescription.createFromMessage(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (errorDescription == null) {
|
||||
errorDescription = ErrorDescription.fromMessage(PyBundle.message("python.new.project.error.solution.another.sdk"));
|
||||
errorDescription = PyPackageManagementService.PyPackageInstallationErrorDescription.createFromMessage(
|
||||
PyBundle.message("python.new.project.error.solution.another.sdk"));
|
||||
}
|
||||
return errorDescription;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.python.packaging.PyPackageInstallationErrorDialog">
|
||||
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="6" column-count="9" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="10">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="2228" height="929"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<vspacer id="de4c">
|
||||
<constraints>
|
||||
<grid row="1" column="8" row-span="3" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="8cad" binding="myCommandOutputPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="9" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="4e743" class="com.intellij.ui.components.JBLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="6fb53"/>
|
||||
<text resource-bundle="messages/LangBundle" key="label.packaging.command.output"/>
|
||||
</properties>
|
||||
</component>
|
||||
<scrollpane id="6fb53" class="com.intellij.ui.components.JBScrollPane">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="700" height="300"/>
|
||||
<maximum-size width="700" height="300"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="307b8" class="javax.swing.JTextArea" binding="myCommandOutput">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<editable value="false"/>
|
||||
<lineWrap value="true"/>
|
||||
<text resource-bundle="messages/LangBundle" key="text.area.packaging.error.no.output"/>
|
||||
<wrapStyleWord value="true"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
</children>
|
||||
</grid>
|
||||
<component id="abb" class="com.intellij.ui.components.JBLabel" binding="packageName">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<anchor value=""/>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="d7910" class="com.intellij.ui.components.JBLabel" binding="pythonVersion">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<anchor value=""/>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
<clientProperties>
|
||||
<html.disable class="java.lang.Boolean" value="false"/>
|
||||
</clientProperties>
|
||||
</component>
|
||||
<component id="d745d" class="com.intellij.ui.components.JBLabel" binding="interpreterPath">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<anchor value=""/>
|
||||
<horizontalAlignment value="10"/>
|
||||
<text value=""/>
|
||||
<toolTipText value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="6573b" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Package:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="13f9b" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Interpreter path:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="73a40" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Python version:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="af132" class="javax.swing.JSeparator">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="9" vsize-policy="4" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<grid id="3c0fd" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="5" column="0" row-span="1" col-span="9" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="9b938" class="com.intellij.ui.components.JBLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<font style="1"/>
|
||||
<text value="Troubleshooting steps:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="de3ff">
|
||||
<constraints>
|
||||
<grid row="5" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="52088" class="com.intellij.ui.components.JBLabel" binding="myLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="<html><head></head><body><div>1. Try reading PyCharm guide on <a href="https://www.jetbrains.com/help/pycharm/package-installation-issues.html">troubleshooting package installation</a></div></body></html>"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="3dd1c" class="com.intellij.ui.components.JBLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="1" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="2. Try installing this package by running the following commands in the terminal."/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="c81ab" class="com.intellij.ui.components.JBLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="1" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="If the command crashes in the terminal, the problem is out of IDE control."/>
|
||||
</properties>
|
||||
</component>
|
||||
<scrollpane id="69c18" class="com.intellij.ui.components.JBScrollPane">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="700" height="50"/>
|
||||
<maximum-size width="700" height="50"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="3008a" class="javax.swing.JTextArea" binding="myCommandToTry" default-binding="true">
|
||||
<constraints/>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
</children>
|
||||
</grid>
|
||||
<hspacer id="94ada">
|
||||
<constraints>
|
||||
<grid row="3" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python.packaging;
|
||||
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.jetbrains.python.PySdkBundle;
|
||||
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
|
||||
import com.jetbrains.python.run.PyVirtualEnvReaderKt;
|
||||
import kotlin.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class PyPackageInstallationErrorDialog extends DialogWrapper {
|
||||
private JPanel myMainPanel;
|
||||
private JTextArea myCommandOutput;
|
||||
private JPanel myCommandOutputPanel;
|
||||
private JBLabel packageName;
|
||||
private JBLabel interpreterPath;
|
||||
private JBLabel pythonVersion;
|
||||
private JBLabel myLabel;
|
||||
private JTextArea myCommandToTry;
|
||||
|
||||
public PyPackageInstallationErrorDialog(@NotNull @NlsContexts.DialogTitle String title,
|
||||
@NotNull PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription) {
|
||||
super(false);
|
||||
init();
|
||||
setResizable(false);
|
||||
setTitle(title);
|
||||
final String output = errorDescription.getOutput();
|
||||
final String packageName = errorDescription.getPackageName();
|
||||
final String interpreterPath = errorDescription.getInterpreterPath();
|
||||
final String pythonVersion = errorDescription.getPythonVersion();
|
||||
final String command = errorDescription.getCommand();
|
||||
|
||||
String activate = null;
|
||||
if (errorDescription.getSdk() != null) {
|
||||
final Pair<String, String> activateScript = PyVirtualEnvReaderKt.findActivateScript(interpreterPath, null);
|
||||
if (activateScript != null) {
|
||||
final String activateScriptPath = activateScript.component1();
|
||||
final String condaEnvFolder = activateScript.component2();
|
||||
if (condaEnvFolder != null) {
|
||||
activate = "conda activate " + condaEnvFolder;
|
||||
}
|
||||
else if (activateScriptPath != null) {
|
||||
if (SystemInfo.isWindows) {
|
||||
activate = activateScriptPath;
|
||||
}
|
||||
else {
|
||||
activate = "source " + activateScriptPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
myCommandToTry.setText(activate != null ? activate + "\n" + command : command);
|
||||
myLabel.setCopyable(true);
|
||||
|
||||
myCommandOutputPanel.setVisible(output != null);
|
||||
if (output != null) {
|
||||
myCommandOutput.setText(output);
|
||||
}
|
||||
|
||||
this.packageName.setText(packageName != null ? packageName : PySdkBundle.message("python.sdk.packaging.unknown.package.data"));
|
||||
this.packageName.setCopyable(true);
|
||||
this.interpreterPath.setText(interpreterPath != null ? interpreterPath : PySdkBundle.message("python.sdk.packaging.unknown.package.data"));
|
||||
this.interpreterPath.setCopyable(true);
|
||||
this.pythonVersion.setText(pythonVersion != null ? pythonVersion : PySdkBundle.message("python.sdk.packaging.unknown.package.data"));
|
||||
this.pythonVersion.setCopyable(true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myMainPanel;
|
||||
}
|
||||
}
|
||||
@@ -31,10 +31,11 @@ import org.jetbrains.annotations.PropertyKey;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author vlan
|
||||
*/
|
||||
* @author vlan
|
||||
*/
|
||||
public final class PyPackageManagerUI {
|
||||
@NotNull private static final Logger LOG = Logger.getInstance(PyPackageManagerUI.class);
|
||||
|
||||
@@ -182,10 +183,16 @@ public final class PyPackageManagerUI {
|
||||
final Ref<Notification> notificationRef = new Ref<>(null);
|
||||
if (exceptions.isEmpty()) {
|
||||
notificationRef.set(new PackagingNotification(PACKAGING_GROUP_ID, getSuccessTitle(), getSuccessDescription(),
|
||||
NotificationType.INFORMATION, null));
|
||||
NotificationType.INFORMATION, null));
|
||||
}
|
||||
else {
|
||||
final PackageManagementService.ErrorDescription description = PyPackageManagementService.toErrorDescription(exceptions, mySdk);
|
||||
final List<String> requirements = this instanceof InstallTask && ((InstallTask)this).myRequirements != null
|
||||
? ContainerUtil.map(((InstallTask)this).myRequirements, req -> req.getName()) : null;
|
||||
final String packageNames = exceptions.stream()
|
||||
.flatMap(e -> (e instanceof PyExecutionException) ? ((PyExecutionException)e).getArgs().stream() : null)
|
||||
.filter(str -> str != null && requirements != null && requirements.contains(str)).collect(Collectors.joining(", "));
|
||||
final PyPackageManagementService.PyPackageInstallationErrorDescription description = PyPackageManagementService.
|
||||
toErrorDescription(exceptions, mySdk, packageNames);
|
||||
if (description != null) {
|
||||
final String firstLine = PyBundle.message("python.packaging.notification.title.error.occurred", getTitle());
|
||||
final NotificationListener listener = new NotificationListener() {
|
||||
@@ -194,12 +201,14 @@ public final class PyPackageManagerUI {
|
||||
@NotNull HyperlinkEvent event) {
|
||||
assert myProject != null;
|
||||
final String title = StringUtil.capitalizeWords(getFailureTitle(), true);
|
||||
PackagesNotificationPanel.showError(title, description);
|
||||
final PyPackageInstallationErrorDialog dialog =
|
||||
new PyPackageInstallationErrorDialog(title, description);
|
||||
dialog.show();
|
||||
}
|
||||
};
|
||||
String content = wrapIntoLink(firstLine, "python.packaging.notification.description.details.link");
|
||||
notificationRef.set(new PackagingNotification(PACKAGING_GROUP_ID, getFailureTitle(), content,
|
||||
NotificationType.ERROR, listener));
|
||||
NotificationType.ERROR, listener));
|
||||
}
|
||||
}
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
@@ -236,10 +245,10 @@ public final class PyPackageManagerUI {
|
||||
@NotNull private final List<String> myExtraArgs;
|
||||
|
||||
InstallTask(@Nullable Project project,
|
||||
@NotNull Sdk sdk,
|
||||
@Nullable List<PyRequirement> requirements,
|
||||
@NotNull List<String> extraArgs,
|
||||
@Nullable Listener listener) {
|
||||
@NotNull Sdk sdk,
|
||||
@Nullable List<PyRequirement> requirements,
|
||||
@NotNull List<String> extraArgs,
|
||||
@Nullable Listener listener) {
|
||||
super(project, sdk, PyBundle.message("python.packaging.progress.title.installing.packages"), listener);
|
||||
myRequirements = requirements;
|
||||
myExtraArgs = extraArgs;
|
||||
@@ -317,8 +326,8 @@ public final class PyPackageManagerUI {
|
||||
private static class InstallManagementTask extends InstallTask {
|
||||
|
||||
InstallManagementTask(@Nullable Project project,
|
||||
@NotNull Sdk sdk,
|
||||
@Nullable Listener listener) {
|
||||
@NotNull Sdk sdk,
|
||||
@Nullable Listener listener) {
|
||||
super(project, sdk, Collections.emptyList(), Collections.emptyList(), listener);
|
||||
}
|
||||
|
||||
@@ -350,9 +359,9 @@ public final class PyPackageManagerUI {
|
||||
@NotNull private final List<PyPackage> myPackages;
|
||||
|
||||
UninstallTask(@Nullable Project project,
|
||||
@NotNull Sdk sdk,
|
||||
@Nullable Listener listener,
|
||||
@NotNull List<PyPackage> packages) {
|
||||
@NotNull Sdk sdk,
|
||||
@Nullable Listener listener,
|
||||
@NotNull List<PyPackage> packages) {
|
||||
super(project, sdk, PyBundle.message("python.packaging.progress.title.uninstalling.packages"), listener);
|
||||
myPackages = packages;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python.packaging;
|
||||
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.webcore.packaging.PackageManagementService;
|
||||
import com.intellij.webcore.packaging.PackagesNotificationPanel;
|
||||
import com.intellij.webcore.packaging.PackagingErrorDialog;
|
||||
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public class PyPackagesNotificationPanel extends PackagesNotificationPanel {
|
||||
|
||||
public PyPackagesNotificationPanel() {
|
||||
super(PyPackagesNotificationPanel::showPackageInstallationError);
|
||||
}
|
||||
|
||||
public static void showPackageInstallationError(@NotNull @NlsContexts.DialogTitle String title,
|
||||
@NotNull PackageManagementService.ErrorDescription description) {
|
||||
if (description instanceof PyPackageManagementService.PyPackageInstallationErrorDescription) {
|
||||
final PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription =
|
||||
(PyPackageManagementService.PyPackageInstallationErrorDescription)description;
|
||||
final PyPackageInstallationErrorDialog dialog = new PyPackageInstallationErrorDialog(title, errorDescription);
|
||||
dialog.show();
|
||||
} else {
|
||||
final PackagingErrorDialog dialog = new PackagingErrorDialog(title, description);
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.text.HtmlBuilder;
|
||||
import com.intellij.ui.ToggleActionButton;
|
||||
import com.intellij.webcore.packaging.InstalledPackage;
|
||||
import com.intellij.webcore.packaging.InstalledPackagesPanel;
|
||||
import com.intellij.webcore.packaging.PackageManagementService;
|
||||
import com.intellij.webcore.packaging.PackagesNotificationPanel;
|
||||
import com.intellij.webcore.packaging.*;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PySdkBundle;
|
||||
import com.jetbrains.python.packaging.*;
|
||||
@@ -68,9 +65,11 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
|
||||
public void finished(List<ExecutionException> exceptions) {
|
||||
myPackagesTable.setPaintBusy(false);
|
||||
PyPackageManager packageManager = PyPackageManager.getInstance(sdk);
|
||||
final PackageManagementService.ErrorDescription description = PyPackageManagementService.toErrorDescription(exceptions, sdk);
|
||||
final PyPackageManagementService.PyPackageInstallationErrorDescription description =
|
||||
PyPackageManagementService.toErrorDescription(exceptions, sdk, "packaging tools");
|
||||
if (description != null) {
|
||||
PackagesNotificationPanel.showError(PyBundle.message("python.packaging.failed.to.install.packaging.tools.title"), description);
|
||||
PyPackagesNotificationPanel.showPackageInstallationError(
|
||||
PyBundle.message("python.packaging.failed.to.install.packaging.tools.title"), description);
|
||||
}
|
||||
packageManager.refresh();
|
||||
updatePackages(PyPackageManagers.getInstance().getManagementService(myProject, sdk));
|
||||
@@ -93,7 +92,8 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
|
||||
myHasManagement = PyPackageManager.getInstance(selectedSdk).hasManagement();
|
||||
application.invokeLater(() -> updateUninstallUpgrade(), ModalityState.any());
|
||||
if (!myHasManagement) {
|
||||
throw new PyExecutionException(PySdkBundle.message("python.sdk.packaging.tools.not.found"), "pip", Collections.emptyList(), "", "", 0,
|
||||
throw new PyExecutionException(PySdkBundle.message("python.sdk.packaging.tools.not.found"), "pip", Collections.emptyList(), "",
|
||||
"", 0,
|
||||
ImmutableList.of(new PyInstallPackageManagementFix()));
|
||||
}
|
||||
}
|
||||
@@ -185,31 +185,33 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
|
||||
|
||||
@Override
|
||||
protected ToggleActionButton @NotNull [] getExtraActions() {
|
||||
final ToggleActionButton useCondaButton = new DumbAwareToggleActionButton(PyBundle.messagePointer("action.AnActionButton.text.use.conda.package.manager"), PythonIcons.Python.Anaconda) {
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
final Sdk sdk = getSelectedSdk();
|
||||
return sdk != null && PyPackageManager.getInstance(sdk) instanceof PyCondaPackageManagerImpl &&
|
||||
((PyCondaPackageManagerImpl)PyPackageManager.getInstance(sdk)).useConda();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
final Sdk sdk = getSelectedSdk();
|
||||
if (sdk == null) return;
|
||||
final PyPackageManager manager = PyPackageManager.getInstance(sdk);
|
||||
if (manager instanceof PyCondaPackageManagerImpl) {
|
||||
((PyCondaPackageManagerImpl)manager).useConda(state);
|
||||
final ToggleActionButton useCondaButton =
|
||||
new DumbAwareToggleActionButton(PyBundle.messagePointer("action.AnActionButton.text.use.conda.package.manager"),
|
||||
PythonIcons.Python.Anaconda) {
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
final Sdk sdk = getSelectedSdk();
|
||||
return sdk != null && PyPackageManager.getInstance(sdk) instanceof PyCondaPackageManagerImpl &&
|
||||
((PyCondaPackageManagerImpl)PyPackageManager.getInstance(sdk)).useConda();
|
||||
}
|
||||
updatePackages(myPackageManagementService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
final Sdk sdk = getSelectedSdk();
|
||||
return sdk != null && PythonSdkUtil.isConda(sdk);
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
final Sdk sdk = getSelectedSdk();
|
||||
if (sdk == null) return;
|
||||
final PyPackageManager manager = PyPackageManager.getInstance(sdk);
|
||||
if (manager instanceof PyCondaPackageManagerImpl) {
|
||||
((PyCondaPackageManagerImpl)manager).useConda(state);
|
||||
}
|
||||
updatePackages(myPackageManagementService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
final Sdk sdk = getSelectedSdk();
|
||||
return sdk != null && PythonSdkUtil.isConda(sdk);
|
||||
}
|
||||
};
|
||||
|
||||
final ToggleActionButton showEarlyReleasesButton =
|
||||
new DumbAwareToggleActionButton(PyBundle.messagePointer("action.AnActionButton.text.show.early.releases"), AllIcons.Actions.Show) {
|
||||
@@ -233,4 +235,9 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
|
||||
super(text, icon);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull PackagesNotificationPanel createNotificationPanel() {
|
||||
return new PyPackagesNotificationPanel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.RunCanceledByUserException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.openapi.util.NlsContexts.DetailedDescription;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.scale.JBUIScale;
|
||||
@@ -156,8 +158,9 @@ public class PyPackageManagementService extends PackageManagementServiceEx {
|
||||
@Override
|
||||
public String getInstallToUserText() {
|
||||
String userSiteText = PyBundle.message("button.install.to.user.site.packages.directory");
|
||||
if (!PythonSdkUtil.isRemote(mySdk))
|
||||
if (!PythonSdkUtil.isRemote(mySdk)) {
|
||||
userSiteText += " (" + PythonSdkUtil.getUserSite() + ")";
|
||||
}
|
||||
return userSiteText;
|
||||
}
|
||||
|
||||
@@ -179,8 +182,12 @@ public class PyPackageManagementService extends PackageManagementServiceEx {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installPackage(@NotNull RepoPackage repoPackage, @Nullable String version, boolean forceUpgrade, @Nullable String extraOptions,
|
||||
@NotNull Listener listener, boolean installToUser) {
|
||||
public void installPackage(@NotNull RepoPackage repoPackage,
|
||||
@Nullable String version,
|
||||
boolean forceUpgrade,
|
||||
@Nullable String extraOptions,
|
||||
@NotNull Listener listener,
|
||||
boolean installToUser) {
|
||||
final String packageName = repoPackage.getName();
|
||||
final String repository = PyPIPackageUtil.isPyPIRepository(repoPackage.getRepoUrl()) ? null : repoPackage.getRepoUrl();
|
||||
final List<String> extraArgs = new ArrayList<>();
|
||||
@@ -210,7 +217,7 @@ public class PyPackageManagementService extends PackageManagementServiceEx {
|
||||
|
||||
@Override
|
||||
public void finished(@Nullable List<ExecutionException> exceptions) {
|
||||
listener.operationFinished(packageName, toErrorDescription(exceptions, mySdk));
|
||||
listener.operationFinished(packageName, toErrorDescription(exceptions, mySdk, repoPackage.getName()));
|
||||
}
|
||||
});
|
||||
ui.install(Collections.singletonList(req), extraArgs);
|
||||
@@ -218,8 +225,15 @@ public class PyPackageManagementService extends PackageManagementServiceEx {
|
||||
|
||||
@Nullable
|
||||
public static ErrorDescription toErrorDescription(@Nullable List<ExecutionException> exceptions, @Nullable Sdk sdk) {
|
||||
return toErrorDescription(exceptions, sdk, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyPackageInstallationErrorDescription toErrorDescription(@Nullable List<ExecutionException> exceptions,
|
||||
@Nullable Sdk sdk,
|
||||
@Nullable String packageName) {
|
||||
if (exceptions != null && !exceptions.isEmpty() && !isCancelled(exceptions)) {
|
||||
return createDescription(exceptions.get(0), sdk);
|
||||
return createDescription(exceptions.get(0), sdk, packageName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -316,18 +330,21 @@ public class PyPackageManagementService extends PackageManagementServiceEx {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ErrorDescription createDescription(@NotNull ExecutionException e, @Nullable Sdk sdk) {
|
||||
private static PyPackageInstallationErrorDescription createDescription(@NotNull ExecutionException e,
|
||||
@Nullable Sdk sdk,
|
||||
@Nullable String packageName) {
|
||||
if (e instanceof PyExecutionException) {
|
||||
final PyExecutionException ee = (PyExecutionException)e;
|
||||
final String stdoutCause = findErrorCause(ee.getStdout());
|
||||
final String stderrCause = findErrorCause(ee.getStderr());
|
||||
final String cause = stdoutCause != null ? stdoutCause : stderrCause;
|
||||
final String message = cause != null ? cause : ee.getMessage();
|
||||
final String message = cause != null ? cause : ee.getMessage();
|
||||
final String command = ee.getCommand() + " " + StringUtil.join(ee.getArgs(), " ");
|
||||
return new ErrorDescription(message, command, ee.getStdout() + "\n" + ee.getStderr(), findErrorSolution(ee, cause, sdk));
|
||||
return new PyPackageInstallationErrorDescription(message, command, ee.getStdout() + "\n" + ee.getStderr(),
|
||||
findErrorSolution(ee, cause, sdk), packageName, sdk);
|
||||
}
|
||||
else {
|
||||
return ErrorDescription.fromMessage(e.getMessage());
|
||||
return new PyPackageInstallationErrorDescription(e.getMessage(), null, null, null, packageName, sdk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,4 +422,45 @@ public class PyPackageManagementService extends PackageManagementServiceEx {
|
||||
public String getID() {
|
||||
return "Python";
|
||||
}
|
||||
|
||||
public static class PyPackageInstallationErrorDescription extends ErrorDescription {
|
||||
@Nullable private final String myPackageName;
|
||||
@Nullable private final String myPythonVersion;
|
||||
@Nullable private final String myInterpreterPath;
|
||||
@Nullable private final Sdk mySdk;
|
||||
|
||||
public PyPackageInstallationErrorDescription(@NotNull @DetailedDescription String message,
|
||||
@Nullable String command,
|
||||
@Nullable String output,
|
||||
@Nullable @DetailedDescription String solution,
|
||||
@Nullable String packageName,
|
||||
@Nullable Sdk sdk) {
|
||||
super(message, command, output, solution);
|
||||
myPackageName = packageName;
|
||||
mySdk = sdk;
|
||||
myPythonVersion = sdk != null ? sdk.getVersionString() : null;
|
||||
myInterpreterPath = sdk != null ? sdk.getHomePath() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyPackageInstallationErrorDescription createFromMessage(@Nullable @NlsContexts.DetailedDescription String message) {
|
||||
return message != null ? new PyPackageInstallationErrorDescription(message, null, null, null, null, null) : null;
|
||||
}
|
||||
|
||||
public @Nullable @NlsSafe String getPackageName() {
|
||||
return myPackageName;
|
||||
}
|
||||
|
||||
public @Nullable @NlsSafe String getPythonVersion() {
|
||||
return myPythonVersion;
|
||||
}
|
||||
|
||||
public @Nullable @NlsSafe String getInterpreterPath() {
|
||||
return myInterpreterPath;
|
||||
}
|
||||
|
||||
public @Nullable Sdk getSdk() {
|
||||
return mySdk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user