added initial conda support

This commit is contained in:
Ekaterina Tuzova
2015-09-28 16:52:04 +03:00
parent 5950e861dd
commit 55dacfeb3a
14 changed files with 569 additions and 33 deletions
@@ -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);
}
});
+50
View File
@@ -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);
}
});
+3 -1
View File
@@ -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);
}
}
@@ -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();