From 15d6757c6aabf9141bf0eb2a1bac7d3a3924ccab Mon Sep 17 00:00:00 2001 From: "teodora.misan" Date: Thu, 21 Nov 2024 14:33:55 +0200 Subject: [PATCH 1/5] EBR-121: add .version file for keeping generated folders updated after a new release is made on lab --- tvbextxircuits/start_xircuits.py | 50 ++++++++++++++++++++++++++++---- tvbextxircuits/utils.py | 6 ++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/tvbextxircuits/start_xircuits.py b/tvbextxircuits/start_xircuits.py index 2679f114..a79d9e45 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 @@ -14,9 +14,49 @@ def init_xircuits(): 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('xai_components', '', 'xai_components') + + # Create a version file for keeping generated folders in sync after a new release is installed + version_file = Path(os.getcwd()) / '.version' + current_version = get_extension_version() + version_file.write_text(current_version) + + +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.error("Version file not found.") + return + + 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 @@ -125,7 +165,7 @@ def init_configs(): ) config_path = Path(os.getcwd()) / ".xircuits" - if not config_path.exists(): + if not config_path.exists() or version_changed(): init_xircuits() save_component_library_config() diff --git a/tvbextxircuits/utils.py b/tvbextxircuits/utils.py index d5bb1718..8c618d64 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 @@ -28,6 +30,10 @@ def copy_from_installed_wheel(package_name, resource="", dest_path=None): # Get the resource reference ref = importlib_resources.files(package_name) / resource + config_path = Path(os.getcwd()) / dest_path + # If the path already exists it means a new version of the package is available, so a cleanup need to be done + if config_path.exists(): + shutil.rmtree(config_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 From 4e78baed79001b3bf09b840ffd83f33418f5ff90 Mon Sep 17 00:00:00 2001 From: "teodora.misan" Date: Tue, 26 Nov 2024 10:27:55 +0200 Subject: [PATCH 2/5] EBR-121: check changes in folders before deletion --- tvbextxircuits/utils.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tvbextxircuits/utils.py b/tvbextxircuits/utils.py index 8c618d64..996b57af 100644 --- a/tvbextxircuits/utils.py +++ b/tvbextxircuits/utils.py @@ -1,3 +1,4 @@ +import filecmp from pathlib import Path STORAGE_CONFIG_FILE = 'storage_config.json' # To be used only for HPC runs @@ -23,6 +24,13 @@ def is_valid_url(url): except ValueError: return False +def are_folders_identical(resource_path, dest_path): + """ + Check if two folders are identical. + """ + comparison_dir = filecmp.dircmp(resource_path, dest_path) + return not (comparison_dir.left_only or comparison_dir.right_only or comparison_dir.diff_files) + def copy_from_installed_wheel(package_name, resource="", dest_path=None): if dest_path is None: dest_path = package_name @@ -31,9 +39,10 @@ def copy_from_installed_wheel(package_name, resource="", dest_path=None): ref = importlib_resources.files(package_name) / resource config_path = Path(os.getcwd()) / dest_path - # If the path already exists it means a new version of the package is available, so a cleanup need to be done - if config_path.exists(): - shutil.rmtree(config_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 config_path.exists() and not are_folders_identical(resource_path, dest_path): + shutil.rmtree(config_path) + shutil.copytree(resource_path, dest_path, dirs_exist_ok=True) + elif not config_path.exists(): + shutil.copytree(resource_path, dest_path) \ No newline at end of file From edc8b00558d01480b609117cfd0e4eee8fe27c89 Mon Sep 17 00:00:00 2001 From: "teodora.misan" Date: Tue, 26 Nov 2024 13:55:10 +0200 Subject: [PATCH 3/5] EBR-121: refactor code --- .gitignore | 1 + tvbextxircuits/start_xircuits.py | 26 +++++++++++++++----------- tvbextxircuits/utils.py | 15 +++------------ 3 files changed, 19 insertions(+), 23 deletions(-) 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 a79d9e45..fafd564f 100644 --- a/tvbextxircuits/start_xircuits.py +++ b/tvbextxircuits/start_xircuits.py @@ -11,15 +11,19 @@ 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') - 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 - version_file = Path(os.getcwd()) / '.version' - current_version = get_extension_version() - version_file.write_text(current_version) + 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(): @@ -35,8 +39,8 @@ def version_changed(): return if not version_file.exists(): - LOGGER.error("Version file not found.") - return + LOGGER.info("Version file not found.") + return True try: stored_version = version_file.read_text().strip() @@ -163,10 +167,10 @@ def init_configs(): ====================================== ''' ) - + vers_changed = version_changed() config_path = Path(os.getcwd()) / ".xircuits" - if not config_path.exists() or version_changed(): - 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 996b57af..c610f375 100644 --- a/tvbextxircuits/utils.py +++ b/tvbextxircuits/utils.py @@ -24,14 +24,7 @@ def is_valid_url(url): except ValueError: return False -def are_folders_identical(resource_path, dest_path): - """ - Check if two folders are identical. - """ - comparison_dir = filecmp.dircmp(resource_path, dest_path) - return not (comparison_dir.left_only or comparison_dir.right_only or comparison_dir.diff_files) - -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 @@ -41,8 +34,6 @@ def copy_from_installed_wheel(package_name, resource="", dest_path=None): config_path = Path(os.getcwd()) / dest_path # Create the temporary file context with importlib_resources.as_file(ref) as resource_path: - if config_path.exists() and not are_folders_identical(resource_path, dest_path): + if config_path.exists() and version_changed: shutil.rmtree(config_path) - shutil.copytree(resource_path, dest_path, dirs_exist_ok=True) - elif not config_path.exists(): - shutil.copytree(resource_path, dest_path) \ No newline at end of file + shutil.copytree(resource_path, dest_path) From 7e2e95f097a7fda52297eba2877a23618c10e96f Mon Sep 17 00:00:00 2001 From: romina1601 Date: Tue, 26 Nov 2024 14:25:50 +0200 Subject: [PATCH 4/5] EBR-121. Refactor condition for generating folder --- tvbextxircuits/start_xircuits.py | 2 +- tvbextxircuits/utils.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tvbextxircuits/start_xircuits.py b/tvbextxircuits/start_xircuits.py index fafd564f..1155f280 100644 --- a/tvbextxircuits/start_xircuits.py +++ b/tvbextxircuits/start_xircuits.py @@ -40,7 +40,7 @@ def version_changed(): if not version_file.exists(): LOGGER.info("Version file not found.") - return True + return False try: stored_version = version_file.read_text().strip() diff --git a/tvbextxircuits/utils.py b/tvbextxircuits/utils.py index c610f375..02fefaca 100644 --- a/tvbextxircuits/utils.py +++ b/tvbextxircuits/utils.py @@ -34,6 +34,7 @@ def copy_from_installed_wheel(package_name, resource="", dest_path=None, version config_path = Path(os.getcwd()) / dest_path # Create the temporary file context with importlib_resources.as_file(ref) as resource_path: - if config_path.exists() and version_changed: - shutil.rmtree(config_path) - shutil.copytree(resource_path, dest_path) + if not config_path.exists() or version_changed: + if config_path.exists(): + shutil.rmtree(config_path) + shutil.copytree(resource_path, dest_path) From f91fb8f6601a3fd686dff9ee8a2fdda6ec2efeaf Mon Sep 17 00:00:00 2001 From: "teodora.misan" Date: Tue, 26 Nov 2024 15:15:55 +0200 Subject: [PATCH 5/5] EBR-121: remove import --- tvbextxircuits/utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tvbextxircuits/utils.py b/tvbextxircuits/utils.py index 02fefaca..75b4b0e1 100644 --- a/tvbextxircuits/utils.py +++ b/tvbextxircuits/utils.py @@ -1,4 +1,3 @@ -import filecmp from pathlib import Path STORAGE_CONFIG_FILE = 'storage_config.json' # To be used only for HPC runs