mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
added initial conda support
This commit is contained in:
@@ -522,6 +522,7 @@ public class ManagePackagesDialog extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
public void consume(Exception exception) {
|
||||
myDescriptionTextArea.setText("No information available");
|
||||
LOG.info("Error retrieving package details", exception);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
ERROR_WRONG_USAGE = 1
|
||||
ERROR_EXCEPTION = 4
|
||||
|
||||
def usage():
|
||||
sys.stderr.write('Usage: conda_packaging_tool.py <listall>\n')
|
||||
sys.stderr.flush()
|
||||
exit(ERROR_WRONG_USAGE)
|
||||
|
||||
def do_list_available_packages():
|
||||
from conda.cli.main_search import common
|
||||
index = common.get_index_trap()
|
||||
for pkg in index.values():
|
||||
sys.stdout.write("\t".join([pkg["name"], pkg["version"], ":".join(pkg["depends"])])+chr(10))
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def do_list_channels():
|
||||
import conda.config as config
|
||||
for channel in config.get_channel_urls():
|
||||
sys.stdout.write(channel+chr(10))
|
||||
sys.stdout.flush()
|
||||
|
||||
def main():
|
||||
retcode = 0
|
||||
try:
|
||||
if len(sys.argv) < 2:
|
||||
usage()
|
||||
cmd = sys.argv[1]
|
||||
if cmd == 'listall':
|
||||
if len(sys.argv) != 2:
|
||||
usage()
|
||||
return
|
||||
do_list_available_packages()
|
||||
elif cmd == 'channels':
|
||||
if len(sys.argv) != 2:
|
||||
usage()
|
||||
return
|
||||
do_list_channels()
|
||||
else:
|
||||
usage()
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
exit(ERROR_EXCEPTION)
|
||||
exit(retcode)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -37,8 +37,8 @@ import com.intellij.ui.CollectionComboBoxModel;
|
||||
import com.intellij.util.NullableConsumer;
|
||||
import com.intellij.webcore.packaging.PackagesNotificationPanel;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.packaging.PyPackageManagers;
|
||||
import com.jetbrains.python.packaging.ui.PyInstalledPackagesPanel;
|
||||
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.sdk.*;
|
||||
@@ -94,7 +94,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final Sdk selectedSdk = (Sdk)mySdkCombo.getSelectedItem();
|
||||
myPackagesPanel.updatePackages(selectedSdk != null ? new PyPackageManagementService(myProject, selectedSdk) : null);
|
||||
myPackagesPanel.updatePackages(selectedSdk != null ? PyPackageManagers.getInstance().getManagementService(myProject, selectedSdk) : null);
|
||||
myPackagesPanel.updateNotifications(selectedSdk);
|
||||
}
|
||||
});
|
||||
@@ -148,7 +148,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
|
||||
}
|
||||
updateSdkList(false);
|
||||
mySdkCombo.getModel().setSelectedItem(myProjectSdksModel.findSdk(sdk.getName()));
|
||||
myPackagesPanel.updatePackages(new PyPackageManagementService(myProject, sdk));
|
||||
myPackagesPanel.updatePackages(PyPackageManagers.getInstance().getManagementService(myProject, sdk));
|
||||
myPackagesPanel.updateNotifications(sdk);
|
||||
}
|
||||
};
|
||||
@@ -336,7 +336,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
|
||||
|
||||
final Sdk sdk = getSdk();
|
||||
mySdkCombo.getModel().setSelectedItem(sdk == null ? null : myProjectSdksModel.findSdk(sdk.getName()));
|
||||
myPackagesPanel.updatePackages(sdk != null ? new PyPackageManagementService(myProject, sdk) : null);
|
||||
myPackagesPanel.updatePackages(sdk != null ? PyPackageManagers.getInstance().getManagementService(myProject, sdk) : null);
|
||||
myPackagesPanel.updateNotifications(sdk);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,9 @@
|
||||
package com.jetbrains.python.packaging;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.webcore.packaging.PackageManagementService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -31,4 +33,6 @@ public abstract class PyPackageManagers {
|
||||
|
||||
@NotNull
|
||||
public abstract PyPackageManager forSdk(Sdk sdk);
|
||||
|
||||
public abstract PackageManagementService getManagementService(Project project, Sdk sdk);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.ui.LabeledComponent;
|
||||
import com.intellij.ui.CollectionComboBoxModel;
|
||||
import com.intellij.webcore.packaging.PackagesNotificationPanel;
|
||||
import com.jetbrains.python.packaging.ui.PyInstalledPackagesPanel;
|
||||
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
|
||||
import com.jetbrains.python.sdk.PreferredSdkComparator;
|
||||
import com.jetbrains.python.sdk.PySdkListCellRenderer;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
@@ -53,7 +52,7 @@ public class PyManagePackagesDialog extends DialogWrapper {
|
||||
PackagesNotificationPanel notificationPanel = new PackagesNotificationPanel();
|
||||
final PyInstalledPackagesPanel packagesPanel = new PyInstalledPackagesPanel(project, notificationPanel);
|
||||
packagesPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
|
||||
packagesPanel.updatePackages(new PyPackageManagementService(project, sdk));
|
||||
packagesPanel.updatePackages(PyPackageManagers.getInstance().getManagementService(project, sdk));
|
||||
packagesPanel.updateNotifications(sdk);
|
||||
|
||||
myMainPanel = new JPanel(new BorderLayout());
|
||||
@@ -67,7 +66,7 @@ public class PyManagePackagesDialog extends DialogWrapper {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Sdk sdk = (Sdk) sdkComboBox.getSelectedItem();
|
||||
packagesPanel.updatePackages(new PyPackageManagementService(project, sdk));
|
||||
packagesPanel.updatePackages(PyPackageManagers.getInstance().getManagementService(project, sdk));
|
||||
packagesPanel.updateNotifications(sdk);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -93,6 +93,8 @@
|
||||
|
||||
<applicationService serviceInterface="com.jetbrains.python.packaging.PyPackageService"
|
||||
serviceImplementation="com.jetbrains.python.packaging.PyPackageService"/>
|
||||
<applicationService serviceInterface="com.jetbrains.python.packaging.PyCondaPackageService"
|
||||
serviceImplementation="com.jetbrains.python.packaging.PyCondaPackageService"/>
|
||||
<applicationService serviceInterface="com.jetbrains.python.module.PyModuleService"
|
||||
serviceImplementation="com.jetbrains.python.module.PyModuleServiceImpl"/>
|
||||
|
||||
@@ -523,7 +525,7 @@
|
||||
<additionalTextAttributes scheme="Darcula" file="colorSchemes/PythonDarcula.xml"/>
|
||||
|
||||
<postStartupActivity implementation="com.jetbrains.python.sdk.PythonSdkUpdater"/>
|
||||
<postStartupActivity implementation="com.jetbrains.python.packaging.PyPIPackagesUpdater"/>
|
||||
<postStartupActivity implementation="com.jetbrains.python.packaging.PyPackagesUpdater"/>
|
||||
<directoryProjectConfigurator implementation="com.jetbrains.python.testing.PyIntegratedToolsProjectConfigurator" id="integratedTools" order="after sdk"/>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.packaging;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.RunCanceledByUserException;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.process.CapturingProcessHandler;
|
||||
import com.intellij.execution.process.ProcessOutput;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class PyCondaPackageManagerImpl extends PyPackageManagerImpl {
|
||||
public static final String PYTHON = "python";
|
||||
|
||||
PyCondaPackageManagerImpl(@NotNull Sdk sdk) {
|
||||
super(sdk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installManagement() throws ExecutionException {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasManagement(boolean cachedOnly) throws ExecutionException {
|
||||
return getCondaExecutable(mySdk) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installManagement(@NotNull String name) throws ExecutionException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void install(@NotNull List<PyRequirement> requirements, @NotNull List<String> extraArgs) throws ExecutionException {
|
||||
final ArrayList<String> arguments = new ArrayList<String>();
|
||||
for (PyRequirement requirement : requirements) {
|
||||
arguments.add(requirement.toString());
|
||||
}
|
||||
arguments.add("-y");
|
||||
if (extraArgs.contains("-U")) {
|
||||
getCondaOutput("update", arguments);
|
||||
}
|
||||
else {
|
||||
arguments.addAll(extraArgs);
|
||||
getCondaOutput("install", arguments);
|
||||
}
|
||||
}
|
||||
|
||||
private ProcessOutput getCondaOutput(@NotNull final String command, List<String> arguments) throws ExecutionException {
|
||||
final String condaExecutable = getCondaExecutable(mySdk);
|
||||
|
||||
final String path = getCondaDirectory();
|
||||
if (path == null) throw new PyExecutionException("Empty conda name for " + mySdk, command, arguments);
|
||||
|
||||
final ArrayList<String> parameters = Lists.newArrayList(condaExecutable, command, "-p", path);
|
||||
parameters.addAll(arguments);
|
||||
|
||||
final GeneralCommandLine commandLine = new GeneralCommandLine(parameters);
|
||||
final Process process = commandLine.createProcess();
|
||||
final CapturingProcessHandler handler = new CapturingProcessHandler(process);
|
||||
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
final ProcessOutput result;
|
||||
if (indicator != null) {
|
||||
result = handler.runProcessWithProgressIndicator(indicator);
|
||||
}
|
||||
else {
|
||||
result = handler.runProcess();
|
||||
}
|
||||
if (result.isCancelled()) {
|
||||
throw new RunCanceledByUserException();
|
||||
}
|
||||
final int exitCode = result.getExitCode();
|
||||
if (exitCode != 0) {
|
||||
final String message = StringUtil.isEmptyOrSpaces(result.getStdout()) && StringUtil.isEmptyOrSpaces(result.getStderr()) ?
|
||||
"Permission denied" : "Non-zero exit code";
|
||||
throw new PyExecutionException(message, "Conda", parameters, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getCondaDirectory() {
|
||||
final VirtualFile homeDirectory = mySdk.getHomeDirectory();
|
||||
if (homeDirectory == null) return null;
|
||||
return homeDirectory.getParent().getParent().getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void install(@NotNull String requirementString) throws ExecutionException {
|
||||
getCondaOutput("install", Lists.newArrayList(requirementString, "-y"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstall(@NotNull List<PyPackage> packages) throws ExecutionException {
|
||||
final ArrayList<String> arguments = new ArrayList<String>();
|
||||
for (PyPackage aPackage : packages) {
|
||||
arguments.add(aPackage.getName());
|
||||
}
|
||||
arguments.add("-y");
|
||||
|
||||
getCondaOutput("remove", arguments);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<PyPackage> getPackages(boolean cachedOnly) throws ExecutionException {
|
||||
final ProcessOutput output = getCondaOutput("list", Lists.newArrayList("-e"));
|
||||
return parseCondaToolOutput(output.getStdout());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected static List<PyPackage> parseCondaToolOutput(@NotNull String s) throws ExecutionException {
|
||||
final String[] lines = StringUtil.splitByLines(s);
|
||||
final List<PyPackage> packages = new ArrayList<PyPackage>();
|
||||
for (String line : lines) {
|
||||
if (line.startsWith("#")) continue;
|
||||
final List<String> fields = StringUtil.split(line, "=");
|
||||
if (fields.size() < 3) {
|
||||
throw new PyExecutionException("Invalid conda output format", "conda", Collections.<String>emptyList());
|
||||
}
|
||||
final String name = fields.get(0);
|
||||
final String version = fields.get(1);
|
||||
final String location = fields.get(2);
|
||||
final List<PyRequirement> requirements = new ArrayList<PyRequirement>();
|
||||
if (fields.size() >= 4) {
|
||||
final String requiresLine = fields.get(3);
|
||||
final String requiresSpec = StringUtil.join(StringUtil.split(requiresLine, ":"), "\n");
|
||||
requirements.addAll(PyRequirement.parse(requiresSpec));
|
||||
}
|
||||
if (!"Python".equals(name)) {
|
||||
packages.add(new PyPackage(name, version, location, requirements));
|
||||
}
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getCondaExecutable(Sdk sdk) {
|
||||
final String condaName = SystemInfo.isWindows ? "conda.exe" : "conda";
|
||||
final VirtualFile homeDirectory = sdk.getHomeDirectory();
|
||||
if (homeDirectory == null) return null;
|
||||
final VirtualFile condaExecutable = homeDirectory.getParent().findChild(condaName);
|
||||
return condaExecutable != null ? condaExecutable.getPath() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String createVirtualEnv(@NotNull String destinationDir, boolean useGlobalSite) throws ExecutionException {
|
||||
final String condaExecutable = getCondaExecutable(mySdk);
|
||||
final String versionString = mySdk.getVersionString();
|
||||
final LanguageLevel level = versionString != null ? LanguageLevel.fromPythonVersion(versionString) : LanguageLevel.PYTHON35;
|
||||
|
||||
final ArrayList<String> parameters = Lists.newArrayList(condaExecutable, "create", "-p", destinationDir,
|
||||
"python=" + level.toString(), "-y");
|
||||
|
||||
final GeneralCommandLine commandLine = new GeneralCommandLine(parameters);
|
||||
final Process process = commandLine.createProcess();
|
||||
final CapturingProcessHandler handler = new CapturingProcessHandler(process);
|
||||
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
final ProcessOutput result = handler.runProcessWithProgressIndicator(indicator);
|
||||
if (result.isCancelled()) {
|
||||
throw new RunCanceledByUserException();
|
||||
}
|
||||
final int exitCode = result.getExitCode();
|
||||
if (exitCode != 0) {
|
||||
final String message = StringUtil.isEmptyOrSpaces(result.getStdout()) && StringUtil.isEmptyOrSpaces(result.getStderr()) ?
|
||||
"Permission denied" : "Non-zero exit code";
|
||||
throw new PyExecutionException(message, "Conda", parameters, result);
|
||||
}
|
||||
final String binary = PythonSdkType.getPythonExecutable(destinationDir);
|
||||
final String binaryFallback = destinationDir + File.separator + "bin" + File.separator + "python";
|
||||
return (binary != null) ? binary : binaryFallback;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.packaging;
|
||||
|
||||
import com.intellij.execution.process.ProcessOutput;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.text.VersionComparatorUtil;
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||
import com.jetbrains.python.PythonHelpersLocator;
|
||||
import com.jetbrains.python.sdk.PySdkUtil;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
@State(name = "PyCondaPackageService",
|
||||
storages = {
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/conda_packages.xml")
|
||||
}
|
||||
)
|
||||
public class PyCondaPackageService implements PersistentStateComponent<PyCondaPackageService> {
|
||||
public Map<String, String> CONDA_PACKAGES = ContainerUtil.newConcurrentMap();
|
||||
public Map<String, List<String>> PACKAGES_TO_RELEASES = new HashMap<String, List<String>>();
|
||||
public Set<String> CONDA_CHANNELS = ContainerUtil.newConcurrentSet();
|
||||
|
||||
public long LAST_TIME_CHECKED = 0;
|
||||
|
||||
@Override
|
||||
public PyCondaPackageService getState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(PyCondaPackageService state) {
|
||||
XmlSerializerUtil.copyBean(state, this);
|
||||
}
|
||||
|
||||
public static PyCondaPackageService getInstance() {
|
||||
return ServiceManager.getService(PyCondaPackageService.class);
|
||||
}
|
||||
|
||||
public Map<String, String> getCondaPackages() {
|
||||
return CONDA_PACKAGES;
|
||||
}
|
||||
|
||||
public Map<String, String> loadAndGetPackages() {
|
||||
if (CONDA_PACKAGES.isEmpty()) {
|
||||
updatePackagesCache();
|
||||
}
|
||||
return CONDA_PACKAGES;
|
||||
}
|
||||
|
||||
public Set<String> loadAndGetChannels() {
|
||||
if (CONDA_CHANNELS.isEmpty()) {
|
||||
updateChannels();
|
||||
}
|
||||
return CONDA_CHANNELS;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getCondaPython() {
|
||||
final String condaName = SystemInfo.isWindows ? "python.exe" : "python";
|
||||
final VirtualFile userHome = LocalFileSystem.getInstance().findFileByPath(SystemProperties.getUserHome().replace('\\', '/'));
|
||||
if (userHome != null) {
|
||||
for (String root : VirtualEnvSdkFlavor.CONDA_DEFAULT_ROOTS) {
|
||||
VirtualFile condaFolder = userHome.findChild(root);
|
||||
String executableFile = findExecutable(condaName, condaFolder);
|
||||
if (executableFile != null) return executableFile;
|
||||
if (SystemInfo.isWindows) {
|
||||
condaFolder = LocalFileSystem.getInstance().findFileByPath("C:\\" + root);
|
||||
executableFile = findExecutable(condaName, condaFolder);
|
||||
if (executableFile != null) return executableFile;
|
||||
}
|
||||
else {
|
||||
final String systemWidePath = "/opt/anaconda";
|
||||
condaFolder = LocalFileSystem.getInstance().findFileByPath(systemWidePath);
|
||||
executableFile = findExecutable(condaName, condaFolder);
|
||||
if (executableFile != null) return executableFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String findExecutable(String condaName, VirtualFile condaFolder) {
|
||||
if (condaFolder != null) {
|
||||
final VirtualFile bin = condaFolder.findChild("bin");
|
||||
if (bin != null) {
|
||||
final VirtualFile[] children = bin.getChildren();
|
||||
if (children.length == 0) return null;
|
||||
final String executableFile = PythonSdkType.getExecutablePath(children[0].getPath(), condaName);
|
||||
if (executableFile != null) {
|
||||
return executableFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updatePackagesCache() {
|
||||
final String condaPython = getCondaPython();
|
||||
if (condaPython == null) return;
|
||||
final String path = PythonHelpersLocator.getHelperPath("conda_packaging_tool.py");
|
||||
final String runDirectory = new File(condaPython).getParent();
|
||||
final ProcessOutput output = PySdkUtil.getProcessOutput(runDirectory, new String[]{condaPython, path, "listall"});
|
||||
if (output.getExitCode() != 0) return;
|
||||
final List<String> lines = output.getStdoutLines();
|
||||
for (String line : lines) {
|
||||
final List<String> split = StringUtil.split(line, "\t");
|
||||
if (split.size() < 2) continue;
|
||||
final String aPackage = CONDA_PACKAGES.get(split.get(0));
|
||||
if (aPackage != null) {
|
||||
if (VersionComparatorUtil.compare(aPackage, split.get(1)) < 0)
|
||||
CONDA_PACKAGES.put(split.get(0), split.get(1));
|
||||
}
|
||||
else {
|
||||
CONDA_PACKAGES.put(split.get(0), split.get(1));
|
||||
}
|
||||
|
||||
if (PACKAGES_TO_RELEASES.containsKey(split.get(0))) {
|
||||
final List<String> versions = PACKAGES_TO_RELEASES.get(split.get(0));
|
||||
if (!versions.contains(split.get(1))) {
|
||||
versions.add(split.get(1));
|
||||
}
|
||||
}
|
||||
else {
|
||||
final ArrayList<String> versions = new ArrayList<String>();
|
||||
versions.add(split.get(1));
|
||||
PACKAGES_TO_RELEASES.put(split.get(0), versions);
|
||||
}
|
||||
}
|
||||
LAST_TIME_CHECKED = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getPackageVersions(@NotNull final String packageName) {
|
||||
if (PACKAGES_TO_RELEASES.containsKey(packageName)) {
|
||||
return PACKAGES_TO_RELEASES.get(packageName);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public void updateChannels() {
|
||||
final String condaPython = getCondaPython();
|
||||
if (condaPython == null) return;
|
||||
final String path = PythonHelpersLocator.getHelperPath("conda_packaging_tool.py");
|
||||
final String runDirectory = new File(condaPython).getParent();
|
||||
final ProcessOutput output = PySdkUtil.getProcessOutput(runDirectory, new String[]{condaPython, path, "channels"});
|
||||
if (output.getExitCode() != 0) return;
|
||||
final List<String> lines = output.getStdoutLines();
|
||||
for (String line : lines) {
|
||||
CONDA_CHANNELS.add(line);
|
||||
}
|
||||
LAST_TIME_CHECKED = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package com.jetbrains.python.packaging;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.jetbrains.python.packaging.ui.PyCondaManagementService;
|
||||
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -29,7 +32,6 @@ public class PyPackageManagersImpl extends PyPackageManagers {
|
||||
private final Map<String, PyPackageManagerImpl> myInstances = new HashMap<String, PyPackageManagerImpl>();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public synchronized PyPackageManager forSdk(Sdk sdk) {
|
||||
final String name = sdk.getName();
|
||||
PyPackageManagerImpl manager = myInstances.get(name);
|
||||
@@ -37,6 +39,9 @@ public class PyPackageManagersImpl extends PyPackageManagers {
|
||||
if (PythonSdkType.isRemote(sdk)) {
|
||||
manager = new PyRemotePackageManagerImpl(sdk);
|
||||
}
|
||||
else if (PyCondaPackageManagerImpl.getCondaExecutable(sdk) != null) {
|
||||
manager = new PyCondaPackageManagerImpl(sdk);
|
||||
}
|
||||
else {
|
||||
manager = new PyPackageManagerImpl(sdk);
|
||||
}
|
||||
@@ -44,4 +49,11 @@ public class PyPackageManagersImpl extends PyPackageManagers {
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
public PyPackageManagementService getManagementService(Project project, Sdk sdk) {
|
||||
if (PyCondaPackageManagerImpl.getCondaExecutable(sdk) != null) {
|
||||
return new PyCondaManagementService(project, sdk);
|
||||
}
|
||||
return new PyPackageManagementService(project, sdk);
|
||||
}
|
||||
}
|
||||
|
||||
+22
-17
@@ -18,7 +18,6 @@ package com.jetbrains.python.packaging;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -34,19 +33,9 @@ import java.io.IOException;
|
||||
* PyPI cache updater
|
||||
* User : catherine
|
||||
*/
|
||||
public class PyPIPackagesUpdater implements StartupActivity {
|
||||
public class PyPackagesUpdater implements StartupActivity {
|
||||
private static final Logger LOG = Logger.getInstance("#com.jetbrains.python.packaging.PyPIPackagesUpdater");
|
||||
|
||||
public static PyPIPackagesUpdater getInstance() {
|
||||
final StartupActivity[] extensions = Extensions.getExtensions(StartupActivity.POST_STARTUP_ACTIVITY);
|
||||
for (StartupActivity extension : extensions) {
|
||||
if (extension instanceof PyPIPackagesUpdater) {
|
||||
return (PyPIPackagesUpdater) extension;
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("could not find self");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runActivity(@NotNull final Project project) {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
@@ -68,19 +57,35 @@ public class PyPIPackagesUpdater implements StartupActivity {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (checkCondaUpdateNeeded(project)) {
|
||||
application.executeOnPooledThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PyCondaPackageService.getInstance().updatePackagesCache();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkCondaUpdateNeeded(Project project) {
|
||||
if (!hasPython(project)) return false;
|
||||
final long timeDelta = System.currentTimeMillis() - PyCondaPackageService.getInstance().LAST_TIME_CHECKED;
|
||||
if (Math.abs(timeDelta) < DateFormatUtil.DAY) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean checkNeeded(Project project, PyPackageService service) {
|
||||
boolean hasPython = false;
|
||||
private static boolean hasPython(Project project) {
|
||||
for (Module module : ModuleManager.getInstance(project).getModules()) {
|
||||
final Sdk sdk = PythonSdkType.findPythonSdk(module);
|
||||
if (sdk != null && sdk.getSdkType() instanceof PythonSdkType) {
|
||||
hasPython = true;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!hasPython) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean checkNeeded(Project project, PyPackageService service) {
|
||||
if (!hasPython(project)) return false;
|
||||
final long timeDelta = System.currentTimeMillis() - service.LAST_TIME_CHECKED;
|
||||
if (Math.abs(timeDelta) < DateFormatUtil.DAY) return false;
|
||||
return true;
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.packaging.ui;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.util.CatchingConsumer;
|
||||
import com.intellij.webcore.packaging.InstalledPackage;
|
||||
import com.intellij.webcore.packaging.PackageVersionComparator;
|
||||
import com.intellij.webcore.packaging.RepoPackage;
|
||||
import com.jetbrains.python.packaging.PyCondaPackageService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class PyCondaManagementService extends PyPackageManagementService {
|
||||
|
||||
public PyCondaManagementService(@NotNull final Project project, @NotNull final Sdk sdk) {
|
||||
super(project, sdk);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<RepoPackage> getAllPackagesCached() {
|
||||
return versionMapToPackageList(PyCondaPackageService.getInstance().getCondaPackages());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<RepoPackage> getAllPackages() {
|
||||
return versionMapToPackageList(PyCondaPackageService.getInstance().loadAndGetPackages());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<RepoPackage> reloadAllPackages() {
|
||||
return getAllPackages();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllRepositories() {
|
||||
List<String> result = new ArrayList<String>();
|
||||
result.addAll(PyCondaPackageService.getInstance().loadAndGetChannels());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInstallToUser() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetchPackageVersions(String packageName, CatchingConsumer<List<String>, Exception> consumer) {
|
||||
final List<String> versions = PyCondaPackageService.getInstance().getPackageVersions(packageName);
|
||||
Collections.sort(versions, Collections.reverseOrder(new PackageVersionComparator()));
|
||||
consumer.consume(versions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallPackages(List<InstalledPackage> installedPackages, Listener listener) {
|
||||
super.uninstallPackages(installedPackages, listener);
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
|
||||
PackagesNotificationPanel.showError("Failed to install Python packaging tools", description);
|
||||
}
|
||||
packageManager.refresh();
|
||||
updatePackages(new PyPackageManagementService(myProject, sdk));
|
||||
updatePackages(PyPackageManagers.getInstance().getManagementService(myProject, sdk));
|
||||
updateNotifications(sdk);
|
||||
}
|
||||
});
|
||||
@@ -130,7 +130,7 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
|
||||
if (sdk != null) {
|
||||
fix.run(sdk);
|
||||
myNotificationArea.removeLinkHandler(key);
|
||||
updatePackages(new PyPackageManagementService(myProject, sdk));
|
||||
updatePackages(PyPackageManagers.getInstance().getManagementService(myProject, sdk));
|
||||
updateNotifications(sdk);
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,8 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
|
||||
final String name = pkg.getName();
|
||||
if (PyPackageManager.PIP.equals(name) ||
|
||||
PyPackageManager.SETUPTOOLS.equals(name) ||
|
||||
PyPackageManager.DISTRIBUTE.equals(name)) {
|
||||
PyPackageManager.DISTRIBUTE.equals(name) ||
|
||||
PyCondaPackageManagerImpl.PYTHON.equals(name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -49,11 +49,12 @@ public class PyPackageManagementService extends PackageManagementService {
|
||||
private final Project myProject;
|
||||
private final Sdk mySdk;
|
||||
|
||||
public PyPackageManagementService(Project project, Sdk sdk) {
|
||||
public PyPackageManagementService(@NotNull final Project project, @NotNull final Sdk sdk) {
|
||||
myProject = project;
|
||||
mySdk = sdk;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Sdk getSdk() {
|
||||
return mySdk;
|
||||
}
|
||||
@@ -90,7 +91,7 @@ public class PyPackageManagementService extends PackageManagementService {
|
||||
return packages;
|
||||
}
|
||||
|
||||
private static List<RepoPackage> versionMapToPackageList(Map<String, String> packageToVersionMap) {
|
||||
protected static List<RepoPackage> versionMapToPackageList(Map<String, String> packageToVersionMap) {
|
||||
final boolean customRepoConfigured = !PyPackageService.getInstance().additionalRepositories.isEmpty();
|
||||
String url = customRepoConfigured ? PyPIPackageUtil.PYPI_URL : "";
|
||||
List<RepoPackage> packages = new ArrayList<RepoPackage>();
|
||||
|
||||
@@ -42,7 +42,7 @@ public class VirtualEnvSdkFlavor extends CPythonSdkFlavor {
|
||||
private VirtualEnvSdkFlavor() {
|
||||
}
|
||||
private final static String[] NAMES = new String[]{"jython", "pypy", "python.exe", "jython.bat", "pypy.exe"};
|
||||
private final static String[] CONDA_DEFAULT_ROOTS = new String[]{"anaconda", "anaconda3", "miniconda", "miniconda3",
|
||||
public final static String[] CONDA_DEFAULT_ROOTS = new String[]{"anaconda", "anaconda3", "miniconda", "miniconda3",
|
||||
"Anaconda", "Anaconda3", "Miniconda", "Miniconda3"};
|
||||
|
||||
public static VirtualEnvSdkFlavor INSTANCE = new VirtualEnvSdkFlavor();
|
||||
|
||||
Reference in New Issue
Block a user