--- a/CondaInterface/Conda.py Tue Feb 05 19:39:42 2019 +0100 +++ b/CondaInterface/Conda.py Tue Feb 05 19:58:26 2019 +0100 @@ -41,6 +41,10 @@ self.__ui = parent + ####################################################################### + ## environment related methods below + ####################################################################### + def createCondaEnvironment(self, arguments): """ Public method to create a conda environment. @@ -162,3 +166,276 @@ return False return jsonDict["success"] + + def getCondaEnvironmentsList(self, listPrefixes=False): + """ + Public method to get a list of all Conda environments. + + @param listPrefixes flag indicating to return prefixes instead of names + @type bool + @return list of environment names or prefixes + @rtype list of str + """ + # TODO: return environment name and prefix + # TODO: return root environment only, if writable ('root_prefix', 'root_writable') + exe = Preferences.getConda("CondaExecutable") + if not exe: + exe = "conda" + + environmentsList = [] + + proc = QProcess() + proc.start(exe, ["info", "--json"]) + if proc.waitForStarted(15000): + if proc.waitForFinished(15000): + output = str(proc.readAllStandardOutput(), + Preferences.getSystem("IOEncoding"), + 'replace').strip() + try: + jsonDict = json.loads(output) + except Exception: + jsonDict = {} + + if "envs" in jsonDict: + if listPrefixes: + environmentsList = jsonDict["envs"][:] + else: + environmentsList = [ + os.path.basename(e) for e in jsonDict["envs"]] + + return environmentsList + + ####################################################################### + ## package related methods below + ####################################################################### + + def getInstalledPackages(self, name="", prefix=""): + """ + Public method to get a list of installed packages of a conda + environment. + + @param name name of the environment + @type str + @param prefix prefix of the environment + @type str + @return list of installed packages. Each entry is a tuple containing + the package name, version and build. + @rtype list of tuples of (str, str, str) + @rtype bool + @exception RuntimeError raised to indicate an error in parameters + + Note: only one of name or prefix must be given. + """ + if name and prefix: + raise RuntimeError("Only one of 'name' or 'prefix' must be given.") + + if not name and not prefix: + raise RuntimeError("One of 'name' or 'prefix' must be given.") + + args = [ + "list", + "--json", + ] + if name: + args.extend(["--name", name]) + elif prefix: + args.extend(["--prefix", prefix]) + + exe = Preferences.getConda("CondaExecutable") + if not exe: + exe = "conda" + + packages = [] + + proc = QProcess() + proc.start(exe, args) + if proc.waitForStarted(15000): + if proc.waitForFinished(15000): + output = str(proc.readAllStandardOutput(), + Preferences.getSystem("IOEncoding"), + 'replace').strip() + try: + jsonList = json.loads(output) + except Exception: + jsonList = [] + + for package in jsonList: + if isinstance(package, dict): + packages.append(( + package["name"], + package["version"], + package["build_string"] + )) + else: + packages.append(tuple(package.rsplit("-", 2))) + + return packages + + def getUpdateablePackages(self, name="", prefix=""): + """ + Public method to get a list of updateable packages of a conda + environment. + + @param name name of the environment + @type str + @param prefix prefix of the environment + @type str + @return list of installed packages. Each entry is a tuple containing + the package name, version and build. + @rtype list of tuples of (str, str, str) + @rtype bool + @exception RuntimeError raised to indicate an error in parameters + + Note: only one of name or prefix must be given. + """ + if name and prefix: + raise RuntimeError("Only one of 'name' or 'prefix' must be given.") + + if not name and not prefix: + raise RuntimeError("One of 'name' or 'prefix' must be given.") + + args = [ + "update", + "--json", + "--quiet", + "--all", + "--dry-run", + ] + if name: + args.extend(["--name", name]) + elif prefix: + args.extend(["--prefix", prefix]) + + exe = Preferences.getConda("CondaExecutable") + if not exe: + exe = "conda" + + packages = [] + + proc = QProcess() + proc.start(exe, args) + if proc.waitForStarted(15000): + if proc.waitForFinished(15000): + output = str(proc.readAllStandardOutput(), + Preferences.getSystem("IOEncoding"), + 'replace').strip() + try: + jsonDict = json.loads(output) + except Exception: + jsonDict = {} + + if "actions" in jsonDict and "LINK" in jsonDict["actions"]: + for linkEntry in jsonDict["actions"]["LINK"]: + if isinstance(linkEntry, dict): + packages.append(( + linkEntry["name"], + linkEntry["version"], + linkEntry["build_string"] + )) + else: + package = linkEntry.split()[0] + packages.append(tuple(package.rsplit("-", 2))) + + return packages + + def updatePackages(self, packages, name="", prefix=""): + """ + Public method to update packages of a conda environment. + + @param packages list of package names to be updated + @type list of str + @param name name of the environment + @type str + @param prefix prefix of the environment + @type str + @return list of installed packages. Each entry is a tuple containing + the package name, version and build. + @rtype list of tuples of (str, str, str) + @rtype bool + @exception RuntimeError raised to indicate an error in parameters + + Note: only one of name or prefix must be given. + """ + if name and prefix: + raise RuntimeError("Only one of 'name' or 'prefix' must be given.") + + if not name and not prefix: + raise RuntimeError("One of 'name' or 'prefix' must be given.") + + # TODO: not implemented yet + + def updateAllPackages(self, name="", prefix=""): + """ + Public method to update all packages of a conda environment. + + @param name name of the environment + @type str + @param prefix prefix of the environment + @type str + @return list of installed packages. Each entry is a tuple containing + the package name, version and build. + @rtype list of tuples of (str, str, str) + @rtype bool + @exception RuntimeError raised to indicate an error in parameters + + Note: only one of name or prefix must be given. + """ + if name and prefix: + raise RuntimeError("Only one of 'name' or 'prefix' must be given.") + + if not name and not prefix: + raise RuntimeError("One of 'name' or 'prefix' must be given.") + + # TODO: not implemented yet + + def installPackages(self, packages, name="", prefix=""): + """ + Public method to install packages into a conda environment. + + @param packages list of package names to be installed + @type list of str + @param name name of the environment + @type str + @param prefix prefix of the environment + @type str + @return list of installed packages. Each entry is a tuple containing + the package name, version and build. + @rtype list of tuples of (str, str, str) + @rtype bool + @exception RuntimeError raised to indicate an error in parameters + + Note: only one of name or prefix must be given. + """ + if name and prefix: + raise RuntimeError("Only one of 'name' or 'prefix' must be given.") + + if not name and not prefix: + raise RuntimeError("One of 'name' or 'prefix' must be given.") + + # TODO: not implemented yet + + def uninstallPackages(self, packages, name="", prefix=""): + """ + Public method to uninstall packages of a conda environment. + + @param packages list of package names to be uninstalled + @type list of str + @param name name of the environment + @type str + @param prefix prefix of the environment + @type str + @return list of installed packages. Each entry is a tuple containing + the package name, version and build. + @rtype list of tuples of (str, str, str) + @rtype bool + @exception RuntimeError raised to indicate an error in parameters + + Note: only one of name or prefix must be given. + """ + if name and prefix: + raise RuntimeError("Only one of 'name' or 'prefix' must be given.") + + if not name and not prefix: + raise RuntimeError("One of 'name' or 'prefix' must be given.") + + # TODO: not implemented yet