From 8ff9916704fef3dae46766a05de3fb3a7460ce0a Mon Sep 17 00:00:00 2001 From: Fabio Zadrozny Date: Mon, 16 Sep 2024 08:55:33 -0300 Subject: [PATCH] Move some things related to conda selection to core projects. --- .../org.python.pydev.ast/META-INF/MANIFEST.MF | 1 + .../PyDevCondaPreferences.java | 46 +------- .../pydev/ast/package_managers/CondaCore.java | 111 ++++++++++++++++++ .../package_managers}/NameAndExecutable.java | 18 +-- .../PythonListEditor.java | 6 +- .../pydev/ui/dialogs/PyDialogHelpers.java | 41 ++----- .../AbstractInterpreterEditor.java | 5 +- .../ui/pythonpathconf/AutoConfigMaker.java | 3 +- .../InterpreterConfigHelpers.java | 18 +-- .../pydev/ui/pythonpathconf/PackageTab.java | 2 +- .../AbstractPackageManager.java | 7 +- .../package_manager/CondaPackageManager.java | 28 ++--- .../package_manager/PipPackageManager.java | 6 +- .../package_manager/PipenvPackageManager.java | 2 +- 14 files changed, 172 insertions(+), 122 deletions(-) create mode 100644 plugins/org.python.pydev.ast/src/org/python/pydev/ast/package_managers/CondaCore.java rename plugins/{org.python.pydev/src/org/python/pydev/ui/pythonpathconf => org.python.pydev.ast/src/org/python/pydev/ast/package_managers}/NameAndExecutable.java (70%) diff --git a/plugins/org.python.pydev.ast/META-INF/MANIFEST.MF b/plugins/org.python.pydev.ast/META-INF/MANIFEST.MF index 3c738c7eff..ed4cd916f5 100644 --- a/plugins/org.python.pydev.ast/META-INF/MANIFEST.MF +++ b/plugins/org.python.pydev.ast/META-INF/MANIFEST.MF @@ -29,6 +29,7 @@ Export-Package: org.python.pydev.ast, org.python.pydev.ast.item_pointer, org.python.pydev.ast.listing_utils, org.python.pydev.ast.location, + org.python.pydev.ast.package_managers, org.python.pydev.ast.refactoring, org.python.pydev.ast.runners, org.python.pydev.ast.simpleassist, diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/PyDevCondaPreferences.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/PyDevCondaPreferences.java index 018fdf9a47..cfc69bbdbb 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/PyDevCondaPreferences.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/PyDevCondaPreferences.java @@ -1,22 +1,18 @@ package org.python.pydev.ast.interpreter_managers; import java.io.File; -import java.util.ArrayList; -import java.util.List; +import org.python.pydev.ast.package_managers.CondaCore; import org.python.pydev.core.IInterpreterInfo; import org.python.pydev.core.IInterpreterInfo.UnableToFindExecutableException; import org.python.pydev.core.log.Log; import org.python.pydev.core.preferences.PydevPrefs; -import org.python.pydev.plugin.nature.PythonNature; import org.python.pydev.shared_core.io.FileUtils; -import org.python.pydev.shared_core.structure.OrderedSet; -import org.python.pydev.shared_core.utils.PlatformUtils; public final class PyDevCondaPreferences { - private static final String CONDA_PATH = "CONDA_PATH"; - private static final String DEFAULT_CONDA_PATH = ""; + public static final String CONDA_PATH = "CONDA_PATH"; + public static final String DEFAULT_CONDA_PATH = ""; /** * @return the conda executable or null if it couldn't be found. @@ -49,41 +45,7 @@ public static File findCondaExecutable(IInterpreterInfo interpreterInfo) throws try { condaExecutable = interpreterInfo.searchExecutableForInterpreter("conda", true); } catch (UnableToFindExecutableException e) { - // Unable to find, let's see if it's in the path - OrderedSet pathsToSearch = new OrderedSet<>(PythonNature.getPathsToSearch()); - // use ordered set: we want to search the PATH before hard-coded paths. - String userHomeDir = System.getProperty("user.home"); - if (PlatformUtils.isWindowsPlatform()) { - pathsToSearch.add("c:/tools/miniconda"); - pathsToSearch.add("c:/tools/miniconda2"); - pathsToSearch.add("c:/tools/miniconda3"); - pathsToSearch.add("c:/tools/conda"); - pathsToSearch.add("c:/tools/conda2"); - pathsToSearch.add("c:/tools/conda3"); - } else { - pathsToSearch.add("/opt/conda"); - pathsToSearch.add("/opt/conda/bin"); - pathsToSearch.add("/usr/bin"); - } - pathsToSearch.add(new File(userHomeDir, "miniconda").toString()); - pathsToSearch.add(new File(userHomeDir, "miniconda2").toString()); - pathsToSearch.add(new File(userHomeDir, "miniconda3").toString()); - pathsToSearch.add(new File(userHomeDir, "conda").toString()); - pathsToSearch.add(new File(userHomeDir, "conda2").toString()); - pathsToSearch.add(new File(userHomeDir, "conda3").toString()); - pathsToSearch.add(new File(userHomeDir, "Anaconda").toString()); - pathsToSearch.add(new File(userHomeDir, "Anaconda2").toString()); - pathsToSearch.add(new File(userHomeDir, "Anaconda3").toString()); - pathsToSearch.add(new File(userHomeDir).toString()); - - List searchedDirectories = new ArrayList<>(); - for (String string : pathsToSearch) { - File file = InterpreterInfo.searchExecutableInContainer("conda", new File(string), - searchedDirectories); - if (file != null) { - condaExecutable = file; - } - } + condaExecutable = CondaCore.findCondaExecutableInSystem(); if (condaExecutable == null) { throw e; } diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/package_managers/CondaCore.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/package_managers/CondaCore.java new file mode 100644 index 0000000000..00909422ba --- /dev/null +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/package_managers/CondaCore.java @@ -0,0 +1,111 @@ +package org.python.pydev.ast.package_managers; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.python.pydev.ast.interpreter_managers.InterpreterInfo; +import org.python.pydev.ast.runners.SimpleRunner; +import org.python.pydev.core.log.Log; +import org.python.pydev.json.eclipsesource.JsonArray; +import org.python.pydev.json.eclipsesource.JsonObject; +import org.python.pydev.json.eclipsesource.JsonValue; +import org.python.pydev.plugin.nature.PythonNature; +import org.python.pydev.shared_core.io.FileUtils; +import org.python.pydev.shared_core.structure.OrderedSet; +import org.python.pydev.shared_core.structure.Tuple; +import org.python.pydev.shared_core.utils.PlatformUtils; + +public class CondaCore { + + public static List listCondaEnvironments(File condaExecutable) { + String encoding = "utf-8"; + Tuple output = new SimpleRunner().runAndGetOutput( + new String[] { condaExecutable.toString(), "env", "list", "--json" }, null, null, + null, + encoding); + Log.logInfo(output.o1); + if (output.o2 != null && output.o2.length() > 0) { + Log.logInfo("STDERR when listing conda environments:\n" + output.o2); + + } + JsonObject jsonOutput = JsonValue.readFrom(output.o1).asObject(); + JsonArray envs = jsonOutput.get("envs").asArray(); + Set set = new HashSet<>(); + for (JsonValue env : envs.values()) { + set.add(new File(env.asString())); + } + return new ArrayList(set); + } + + public static List getCondaEnvsAsNameAndExecutable(List envs) { + List ret = new ArrayList(); + if (PlatformUtils.isWindowsPlatform()) { + for (File env : envs) { + File exec = new File(env, "python.exe"); + if (FileUtils.enhancedIsFile(exec)) { + ret.add(new NameAndExecutable(env.getName(), exec.getPath())); + } else { + Log.logInfo("Did not find: " + exec + " in conda environment."); + } + } + } else { + for (File env : envs) { + File exec = new File(new File(env, "bin"), "python"); + if (FileUtils.enhancedIsFile(exec)) { + ret.add(new NameAndExecutable(env.getName(), exec.getPath())); + } else { + Log.logInfo("Did not find: " + exec + " in conda environment."); + } + } + } + return ret; + } + + /** + * @return null if it couldn't be found, otherwise provides the conda + * executable found in the system. + */ + public static File findCondaExecutableInSystem() { + File condaExecutable = null; + // Unable to find, let's see if it's in the path + OrderedSet pathsToSearch = new OrderedSet<>(PythonNature.getPathsToSearch()); + // use ordered set: we want to search the PATH before hard-coded paths. + String userHomeDir = System.getProperty("user.home"); + if (PlatformUtils.isWindowsPlatform()) { + pathsToSearch.add("c:/tools/miniconda"); + pathsToSearch.add("c:/tools/miniconda2"); + pathsToSearch.add("c:/tools/miniconda3"); + pathsToSearch.add("c:/tools/conda"); + pathsToSearch.add("c:/tools/conda2"); + pathsToSearch.add("c:/tools/conda3"); + } else { + pathsToSearch.add("/opt/conda"); + pathsToSearch.add("/opt/conda/bin"); + pathsToSearch.add("/usr/bin"); + } + pathsToSearch.add(new File(userHomeDir, "miniconda").toString()); + pathsToSearch.add(new File(userHomeDir, "miniconda2").toString()); + pathsToSearch.add(new File(userHomeDir, "miniconda3").toString()); + pathsToSearch.add(new File(userHomeDir, "conda").toString()); + pathsToSearch.add(new File(userHomeDir, "conda2").toString()); + pathsToSearch.add(new File(userHomeDir, "conda3").toString()); + pathsToSearch.add(new File(userHomeDir, "Anaconda").toString()); + pathsToSearch.add(new File(userHomeDir, "Anaconda2").toString()); + pathsToSearch.add(new File(userHomeDir, "Anaconda3").toString()); + pathsToSearch.add(new File(userHomeDir).toString()); + + List searchedDirectories = new ArrayList<>(); + for (String string : pathsToSearch) { + File file = InterpreterInfo.searchExecutableInContainer("conda", new File(string), + searchedDirectories); + if (file != null) { + condaExecutable = file; + } + } + return condaExecutable; + } + +} diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/NameAndExecutable.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/package_managers/NameAndExecutable.java similarity index 70% rename from plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/NameAndExecutable.java rename to plugins/org.python.pydev.ast/src/org/python/pydev/ast/package_managers/NameAndExecutable.java index 5fd22c8c9a..f7b5341f2a 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/NameAndExecutable.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/package_managers/NameAndExecutable.java @@ -1,23 +1,23 @@ -package org.python.pydev.ui.pythonpathconf; +package org.python.pydev.ast.package_managers; import org.python.pydev.shared_core.string.FastStringBuffer; public final class NameAndExecutable { - public String o1; - public final String o2; + public String name; + public final String executable; public NameAndExecutable(String name, String executableOrJar) { - this.o1 = name; - this.o2 = executableOrJar; + this.name = name; + this.executable = executableOrJar; } public String getName() { - return this.o1; + return this.name; } public String getExecutableOrJar() { - return this.o2; + return this.executable; } @Override @@ -34,9 +34,9 @@ public boolean equals(Object obj) { public String toString() { FastStringBuffer buffer = new FastStringBuffer(); buffer.append("NameAndExecutable ["); - buffer.appendObject(o1); + buffer.appendObject(name); buffer.append(" -- "); - buffer.appendObject(o2); + buffer.appendObject(executable); buffer.append("]"); return buffer.toString(); } diff --git a/plugins/org.python.pydev/src/org/python/copiedfromeclipsesrc/PythonListEditor.java b/plugins/org.python.pydev/src/org/python/copiedfromeclipsesrc/PythonListEditor.java index dcbaa391c3..dbf154eef9 100644 --- a/plugins/org.python.pydev/src/org/python/copiedfromeclipsesrc/PythonListEditor.java +++ b/plugins/org.python.pydev/src/org/python/copiedfromeclipsesrc/PythonListEditor.java @@ -37,6 +37,7 @@ import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.swt.widgets.Widget; +import org.python.pydev.ast.package_managers.NameAndExecutable; import org.python.pydev.core.IInterpreterManager; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.log.Log; @@ -44,7 +45,6 @@ import org.python.pydev.shared_ui.ImageCache; import org.python.pydev.shared_ui.SharedUiPlugin; import org.python.pydev.ui.pythonpathconf.InterpreterConfigHelpers; -import org.python.pydev.ui.pythonpathconf.NameAndExecutable; import org.python.pydev.ui.pythonpathconf.conda.CondaConfigDialog; /** @@ -158,9 +158,9 @@ protected PythonListEditor(String name, String labelText, Composite parent) { public void addPressed(int configType) { NameAndExecutable input = getNewInputObject(configType); if (input != null) { - if (input.o1 != null && input.o2 != null) { + if (input.name != null && input.executable != null) { setPresentsDefaultValue(false); - TreeItem item = createInterpreterItem(input.o1, input.o2); + TreeItem item = createInterpreterItem(input.name, input.executable); try { treeWithInterpreters.setSelection(item); } catch (Exception e) { diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/dialogs/PyDialogHelpers.java b/plugins/org.python.pydev/src/org/python/pydev/ui/dialogs/PyDialogHelpers.java index 2d2df3410e..8613352f54 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/dialogs/PyDialogHelpers.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/dialogs/PyDialogHelpers.java @@ -7,7 +7,6 @@ package org.python.pydev.ui.dialogs; import java.io.File; -import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -36,15 +35,15 @@ import org.eclipse.ui.dialogs.ListDialog; import org.python.pydev.ast.interpreter_managers.AbstractInterpreterManager; import org.python.pydev.ast.interpreter_managers.PyDevCondaPreferences; +import org.python.pydev.ast.package_managers.CondaCore; +import org.python.pydev.ast.package_managers.NameAndExecutable; import org.python.pydev.core.IInterpreterInfo.UnableToFindExecutableException; import org.python.pydev.core.log.Log; import org.python.pydev.core.preferences.InterpreterGeneralPreferences; import org.python.pydev.plugin.PydevPlugin; import org.python.pydev.shared_core.image.UIConstants; -import org.python.pydev.shared_core.io.FileUtils; import org.python.pydev.shared_core.string.StringUtils; import org.python.pydev.shared_core.utils.ArrayUtils; -import org.python.pydev.shared_core.utils.PlatformUtils; import org.python.pydev.shared_ui.EditorUtils; import org.python.pydev.shared_ui.ImageCache; import org.python.pydev.shared_ui.SharedUiPlugin; @@ -52,7 +51,6 @@ import org.python.pydev.shared_ui.utils.RunInUiThread; import org.python.pydev.shared_ui.utils.UIUtils; import org.python.pydev.ui.pythonpathconf.InterpreterConfigHelpers; -import org.python.pydev.ui.pythonpathconf.NameAndExecutable; import org.python.pydev.ui.pythonpathconf.conda.CondaConfigDialog; import org.python.pydev.ui.pythonpathconf.package_manager.CondaPackageManager; @@ -192,6 +190,9 @@ public static int openQuestionConfigureInterpreter(AbstractInterpreterManager m) */ public static NameAndExecutable openCondaInterpreterSelection(Shell parentShell) { File condaExe = PyDevCondaPreferences.getExecutable(); + if (condaExe == null) { + condaExe = CondaCore.findCondaExecutableInSystem(); + } if (condaExe == null) { new CondaConfigDialog(parentShell).open(); condaExe = PyDevCondaPreferences.getExecutable(); @@ -201,7 +202,7 @@ public static NameAndExecutable openCondaInterpreterSelection(Shell parentShell) } List envs = CondaPackageManager.listCondaEnvironments(condaExe); - List nameAndExecutableList = getAsNameAndExecutable(envs); + List nameAndExecutableList = CondaCore.getCondaEnvsAsNameAndExecutable(envs); if (nameAndExecutableList.size() == 0) { openWarning("Error", "Could not find any Conda environment to choose from."); return null; @@ -211,7 +212,7 @@ public static NameAndExecutable openCondaInterpreterSelection(Shell parentShell) @Override public int compare(NameAndExecutable o1, NameAndExecutable o2) { - return o1.o1.compareToIgnoreCase(o2.o1); + return o1.name.compareToIgnoreCase(o2.name); } }); @@ -227,12 +228,12 @@ public Image getImage(Object element) { public String getText(Object element) { if (element != null && element instanceof NameAndExecutable) { NameAndExecutable nameAndExecutable = (NameAndExecutable) element; - String name = nameAndExecutable.o1; + String name = nameAndExecutable.name; name = StringUtils.truncateIfNeeded(name, 30); return name + StringUtils.createSpaceString(35 - name.length()) - + nameAndExecutable.o2; + + nameAndExecutable.executable; } return super.getText(element); } @@ -283,30 +284,6 @@ protected Control createDialogArea(Composite container) { return null; } - private static List getAsNameAndExecutable(List envs) { - List ret = new ArrayList(); - if (PlatformUtils.isWindowsPlatform()) { - for (File env : envs) { - File exec = new File(env, "python.exe"); - if (FileUtils.enhancedIsFile(exec)) { - ret.add(new NameAndExecutable(env.getName(), exec.getPath())); - } else { - Log.logInfo("Did not find: " + exec + " in conda environment."); - } - } - } else { - for (File env : envs) { - File exec = new File(new File(env, "bin"), "python"); - if (FileUtils.enhancedIsFile(exec)) { - ret.add(new NameAndExecutable(env.getName(), exec.getPath())); - } else { - Log.logInfo("Did not find: " + exec + " in conda environment."); - } - } - } - return ret; - } - /** * @param abstractInterpreterManager */ diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterEditor.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterEditor.java index 38040c4191..fe5d66cc08 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterEditor.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterEditor.java @@ -71,6 +71,7 @@ import org.python.copiedfromeclipsesrc.PythonListEditor; import org.python.pydev.ast.interpreter_managers.IInterpreterProviderFactory; import org.python.pydev.ast.interpreter_managers.InterpreterInfo; +import org.python.pydev.ast.package_managers.NameAndExecutable; import org.python.pydev.core.IInterpreterInfo; import org.python.pydev.core.IInterpreterManager; import org.python.pydev.core.IInterpreterManagerListener; @@ -1064,7 +1065,7 @@ protected NameAndExecutable getNewInputObject(int configType) { } else if (configType == InterpreterConfigHelpers.CONFIG_CONDA) { NameAndExecutable interpreterNameAndExecutable = PyDialogHelpers .openCondaInterpreterSelection(getShell()); - if (interpreterNameAndExecutable != null && interpreterNameAndExecutable.o2 != null) { + if (interpreterNameAndExecutable != null && interpreterNameAndExecutable.executable != null) { operation = InterpreterConfigHelpers.tryInterpreter( interpreterNameAndExecutable, interpreterManager, false, true, logger, this.getShell(), true); @@ -1086,7 +1087,7 @@ protected NameAndExecutable getNewInputObject(int configType) { logger.println("- Chosen interpreter (name and file):'" + interpreterNameAndExecutable); - if (interpreterNameAndExecutable != null && interpreterNameAndExecutable.o2 != null) { + if (interpreterNameAndExecutable != null && interpreterNameAndExecutable.executable != null) { //ok, now that we got the file, let's see if it is valid and get the library info. operation = InterpreterConfigHelpers.tryInterpreter( interpreterNameAndExecutable, interpreterManager, diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AutoConfigMaker.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AutoConfigMaker.java index a57f64d445..91e5a37462 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AutoConfigMaker.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AutoConfigMaker.java @@ -39,6 +39,7 @@ import org.python.pydev.ast.interpreter_managers.IInterpreterProviderFactory; import org.python.pydev.ast.interpreter_managers.IInterpreterProviderFactory.InterpreterType; import org.python.pydev.ast.interpreter_managers.InterpreterManagersAPI; +import org.python.pydev.ast.package_managers.NameAndExecutable; import org.python.pydev.core.ExtensionHelper; import org.python.pydev.core.IInterpreterInfo; import org.python.pydev.core.IInterpreterManager; @@ -262,7 +263,7 @@ public boolean isValid() throws Exception { // Try a quick config of the provider. // If getNameAndExecutable is successful, the interpreter won't be null & will have a unique name, // but it may a duplicate of something already configured. - if (InterpreterConfigHelpers.getDuplicatedMessageError(null, getNameAndExecutable().o2, + if (InterpreterConfigHelpers.getDuplicatedMessageError(null, getNameAndExecutable().executable, nameToInfo) != null) { return false; } diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/InterpreterConfigHelpers.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/InterpreterConfigHelpers.java index 49e754daed..3933933c7e 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/InterpreterConfigHelpers.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/InterpreterConfigHelpers.java @@ -28,6 +28,7 @@ import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.swt.widgets.Shell; import org.python.copiedfromeclipsesrc.JDTNotAvailableException; +import org.python.pydev.ast.package_managers.NameAndExecutable; import org.python.pydev.ast.runners.SimpleJythonRunner; import org.python.pydev.core.IInterpreterInfo; import org.python.pydev.core.IInterpreterManager; @@ -100,13 +101,13 @@ static ObtainInterpreterInfoOperation tryInterpreter(NameAndExecutable interpret static ObtainInterpreterInfoOperation tryInterpreter(NameAndExecutable interpreterNameAndExecutable, IInterpreterManager interpreterManager, boolean autoSelectFolders, boolean displayErrors, PrintWriter logger, Shell shell, boolean isConda) throws Exception { - String executable = interpreterNameAndExecutable.o2; + String executable = interpreterNameAndExecutable.executable; logger.println("- Ok, file is non-null. Getting info on:" + executable); ProgressMonitorDialog monitorDialog = new AsynchronousProgressMonitorDialog(shell); monitorDialog.setBlockOnOpen(false); ObtainInterpreterInfoOperation operation; while (true) { - operation = new ObtainInterpreterInfoOperation(interpreterNameAndExecutable.o2, logger, + operation = new ObtainInterpreterInfoOperation(interpreterNameAndExecutable.executable, logger, interpreterManager, autoSelectFolders, isConda); monitorDialog.run(true, false, operation); if (operation.e != null) { @@ -235,7 +236,7 @@ static ObtainInterpreterInfoOperation tryInterpreter(NameAndExecutable interpret throw new Exception(ERMSG_NOLIBS + executable); } } - operation.result.setName(interpreterNameAndExecutable.o1); + operation.result.setName(interpreterNameAndExecutable.name); logger.println("- Success getting the info. Result:" + operation.result); return operation; } @@ -267,7 +268,7 @@ static boolean checkInterpreterNameAndExecutable(NameAndExecutable interpreterNa foundError = true; } if (!foundError) { - if (interpreterNameAndExecutable.o2.trim().length() == 0) { + if (interpreterNameAndExecutable.executable.trim().length() == 0) { logger.println("- When trimmed, the chosen file was empty (returning null)."); if (shell != null) { @@ -279,7 +280,8 @@ static boolean checkInterpreterNameAndExecutable(NameAndExecutable interpreterNa } } if (!foundError && nameToInfo != null) { - String error = getDuplicatedMessageError(interpreterNameAndExecutable.o1, interpreterNameAndExecutable.o2, + String error = getDuplicatedMessageError(interpreterNameAndExecutable.name, + interpreterNameAndExecutable.executable, nameToInfo); if (error != null) { logger.println("- Duplicated interpreter found."); @@ -340,8 +342,8 @@ public static String getDuplicatedMessageError(String interpreterName, String ex public static boolean canAddNameAndExecutable(PrintWriter logger, NameAndExecutable interpreterNameAndExecutable, Map nameToInfo, Shell shell) { - interpreterNameAndExecutable.o1 = getUniqueInterpreterName( - interpreterNameAndExecutable.o1, nameToInfo); + interpreterNameAndExecutable.name = getUniqueInterpreterName( + interpreterNameAndExecutable.name, nameToInfo); boolean foundError = checkInterpreterNameAndExecutable( interpreterNameAndExecutable, logger, "Error getting info on interpreter", nameToInfo, shell); @@ -388,7 +390,7 @@ public static ObtainInterpreterInfoOperation createPipenvInterpreter(IInterprete logger.println("- Chosen interpreter (name and file):'" + interpreterNameAndExecutable); - if (interpreterNameAndExecutable != null && interpreterNameAndExecutable.o2 != null) { + if (interpreterNameAndExecutable != null && interpreterNameAndExecutable.executable != null) { //ok, now that we got the file, let's see if it is valid and get the library info. ObtainInterpreterInfoOperation ret = tryInterpreter( interpreterNameAndExecutable, interpreterManager, diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/PackageTab.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/PackageTab.java index 8f0979c3e9..8f5a9c9f47 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/PackageTab.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/PackageTab.java @@ -238,7 +238,7 @@ protected IStatus run(final IProgressMonitor monitor) { if (initialInfo != interpreterInfo || monitor.isCanceled() || tree.isDisposed()) { return Status.OK_STATUS; } - final List list = packageManager.list(); + final List list = packageManager.listLibrariesInEnv(); RunInUiThread.async(() -> { // Update tree only in UI thread! diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/AbstractPackageManager.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/AbstractPackageManager.java index 762009b42e..600ef0d32c 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/AbstractPackageManager.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/AbstractPackageManager.java @@ -29,7 +29,12 @@ public static AbstractPackageManager createPackageManager(IInterpreterInfo inter return new PipPackageManager(interpreterInfo); } - public abstract List list(); + /** + * Provides the details to fill in the tree for the conda libraries + * (list of string[name, version, build info]) + * To be called from any thread. + */ + public abstract List listLibrariesInEnv(); public List errorToList(List listed, UnableToFindExecutableException e) { String message = e.getMessage(); diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/CondaPackageManager.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/CondaPackageManager.java index 63f04e5a7c..2f1073aff4 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/CondaPackageManager.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/CondaPackageManager.java @@ -3,13 +3,12 @@ import java.io.File; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.eclipse.swt.widgets.Shell; import org.python.pydev.ast.codecompletion.shell.AbstractShell; import org.python.pydev.ast.interpreter_managers.PyDevCondaPreferences; +import org.python.pydev.ast.package_managers.CondaCore; import org.python.pydev.ast.runners.SimpleRunner; import org.python.pydev.core.IInterpreterInfo; import org.python.pydev.core.IInterpreterInfo.UnableToFindExecutableException; @@ -34,27 +33,16 @@ public CondaPackageManager(IInterpreterInfo interpreterInfo, File prefix) { } public static List listCondaEnvironments(File condaExecutable) { - String encoding = "utf-8"; - Tuple output = new SimpleRunner().runAndGetOutput( - new String[] { condaExecutable.toString(), "env", "list", "--json" }, null, null, - null, - encoding); - Log.logInfo(output.o1); - if (output.o2 != null && output.o2.length() > 0) { - Log.logInfo("STDERR when listing conda environments:\n" + output.o2); - - } - JsonObject jsonOutput = JsonValue.readFrom(output.o1).asObject(); - JsonArray envs = jsonOutput.get("envs").asArray(); - Set set = new HashSet<>(); - for (JsonValue env : envs.values()) { - set.add(new File(env.asString())); - } - return new ArrayList(set); + return CondaCore.listCondaEnvironments(condaExecutable); } + /** + * Provides the details to fill in the tree for the conda libraries + * (list of string[name, version, build info]) + * To be called from any thread. + */ @Override - public List list() { + public List listLibrariesInEnv() { List listed = new ArrayList(); File condaExecutable; try { diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/PipPackageManager.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/PipPackageManager.java index 0228cb7c5a..887a4d3895 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/PipPackageManager.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/PipPackageManager.java @@ -28,10 +28,12 @@ public PipPackageManager(IInterpreterInfo interpreterInfo) { } /** - * To be called from any thread + * Provides the details to fill in the tree for the conda libraries + * (list of string[name, version, build info]). + * To be called from any thread. */ @Override - public List list() { + public List listLibrariesInEnv() { List listed = new ArrayList(); File pipExecutable; Tuple output; diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/PipenvPackageManager.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/PipenvPackageManager.java index ed474b74cc..2e6effe9f3 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/PipenvPackageManager.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/package_manager/PipenvPackageManager.java @@ -94,7 +94,7 @@ private static String checkPipenvInfoCompatible(String pipenvLocation, String pr } @Override - public List list() { + public List listLibrariesInEnv() { return null; }