From 3fdce74a8a15b26fb0edbf569beb912060c66e2a Mon Sep 17 00:00:00 2001 From: Martin Salinas Date: Fri, 30 Jun 2023 18:29:13 +0200 Subject: [PATCH 1/8] Improved installer With this update, the use of target files by the user is completely optional now and the install helper can generate proper target files whenever the user does not provide its own, creating a greater layer of abstraction in the installation process. --- scipion/install/funcs.py | 74 ++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/scipion/install/funcs.py b/scipion/install/funcs.py index 784708bc..93340034 100644 --- a/scipion/install/funcs.py +++ b/scipion/install/funcs.py @@ -907,6 +907,11 @@ def __init__(self, packageName: str, packageHome: str=None, packageVersion: str= packageHome (str): Optional. Path to the package. It can be absolute or relative to current directory. packageVersion (str): Optional. Package version. """ + # Temporary variables to store target names + self.__genericCommands = 0 + self.__condaCommands = 0 + self.__extraFiles = 0 + # Private list of tuples containing commands with targets self.__commandList = [] @@ -1003,18 +1008,18 @@ def importCommandList(self, commandList: List[Tuple[str, str]]): self.__commandList.extend(commandList) return self - def addCommand(self, command: str, targetName: str, workDir: str=''): + def addCommand(self, command: str, targetName: str='', workDir: str=''): """ ### This function adds the given command with target to the command list. ### The target file needs to be located inside packageHome's directory so Scipion can detect it. #### Parameters: command (str): Command to be added. - targetName (str): Name of the target file to be produced after commands are completed successfully. + targetName (str): Optional. Name of the target file to be produced after commands are completed successfully. workDir (str): Optional. Directory where the command will be executed from. #### Usage: - installer.addCommand('python3 myScript.py', 'MYSCRIPT_COMPLETED', workDir='/home/user/Documents/otherDirectory') + installer.addCommand('python3 myScript.py', targetName='MYSCRIPT_COMPLETED', workDir='/home/user/Documents/otherDirectory') #### This function call will generate the following commands: cd /home/user/Documents/otherDirectory && python3 myScript.py && touch /home/user/scipion/software/em/test-package-1.0/MYSCRIPT_COMPLETED @@ -1023,6 +1028,9 @@ def addCommand(self, command: str, targetName: str, workDir: str=''): workDirCmd = 'cd {} && '.format(workDir) if workDir else '' # Getting target name + if not targetName: + targetName = f'COMMAND_{self.__genericCommands}' + self.__genericCommands += 1 fullTargetName = os.path.join(self.__packageHome, targetName) command = (workDirCmd + command) if workDir else command @@ -1047,16 +1055,17 @@ def addCommands(self, commandList: List[str], binaryName: str=None, workDir:str= cd /home/user/Documents/otherDirectory && python3 myScript.py && touch /home/user/scipion/software/em/test-package-1.0/MYSCRIPT_COMPLETED\n cd /home/user/Documents/otherDirectory && ls && touch /home/user/scipion/software/em/test-package-1.0/DIRECTORY_LISTED """ + # Checking if introduced target name list and command list have same size + if targetNames and len(commandList) != len(targetNames): + raise RuntimeError("Error: Introduced target name list is of size {}, but command list is of size {}.".format(len(targetNames), len(commandList))) + # Defining binary name binaryName = self.__getBinaryNameAndVersion(binaryName=binaryName)[0] - # Defining default target name preffix - defaultTargetPreffix = '{}_EXTRA_COMMAND_'.format(binaryName.upper()) - # Executing commands for idx in range(len(commandList)): - targetName = targetNames[idx] if targetNames else (defaultTargetPreffix + str(idx)) - self.addCommand(commandList[idx], targetName, workDir=workDir) + targetName = targetNames[idx] if targetNames else '' + self.addCommand(commandList[idx], targetName=targetName, workDir=workDir) return self @@ -1184,7 +1193,9 @@ def addCondaPackages(self, packages: List[str], binaryName: str=None, binaryVers binaryName, binaryVersion = self.__getBinaryNameAndVersion(binaryName=binaryName, binaryVersion=binaryVersion) # Defininig target name - targetName = targetName if targetName else '{}_CONDA_PACKAGES_INSTALLED'.format(binaryName.upper()) + if not targetName: + targetName = 'CONDA_COMMAND_{}'.format(self.__condaCommands) + self.__condaCommands += 1 # Adding installation command command = "{} {} && conda install -y {}".format(pwem.Plugin.getCondaActivationCmd(), self.__getEnvActivationCommand(binaryName, binaryVersion=binaryVersion), ' '.join(packages)) @@ -1194,7 +1205,7 @@ def addCondaPackages(self, packages: List[str], binaryName: str=None, binaryVers return self - def getExtraFile(self, url: str, targetName: str, location: str=".", workDir: str='', fileName: str=None): + def getExtraFile(self, url: str, targetName: str='', location: str=".", workDir: str='', fileName: str=None): """ ### This function creates the command to download with wget the file in the given link into the given path. ### The downloaded file will overwrite a local one if they have the same name. @@ -1202,13 +1213,13 @@ def getExtraFile(self, url: str, targetName: str, location: str=".", workDir: st #### Parameters: url (str): URL of the resource to download. - targetName (str): Name of the target file for this command. + targetName (str): Optional. Name of the target file for this command. location (str): Optional. Location where the file will be downloaded. It can be absolute or relative to current directory. workDir (str): Optional. Directory where the file will be downloaded from. fileName (str): Optional. Name of the file after the download. Use intended for cases when expected name differs from url name. #### Usage: - installer.getExtraFile('https://site.com/myfile.tar', 'FILE_DOWNLOADED', location='/home/user/scipion/software/em/test-package-1.0/subdirectory', workDir='/home/user', fileName='test.tar') + installer.getExtraFile('https://site.com/myfile.tar', targetName='FILE_DOWNLOADED', location='/home/user/scipion/software/em/test-package-1.0/subdirectory', workDir='/home/user', fileName='test.tar') #### This function call will generate the following command: cd /home/user && mkdir -p /home/user/scipion/software/em/test-package-1.0/subdirectory && @@ -1218,9 +1229,14 @@ def getExtraFile(self, url: str, targetName: str, location: str=".", workDir: st fileName = fileName if fileName else os.path.basename(url) mkdirCmd = "mkdir -p {} && ".format(location) if location else '' + # Defining target file name + if not targetName: + targetName = 'EXTRA_FILE_{}'.format(self.__extraFiles) + self.__extraFiles += 1 + downloadCmd = "{}wget -O {} {}".format(mkdirCmd, os.path.join(location, fileName), url) - self.addCommand(downloadCmd, targetName, workDir=workDir) - + self.addCommand(downloadCmd, targetName=targetName, workDir=workDir) + return self def getExtraFiles(self, fileList: List[Dict[str, str]], binaryName: str=None, workDir: str='', targetNames: List[str]=None): @@ -1251,12 +1267,13 @@ def getExtraFiles(self, fileList: List[Dict[str, str]], binaryName: str=None, wo cd /home/user && mkdir -p /home/user/scipion/software/em/test-package-1.0/subdirectory2 && wget -O /home/user/scipion/software/em/test-package-1.0/subdirectory2/test2.tar2 https://site.com/myfile.tar2 && touch /home/user/scipion/software/em/test-package-1.0/DOWNLOADED_FILE_2 """ + # Checking if introduced target name list and file list have same size + if targetNames and len(fileList) != len(targetNames): + raise RuntimeError("Error: Introduced target name list is of size {}, but file list is of size {}.".format(len(targetNames), len(fileList))) + # Defining binary name binaryName = self.__getBinaryNameAndVersion(binaryName=binaryName)[0] - # Default preffix for target names - defaultTargetPreffix = "{}_FILE_".format(binaryName.upper()) - # For each file in the list, download file for idx in range(len(fileList)): # Checking if file dictionary contains url @@ -1271,9 +1288,9 @@ def getExtraFiles(self, fileList: List[Dict[str, str]], binaryName: str=None, wo kwargs['path'] = fileList[idx]['path'] downloadable = fileList[idx] if ('path' in fileList[idx] and 'name' in fileList[idx]) else self.getFileDict(fileList[idx]['url'], **kwargs) - targetName = targetNames[idx] if targetNames else (defaultTargetPreffix + str(idx)) - self.getExtraFile(downloadable['url'], targetName, location=downloadable['path'], workDir=workDir, fileName=downloadable['name']) - + targetName = targetNames[idx] if targetNames else '' + self.getExtraFile(downloadable['url'], targetName=targetName, location=downloadable['path'], workDir=workDir, fileName=downloadable['name']) + return self def addPackage(self, env, dependencies: List[str]=[], default: bool=True, **kwargs): @@ -1294,9 +1311,22 @@ def addPackage(self, env, dependencies: List[str]=[], default: bool=True, **kwar #--------------------------------------- PUBLIC UTILS FUNCTIONS ---------------------------------------# def getFileDict(self, url: str, path: str='.', fileName: str=None) -> Dict[str, str]: - """ This function generates the dictionary for a downloadable file. """ + """ + ### This function generates the dictionary for a downloadable file. + + #### Parameters: + url (str): Url of the file to download. + path (str): Optional. Relative or absolute path to download the file to. + fileName (str): Optional. Local file name intented for that file after the download. + + #### Returns: + (dict[str, str]): Dictionary prepared for the download of one file for function getExtraFiles. + + #### Usage: + getFileDict('https://www.mywebsite.com/downloads/file.tar.gz', path='/path/to/myfile', fileName='newFile.tar.gz') + """ # Getting file name fileName = fileName if fileName else os.path.basename(url) # Returning dictionary - return {'url': url, 'path': path, 'name': fileName} + return {'url': url, 'path': path, 'name': fileName} From 410012085ba6974ff6fc9f48c32b03b644872e4f Mon Sep 17 00:00:00 2001 From: Martin Salinas Date: Fri, 30 Jun 2023 18:30:36 +0200 Subject: [PATCH 2/8] Better comment --- scipion/install/funcs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scipion/install/funcs.py b/scipion/install/funcs.py index 93340034..632b981b 100644 --- a/scipion/install/funcs.py +++ b/scipion/install/funcs.py @@ -907,7 +907,7 @@ def __init__(self, packageName: str, packageHome: str=None, packageVersion: str= packageHome (str): Optional. Path to the package. It can be absolute or relative to current directory. packageVersion (str): Optional. Package version. """ - # Temporary variables to store target names + # Temporary variables to store the count for autogenerated target files self.__genericCommands = 0 self.__condaCommands = 0 self.__extraFiles = 0 From d8700e347429eb639cc3907ad66f4b4d923e7b3c Mon Sep 17 00:00:00 2001 From: pconesa Date: Tue, 4 Jul 2023 17:52:25 +0200 Subject: [PATCH 3/8] fix template validation call project with list --- scipion/__main__.py | 11 ++++++++++- scipion/scripts/kickoff.py | 11 +++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/scipion/__main__.py b/scipion/__main__.py index d76a5f2c..ac270f50 100755 --- a/scipion/__main__.py +++ b/scipion/__main__.py @@ -278,7 +278,16 @@ def main(): from pyworkflow.utils.log import LoggingConfigurator LoggingConfigurator.setUpGUILogging() from pyworkflow.apps.pw_project import openProject - arg = sys.argv[2] if mode == MODE_PROJECT else mode + + if mode == MODE_PROJECT: + if len(sys.argv)==3: + arg = sys.argv[2] + + else: + arg = "list" #TODO, import LIST from pyworkflow.apps.pw_project + else: + arg = mode + openProject(arg) elif mode == MODE_TESTS or mode == MODE_TEST: diff --git a/scipion/scripts/kickoff.py b/scipion/scripts/kickoff.py index 739e2608..f8422c4a 100644 --- a/scipion/scripts/kickoff.py +++ b/scipion/scripts/kickoff.py @@ -147,7 +147,7 @@ def _onClosing(self): class KickoffView(tk.Frame): - def __init__(self, parent, windows, template=None, argsList=[], + def __init__(self, parent, windows, template:Template=None, argsList=[], showScheduleOption=True, schedule=True, showProjectOption=True, showProject=True, showProjectName=True, **kwargs): @@ -282,9 +282,12 @@ def _onReadDataFromTemplateForm(self, e=None): for field in self.template.params.values(): newValue = self._getValue(field.getTitle()) field.setValue(newValue) - if not field.validate(): - errors.append("%s value does not validate. Value: %s, Type: %s" - % (field.getTitle(), field.getValue(), + + validationMsg = field.validate() + + if validationMsg: + errors.append("%s value does not validate: %s. Value: %s, Type: %s." + % (field.getTitle(), validationMsg, field.getValue(), field.getType())) # Do more checks only if there are no previous errors From 5304200eb880b81361b7d441b7ff3e29a7b843e2 Mon Sep 17 00:00:00 2001 From: pconesa Date: Tue, 1 Aug 2023 09:09:38 +0200 Subject: [PATCH 4/8] - Update message is green now - SCIPION_DONT_INSTALL_BINARIES is used in the plugin manager to initialize "Skip binaries" check box --- CHANGES.txt | 4 +++- scipion/install/plugin_manager.py | 5 ++--- scipion/install/update_manager.py | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 429cddcc..c893e395 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,6 @@ - +V3.2.0 + - Update message is green now + - SCIPION_DONT_INSTALL_BINARIES is used in the plugin manager to initialize "Skip binaries" check box v3.1.0 users: - Fixing an error related with the Plugin Manager when clicking the plugin treeview diff --git a/scipion/install/plugin_manager.py b/scipion/install/plugin_manager.py index 1d67aa09..30639e7e 100644 --- a/scipion/install/plugin_manager.py +++ b/scipion/install/plugin_manager.py @@ -27,12 +27,11 @@ from tkinter import * import threading -from pyworkflow import Config from pyworkflow.gui.project import ProjectManagerWindow from pyworkflow.project import MenuConfig from pyworkflow.gui import * import pyworkflow.gui.dialog as pwgui -from scipion.install.plugin_funcs import PluginRepository, PluginInfo, NULL_VERSION +from scipion.install.plugin_funcs import PluginRepository, PluginInfo, NULL_VERSION, installBinsDefault from pyworkflow.utils.properties import * from pyworkflow.utils import redStr, makeFilePath @@ -434,7 +433,7 @@ def _fillToolbar(self, frame): # Add option to cancel binaries installation self._col += 1 self.skipBinaries = tk.BooleanVar() - self.skipBinaries.set(False) + self.skipBinaries.set(not installBinsDefault()) installBinsEntry = tk.Checkbutton(frame, variable=self.skipBinaries, font=getDefaultFont(), text="Skip binaries") installBinsEntry.grid(row=0, column=self._col, sticky='ew', padx=5) diff --git a/scipion/install/update_manager.py b/scipion/install/update_manager.py index 341389d0..fa8e3095 100644 --- a/scipion/install/update_manager.py +++ b/scipion/install/update_manager.py @@ -92,7 +92,7 @@ def getPackagesStatus(cls, printAll=True): if needToUpdate: outdatedPackages.append((package[0], version)) print( - redStr('The package %s is out of date. Your version is %s, ' + greenStr('The package %s is out of date. Your version is %s, ' 'the latest is %s.' % (package[0], package[1], version))) elif printAll: From ce5e40ba5ed4cc3f0feb4b2ecb36969e054deb38 Mon Sep 17 00:00:00 2001 From: Grigory Sharov Date: Sat, 5 Aug 2023 15:20:14 +0100 Subject: [PATCH 5/8] Do not raise error when one of the CUDA env vars is not set --- CHANGES.txt | 1 + scipion/install/funcs.py | 16 ++-------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c893e395..065aa8bc 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,7 @@ V3.2.0 - Update message is green now - SCIPION_DONT_INSTALL_BINARIES is used in the plugin manager to initialize "Skip binaries" check box + - Do not raise error when one of the CUDA env vars is not set v3.1.0 users: - Fixing an error related with the Plugin Manager when clicking the plugin treeview diff --git a/scipion/install/funcs.py b/scipion/install/funcs.py index 632b981b..8e078945 100644 --- a/scipion/install/funcs.py +++ b/scipion/install/funcs.py @@ -796,22 +796,10 @@ def updateCudaEnviron(self, package): environ = os.environ.copy() - # If there isn't any CUDA in the environment - if cudaLib is None and cudaBin is None: - # Exit ...do not update the environment - return environ - - elif cudaLib is not None and cudaBin is None: - raise Exception("CUDA_LIB (or %s_CUDA_LIB) is defined, but not " - "CUDA_BIN (or %s_CUDA_BIN), please execute " - "scipion config --update" % (packUpper, packUpper)) - elif cudaBin is not None and cudaLib is None: - raise Exception("CUDA_BIN (or %s_CUDA_BIN) is defined, but not " - "CUDA_LIB (or %s_CUDA_LIB), please execute " - "scipion config --update" % (packUpper, packUpper)) - elif os.path.exists(cudaLib) and os.path.exists(cudaBin): + if os.path.exists(cudaLib): environ.update({'LD_LIBRARY_PATH': cudaLib + ":" + environ['LD_LIBRARY_PATH']}) + if os.path.exists(cudaBin): environ.update({'PATH': cudaBin + ":" + environ['PATH']}) return environ From 5c6e382effb0b8f14f3662cd9a20dd60cfc3bfc7 Mon Sep 17 00:00:00 2001 From: pconesa Date: Fri, 18 Aug 2023 17:36:29 +0200 Subject: [PATCH 6/8] - Exist code is not masked when running xmipp, relion etc commands - CommandDef and CondaCommandDef assist in the definition of commands for the binaries --- CHANGES.txt | 4 ++ scipion/__main__.py | 8 +-- scipion/install/funcs.py | 121 ++++++++++++++++++++++++++++++++++ scipion/tests/installation.py | 24 +++++++ 4 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 scipion/tests/installation.py diff --git a/CHANGES.txt b/CHANGES.txt index 065aa8bc..b30fb7fa 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,7 @@ +V3.3.0 +developers: + - Exist code is not masked when running xmipp, relion etc commands + - CommandDef and CondaCommandDef assist in the definition of commands for the binaries V3.2.0 - Update message is green now - SCIPION_DONT_INSTALL_BINARIES is used in the plugin manager to initialize "Skip binaries" check box diff --git a/scipion/__main__.py b/scipion/__main__.py index ac270f50..7a464c13 100755 --- a/scipion/__main__.py +++ b/scipion/__main__.py @@ -30,6 +30,7 @@ """ Main entry point to scipion. It launches the gui, tests, etc. """ +import subprocess import sys import os from os.path import join, exists, expanduser, expandvars @@ -104,10 +105,9 @@ def runCmd(cmd, args=''): cmd = '%s %s' % (cmd, args) os.environ.update(VARS) - # sys.stdout.write(">>>>> %s\n" % cmd) - result = os.system(cmd) - if not -256 < result < 256: - result = 1 # because if not, 256 is confused with 0 ! + # result = os.system(cmd) + # Replacement of os.system with subprocess.call(cmd, shell=True) + result = subprocess.call(cmd, shell=True) sys.exit(result) diff --git a/scipion/install/funcs.py b/scipion/install/funcs.py index 8e078945..7145f8ab 100644 --- a/scipion/install/funcs.py +++ b/scipion/install/funcs.py @@ -39,6 +39,7 @@ from pyworkflow import Config import pwem from typing import List, Tuple, Dict +from typing_extensions import Self # Then we get some OS vars MACOSX = (platform.system() == 'Darwin') @@ -857,6 +858,126 @@ def createPackageLink(self, packageLink, packageFolder): print("Created link: %s" % linkText) +class CommandDef: + """ Basic command class to hold the command string and the targets""" + def __init__(self, cmd:str, targets:list=[]): + """ Constructor + + e.g.: Command("git clone .../myrepo", "myrepo") + + :param cmd: String with the command/s to run. + :param targets: Optional, a list or a string with file/s or folder/s that should exist as + a consequence of the commands. + + """ + self._cmds = [] + self.new(cmd, targets) + + def new(self, cmd='', targets=None): + """ Creates a new command element becoming the current command to do appends on it""" + + self._cmds.append([cmd, []]) + self.addTarget(targets) + return self + + def addTarget(self, targets: list): + """ Centralized internal method to add targets. They could be a list of string commands or a single command""" + if targets is not None: + lastTargets = self._cmds[-1][1] + + lastTargets.extend(targets if isinstance(targets, list) else [targets]) + + def getCommands(self)->list: + """ Returns the commands""" + return self._cmds + + def append(self, newCmd:str, targets=None, sep="&&")->Self: + """ Appends an extra command to the existing one. + + :param newCmd: New command to append + :param targets: Optional, additional targets in case this command produce them + :param sep: Optional, separator used between the existing command and this new added one. (&&) + + :return itself Command + """ + # Get the last command, target tuple + lastCmdTarget = self._cmds[-1] + + cmd = lastCmdTarget[0] + + # If there is something already + if cmd: + cmd = "%s %s %s" % (cmd , sep, newCmd) + else: + cmd = newCmd + + lastCmdTarget[0] = cmd + + self.addTarget(targets) + + return self + + def cd(self, folder): + """ Appends a cd command to the existing one + + :param folder: folder to changes director to + """ + return self.append("cd %s" % folder) + + def touch(self, fileName): + """ Appends a touch command and its target based on the fileName + + :param fileName: file to touch. Should be created in the binary home folder. Use ../ in case of a previous cd command + + :return: CondaCommandDef (self) + """ + + return self.append("touch %s" % fileName, os.path.basename(fileName)) + + +class CondaCommandDef(CommandDef): + """ Extends CommandDef with some conda specific methods""" + + ENV_CREATED = "env-created.txt" + + def __init__(self, envName, condaActivationCmd=''): + + self._condaActivationCmd = condaActivationCmd.replace("&&", "") + super().__init__("", None) + + self._envName=envName + + def create(self, extraCmds=''): + """ Creates a conda environment with extra commands if passed + + :param extraCmds: additional commands (string) after the conda create -n envName + + :return: CondaCommandDef (self) + + """ + self.append(self._condaActivationCmd) + self.append("conda create -y -n %s %s" % (self._envName, extraCmds)) + return self.touch("env_created.txt") + + def pipInstall(self, packages): + """ Appends pip install to the existing command adding packages""" + + return self.append("python -m pip install %s" % packages) + + def condaInstall(self, packages): + """ Appends conda install to the existing command adding packages""" + + return self.append("conda install %s" % packages) + + def activate(self, appendCondaActivation=False): + """ Activates the conda environment + + :param appendCondaActivation: Pass true to prepend the conda activation command""" + if appendCondaActivation: + self.append(self._condaActivationCmd) + + return self.append("conda activate %s" % self._envName) + def mkdir(path): """ Creates a folder if it does not exist""" if not exists(path): diff --git a/scipion/tests/installation.py b/scipion/tests/installation.py new file mode 100644 index 00000000..7f7b1c5f --- /dev/null +++ b/scipion/tests/installation.py @@ -0,0 +1,24 @@ +import unittest +from scipion.install.funcs import CommandDef, CondaCommandDef + +class TestCommands(unittest.TestCase): + def test_command_class(self): + + myCmd = CommandDef("ls -l", "lolo")\ + .append("cd ..", ["one", "two"])\ + .append("cd .", sep="?") + + self.assertEqual(myCmd.getCommands()[0][0], "ls -l && cd .. ? cd .") + self.assertEqual(myCmd.getCommands()[0][1], ["lolo", "one", "two"]) + + cmds = CondaCommandDef("modelangelo-3.0") + cmds.create('python=3.9').activate().cd('model-angelo')\ + .pipInstall('-r requirements.txt')\ + .condaInstall('-y torchvision torchaudio cudatoolkit=11.3 -c pytorch')\ + .pipInstall('-e .').touch('../env-installed.txt') + + print(cmds.getCommands()) + + +if __name__ == '__main__': + unittest.main() From 9a97e6e7b8cee913307624d334d99385208db98d Mon Sep 17 00:00:00 2001 From: Grigory Sharov Date: Sun, 27 Aug 2023 13:08:50 +0100 Subject: [PATCH 7/8] add missing requirement, update version to match the changelog --- requirements.txt | 1 + scipion/__init__.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a439c80a..919ed6d8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ scipion-em outdated==0.2.2 +typing_extensions diff --git a/scipion/__init__.py b/scipion/__init__.py index 4e2487c2..9ea07ba3 100644 --- a/scipion/__init__.py +++ b/scipion/__init__.py @@ -1,2 +1,2 @@ -__version__ = '3.1.0' +__version__ = '3.3.0' From 81be6aa54ebf727b9f275710730c351af24b1b79 Mon Sep 17 00:00:00 2001 From: pconesa Date: Fri, 22 Sep 2023 09:37:59 +0200 Subject: [PATCH 8/8] tolerate missing cudabin --- scipion/install/funcs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scipion/install/funcs.py b/scipion/install/funcs.py index 7145f8ab..3660e5ca 100644 --- a/scipion/install/funcs.py +++ b/scipion/install/funcs.py @@ -799,8 +799,8 @@ def updateCudaEnviron(self, package): if os.path.exists(cudaLib): environ.update({'LD_LIBRARY_PATH': cudaLib + ":" + - environ['LD_LIBRARY_PATH']}) - if os.path.exists(cudaBin): + environ.get('LD_LIBRARY_PATH',"")}) + if cudaBin and os.path.exists(cudaBin): environ.update({'PATH': cudaBin + ":" + environ['PATH']}) return environ