diff --git a/.gitignore b/.gitignore index 45e58f1a..4122d90a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ share/python-wheels/ .installed.cfg *.egg MANIFEST +.version # PyInstaller # Usually these files are written by a python script from a template diff --git a/tvbextxircuits/start_xircuits.py b/tvbextxircuits/start_xircuits.py index 2679f114..1155f280 100644 --- a/tvbextxircuits/start_xircuits.py +++ b/tvbextxircuits/start_xircuits.py @@ -1,7 +1,7 @@ import argparse +import importlib.metadata from pathlib import Path import os -from .handlers.request_folder import request_folder from .utils import is_empty, copy_from_installed_wheel from .library import list_component_library, install_library, fetch_library, save_component_library_config from .compiler import compile @@ -11,12 +11,56 @@ LOGGER = get_logger(__name__) -def init_xircuits(): +def init_xircuits(vers_changed=False): package_name = 'tvbextxircuits' - copy_from_installed_wheel(package_name, resource='.xircuits', dest_path='.xircuits') - component_library_path = Path(os.getcwd()) / "xai_components" - if not component_library_path.exists(): - copy_from_installed_wheel('xai_components', '', 'xai_components') + copy_from_installed_wheel(package_name, resource='.xircuits', dest_path='.xircuits', version_changed=vers_changed) + copy_from_installed_wheel('xai_components', '', 'xai_components', version_changed=vers_changed) + + # Create a version file for keeping generated folders in sync after a new release is installed + try: + version_file = Path(os.getcwd()) / '.version' + current_version = get_extension_version() + version_file.write_text(current_version) + LOGGER.info("Create version file.") + except Exception as e: + LOGGER.error(f"Error handling version file: {e}") + + +def version_changed(): + """ + Compares user's current version with the version installed on lab. + If they differ, a new version is available. + """ + version_file = Path(os.getcwd()) / '.version' + installed_version = get_extension_version() + + if not installed_version: + LOGGER.error("Not able to retrieve the installed version.") + return + + if not version_file.exists(): + LOGGER.info("Version file not found.") + return False + + try: + stored_version = version_file.read_text().strip() + except Exception as e: + LOGGER.error(f"Error reading version file: {e}") + stored_version = None + + return stored_version != installed_version + +def get_extension_version(): + """ + Retrieves current version of the package + """ + try: + version = importlib.metadata.version("tvb-ext-xircuits") + return version + except importlib.metadata.PackageNotFoundError: + LOGGER.error("Package 'tvb-ext-xircuits' is not installed.") + return None + def cmd_start_xircuits(args, extra_args=[]): # fetch xai_components @@ -123,10 +167,10 @@ def init_configs(): ====================================== ''' ) - + vers_changed = version_changed() config_path = Path(os.getcwd()) / ".xircuits" - if not config_path.exists(): - init_xircuits() + if not config_path.exists() or vers_changed: + init_xircuits(vers_changed) save_component_library_config() diff --git a/tvbextxircuits/utils.py b/tvbextxircuits/utils.py index d5bb1718..75b4b0e1 100644 --- a/tvbextxircuits/utils.py +++ b/tvbextxircuits/utils.py @@ -1,3 +1,5 @@ +from pathlib import Path + STORAGE_CONFIG_FILE = 'storage_config.json' # To be used only for HPC runs COLLAB_NAME_KEY = 'collab_name' # Used only for HPC runs BUCKET_NAME_KEY = 'bucket_name' # Used only for HPC runs @@ -21,13 +23,17 @@ def is_valid_url(url): except ValueError: return False -def copy_from_installed_wheel(package_name, resource="", dest_path=None): +def copy_from_installed_wheel(package_name, resource="", dest_path=None, version_changed=False): if dest_path is None: dest_path = package_name # Get the resource reference ref = importlib_resources.files(package_name) / resource + config_path = Path(os.getcwd()) / dest_path # Create the temporary file context with importlib_resources.as_file(ref) as resource_path: - shutil.copytree(resource_path, dest_path) \ No newline at end of file + if not config_path.exists() or version_changed: + if config_path.exists(): + shutil.rmtree(config_path) + shutil.copytree(resource_path, dest_path)