extract conda interpreter flavor from virtual env

gives us ability to add custom icons and rules
This commit is contained in:
Ekaterina Tuzova
2017-09-06 11:07:54 +03:00
parent c14959d04c
commit ca4c9823e7
11 changed files with 124 additions and 47 deletions
+1
View File
@@ -42,6 +42,7 @@ public class PythonIcons {
public static final Icon Buildout = load("/icons/com/jetbrains/python/buildout/buildout.png"); // 16x16
}
public static final Icon Condaenv = load("/icons/com/jetbrains/python/condaenv.png"); // 16x16
public static final Icon DataView = load("/icons/com/jetbrains/python/DataView.png"); // 13x13
public static class Debug {
@@ -26,6 +26,7 @@ import com.jetbrains.python.sdk.PyDetectedSdk;
import com.jetbrains.python.sdk.PySdkUtil;
import com.jetbrains.python.sdk.PythonSdkAdditionalData;
import com.jetbrains.python.sdk.PythonSdkType;
import com.jetbrains.python.sdk.flavors.CondaEnvSdkFlavor;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor;
import org.jetbrains.annotations.NotNull;
@@ -79,8 +80,9 @@ public class PyConfigurableInterpreterList {
private void addDetectedSdks(@NotNull final List<Sdk> result) {
final List<String> sdkHomes = new ArrayList<>();
sdkHomes.addAll(VirtualEnvSdkFlavor.INSTANCE.suggestHomePaths());
sdkHomes.addAll(CondaEnvSdkFlavor.INSTANCE.suggestHomePaths());
for (PythonSdkFlavor flavor : PythonSdkFlavor.getApplicableFlavors()) {
if (flavor instanceof VirtualEnvSdkFlavor) continue;
if (flavor instanceof VirtualEnvSdkFlavor || flavor instanceof CondaEnvSdkFlavor) continue;
sdkHomes.addAll(flavor.suggestHomePaths());
}
Collections.sort(sdkHomes);
Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

@@ -30,7 +30,7 @@ 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 com.jetbrains.python.sdk.flavors.CondaEnvSdkFlavor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -132,7 +132,7 @@ public class PyCondaPackageService implements PersistentStateComponent<PyCondaPa
public static String getCondaExecutable(@NotNull final String condaName) {
final VirtualFile userHome = LocalFileSystem.getInstance().findFileByPath(SystemProperties.getUserHome().replace('\\', '/'));
if (userHome != null) {
for (String root : VirtualEnvSdkFlavor.CONDA_DEFAULT_ROOTS) {
for (String root : CondaEnvSdkFlavor.CONDA_DEFAULT_ROOTS) {
VirtualFile condaFolder = userHome.findChild(root);
String executableFile = findExecutable(condaName, condaFolder);
if (executableFile != null) return executableFile;
@@ -28,7 +28,7 @@ import com.intellij.ui.components.JBLabel;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.packaging.PyCondaPackageManagerImpl;
import com.jetbrains.python.packaging.PyCondaPackageService;
import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor;
import com.jetbrains.python.sdk.flavors.CondaEnvSdkFlavor;
import com.jetbrains.python.validation.UnsupportedFeaturesUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,7 +66,7 @@ public class CreateCondaEnvDialog extends AbstractCreateVirtualEnvDialog {
@Override
protected void setInitialDestination() {
final List<VirtualFile> locations = VirtualEnvSdkFlavor.getCondaDefaultLocations();
final List<VirtualFile> locations = CondaEnvSdkFlavor.getCondaDefaultLocations();
if (!locations.isEmpty()) {
myInitialPath = locations.get(0).getPath();
return;
@@ -0,0 +1,115 @@
/*
* Copyright 2000-2017 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.sdk.flavors;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SystemProperties;
import com.jetbrains.python.sdk.PythonSdkType;
import icons.PythonIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor.findInDirectory;
public class CondaEnvSdkFlavor extends CPythonSdkFlavor {
private CondaEnvSdkFlavor() {
}
public final static String[] CONDA_DEFAULT_ROOTS = new String[]{"anaconda", "anaconda2", "anaconda3", "miniconda", "miniconda2",
"miniconda3", "Anaconda", "Anaconda2", "Anaconda3", "Miniconda", "Miniconda2", "Miniconda3"};
public static CondaEnvSdkFlavor INSTANCE = new CondaEnvSdkFlavor();
@Override
public Collection<String> suggestHomePaths() {
List<String> candidates = new ArrayList<>();
for (VirtualFile file : getCondaDefaultLocations()) {
candidates.addAll(findInDirectory(file));
}
return candidates;
}
public static List<VirtualFile> getCondaDefaultLocations() {
List<VirtualFile> roots = new ArrayList<>();
final VirtualFile userHome = LocalFileSystem.getInstance().findFileByPath(SystemProperties.getUserHome().replace('\\','/'));
if (userHome != null) {
final VirtualFile condaHidden = userHome.findChild(".conda");
if (condaHidden != null) {
addEnvsFolder(roots, condaHidden);
}
for (String root : CONDA_DEFAULT_ROOTS) {
VirtualFile condaFolder = userHome.findChild(root);
addEnvsFolder(roots, condaFolder);
if (SystemInfo.isWindows) {
final VirtualFile appData = userHome.findFileByRelativePath("AppData\\Local\\Continuum\\" + root);
addEnvsFolder(roots, appData);
condaFolder = LocalFileSystem.getInstance().findFileByPath("C:\\" + root);
addEnvsFolder(roots, condaFolder);
}
else {
final String systemWidePath = "/opt/anaconda";
condaFolder = LocalFileSystem.getInstance().findFileByPath(systemWidePath);
addEnvsFolder(roots, condaFolder);
}
}
}
return roots;
}
private static void addEnvsFolder(@NotNull final List<VirtualFile> roots, @Nullable final VirtualFile condaFolder) {
if (condaFolder != null) {
final VirtualFile envs = condaFolder.findChild("envs");
if (envs != null) {
roots.add(envs);
}
}
}
@Override
public boolean isValidSdkPath(@NotNull File file) {
if (!super.isValidSdkPath(file)) return false;
final File bin = file.getParentFile();
String condaName = "conda";
if (SystemInfo.isWindows) {
condaName = new File(bin, "envs").exists() ? "conda.exe" : "conda.bat";
}
if (bin != null) {
final File conda = new File(bin, condaName);
if (conda.exists()) {
return true;
}
final File condaFolder = bin.getParentFile();
final File condaExecutable = PythonSdkType.findExecutableFile(condaFolder, condaName);
if (condaExecutable != null) return true;
}
return false;
}
@Override
public Icon getIcon() {
return PythonIcons.Python.Condaenv;
}
}
@@ -117,6 +117,7 @@ public abstract class PythonSdkFlavor {
result.add(IronPythonSdkFlavor.INSTANCE);
result.add(PyPySdkFlavor.INSTANCE);
result.add(VirtualEnvSdkFlavor.INSTANCE);
result.add(CondaEnvSdkFlavor.INSTANCE);
result.add(PyRemoteSdkFlavor.INSTANCE);
return result;
@@ -42,8 +42,6 @@ public class VirtualEnvSdkFlavor extends CPythonSdkFlavor {
private VirtualEnvSdkFlavor() {
}
private final static String[] NAMES = new String[]{"jython", "pypy", "python.exe", "jython.bat", "pypy.exe"};
public final static String[] CONDA_DEFAULT_ROOTS = new String[]{"anaconda", "anaconda2", "anaconda3", "miniconda", "miniconda2",
"miniconda3", "Anaconda", "Anaconda2", "Anaconda3", "Miniconda", "Miniconda2", "Miniconda3"};
public static VirtualEnvSdkFlavor INSTANCE = new VirtualEnvSdkFlavor();
@@ -61,10 +59,6 @@ public class VirtualEnvSdkFlavor extends CPythonSdkFlavor {
if (path != null)
candidates.addAll(findInDirectory(path));
for (VirtualFile file : getCondaDefaultLocations()) {
candidates.addAll(findInDirectory(file));
}
final VirtualFile pyEnvLocation = getPyEnvDefaultLocations();
if (pyEnvLocation != null) {
candidates.addAll(findInDirectory(pyEnvLocation));
@@ -88,42 +82,6 @@ public class VirtualEnvSdkFlavor extends CPythonSdkFlavor {
return null;
}
public static List<VirtualFile> getCondaDefaultLocations() {
List<VirtualFile> roots = new ArrayList<>();
final VirtualFile userHome = LocalFileSystem.getInstance().findFileByPath(SystemProperties.getUserHome().replace('\\','/'));
if (userHome != null) {
final VirtualFile condaHidden = userHome.findChild(".conda");
if (condaHidden != null) {
addEnvsFolder(roots, condaHidden);
}
for (String root : CONDA_DEFAULT_ROOTS) {
VirtualFile condaFolder = userHome.findChild(root);
addEnvsFolder(roots, condaFolder);
if (SystemInfo.isWindows) {
final VirtualFile appData = userHome.findFileByRelativePath("AppData\\Local\\Continuum\\" + root);
addEnvsFolder(roots, appData);
condaFolder = LocalFileSystem.getInstance().findFileByPath("C:\\" + root);
addEnvsFolder(roots, condaFolder);
}
else {
final String systemWidePath = "/opt/anaconda";
condaFolder = LocalFileSystem.getInstance().findFileByPath(systemWidePath);
addEnvsFolder(roots, condaFolder);
}
}
}
return roots;
}
private static void addEnvsFolder(@NotNull final List<VirtualFile> roots, @Nullable final VirtualFile condaFolder) {
if (condaFolder != null) {
final VirtualFile envs = condaFolder.findChild("envs");
if (envs != null) {
roots.add(envs);
}
}
}
public static VirtualFile getDefaultLocation() {
final String path = System.getenv().get("WORKON_HOME");
if (!StringUtil.isEmpty(path)) {