/****************************************************************************** * Copyright (C) 2013 Jonah Graham * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Jonah Graham <jonah@kichwacoders.com> - initial API and implementation ******************************************************************************/ package org.python.pydev.ui.pythonpathconf; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.python.pydev.core.log.Log; import org.python.pydev.runners.SimpleRunner; import org.python.pydev.shared_core.string.StringUtils; import org.python.pydev.shared_core.utils.PlatformUtils; import at.jta.Key; import at.jta.Regor; public class PythonInterpreterProviderFactory extends AbstractInterpreterProviderFactory { @Override public IInterpreterProvider[] getInterpreterProviders(InterpreterType type) { if (type != IInterpreterProviderFactory.InterpreterType.PYTHON) { return null; } List<String> foundVersions = new ArrayList<String>(); Set<String> pathsToSearch = new LinkedHashSet<String>(); try { Map<String, String> env = SimpleRunner.getDefaultSystemEnv(null); if (env.containsKey("PYTHON_HOME")) { pathsToSearch.add(env.get("PYTHON_HOME")); } if (env.containsKey("PYTHONHOME")) { pathsToSearch.add(env.get("PYTHONHOME")); } if (env.containsKey("PATH")) { String path = env.get("PATH"); String separator = SimpleRunner.getPythonPathSeparator(); final List<String> split = StringUtils.split(path, separator); pathsToSearch.addAll(split); } } catch (CoreException e) { Log.log(e); } if (!PlatformUtils.isWindowsPlatform()) { // Paths to search on linux/mac pathsToSearch.add("/usr/bin"); pathsToSearch.add("/usr/local/bin"); } if (PlatformUtils.isMacOsPlatform()) { // Path to search on mac pathsToSearch.add("/Library/Frameworks/Python.framework/Versions/Current/bin"); } // Do this first (i.e.: give priority to the one found first in the path). List<String> searchPatterns; if (PlatformUtils.isWindowsPlatform()) { searchPatterns = Arrays.asList("python.exe", "pypy.exe"); } else { searchPatterns = Arrays.asList("python", "python\\d(\\.\\d)*|pypy"); } final String[] ret = searchPaths(pathsToSearch, searchPatterns, false); foundVersions.addAll(Arrays.asList(ret)); if (PlatformUtils.isWindowsPlatform()) { // On windows we can also try to see the installed versions... try { Regor regor = new Regor(); // The structure for Python is something as // Software\\Python\\PythonCore\\2.6\\InstallPath for (Key root : new Key[] { Regor.HKEY_LOCAL_MACHINE, Regor.HKEY_CURRENT_USER }) { Key key = regor.openKey(root, "Software\\Python\\PythonCore", Regor.KEY_READ); if (key != null) { try { @SuppressWarnings("rawtypes") List l = regor.listKeys(key); for (Object o : l) { Key openKey = regor.openKey(key, (String) o + "\\InstallPath", Regor.KEY_READ); if (openKey != null) { try { byte buf[] = regor.readValue(openKey, ""); if (buf != null) { String parseValue = Regor.parseValue(buf); // Ok, this should be the directory // where it's installed, try to find // a 'python.exe' there... File file = new File(parseValue, "python.exe"); if (file.isFile()) { foundVersions.add(file.toString()); } } } finally { regor.closeKey(openKey); } } } } finally { regor.closeKey(key); } } } } catch (Throwable e) { Log.log(e); } } if (foundVersions.size() > 0) { // Remove duplicates foundVersions = new ArrayList<String>(new LinkedHashSet<String>(foundVersions)); return AlreadyInstalledInterpreterProvider.create("python", foundVersions.toArray(new String[foundVersions.size()])); } // This should be enough to find it from the PATH or any other way it's // defined. return AlreadyInstalledInterpreterProvider.create("python", "python"); } }