From 9379dfa7e67f06cc5188ab6ed28ea3bf4ec6b8af Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Fri, 15 Sep 2023 13:19:17 +0100 Subject: [PATCH] add upgrade_iblrig command --- iblrig/base_tasks.py | 2 +- iblrig/gui/wizard.py | 2 +- iblrig/version_management.py | 107 +++++++++++++++++++++++++++-------- pyproject.toml | 1 + 4 files changed, 85 insertions(+), 27 deletions(-) diff --git a/iblrig/base_tasks.py b/iblrig/base_tasks.py index 250a5ef67..5dce629a7 100644 --- a/iblrig/base_tasks.py +++ b/iblrig/base_tasks.py @@ -82,7 +82,7 @@ def __init__(self, subject=None, task_parameter_file=None, file_hardware_setting if update_status is True: print(f"\nUpdate to iblrig {remote_version} is available!\n" f"Please update by issuing:\n\n" - f" pip install --upgrade -e .\n") + f" upgrade_iblrig\n") while True: print("- Press [Enter] to exit IBL Rig and perform the update right away.\n" "- Enter 'I will update later' to continue without updating.") diff --git a/iblrig/gui/wizard.py b/iblrig/gui/wizard.py index 99bd79709..454ea0dfa 100644 --- a/iblrig/gui/wizard.py +++ b/iblrig/gui/wizard.py @@ -154,7 +154,7 @@ def __init__(self, *args, **kwargs): def check_for_update(self): update_available, remote_version = check_for_updates() if update_available == 1: - cmdBox = QtWidgets.QLineEdit('pip install --upgrade -e .') + cmdBox = QtWidgets.QLineEdit('upgrade_iblrig') cmdBox.setReadOnly(True) msgBox = QtWidgets.QMessageBox(parent=self) msgBox.setWindowTitle("Update Notice") diff --git a/iblrig/version_management.py b/iblrig/version_management.py index 730702098..7ed2131d9 100644 --- a/iblrig/version_management.py +++ b/iblrig/version_management.py @@ -2,6 +2,7 @@ from pathlib import Path from re import sub from subprocess import check_output, check_call, SubprocessError +import sys import iblrig from iblutil.util import setup_logger @@ -12,35 +13,91 @@ def check_for_updates(): log.info('Checking for updates ...') - # assert that git is being used - dir_base = Path(iblrig.__file__).parents[1] - if not dir_base.joinpath('.git').exists(): - log.debug('iblrig does not seem to be managed through git') - return -1, '' - - # get newest remote tag try: - branch = check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"], - cwd=dir_base) - branch = sub(r'\n', '', branch.decode()) - check_call(["git", "fetch", "origin", branch, "-q"], cwd=dir_base, timeout=5) - version_remote_str = check_output(["git", "describe", "--tags", "--abbrev=0"], - cwd=dir_base) - version_remote_str = sub(r'[^\d\.]', '', version_remote_str.decode()) - except (SubprocessError, FileNotFoundError): - log.debug('Could not fetch remote tags') + v_local = version.parse(iblrig.__version__) + except (version.InvalidVersion, TypeError): + log.debug('Could not parse local version string') return -1, '' - # parse version information - try: - version_local = version.parse(iblrig.__version__) - version_remote = version.parse(version_remote_str) - except version.InvalidVersion: - log.debug('Invalid version string') + v_remote = Remote().version() + if v_remote is None: + log.debug('Could not parse remote version string') return -1, '' - if version_remote > version_local: - log.info(f'Update to iblrig {version_remote_str} found.') + if v_remote > v_local: + log.info(f'Update to iblrig {v_remote} found.') else: log.info('No update found.') - return version_remote > version_local, version_remote_str if version_remote > version_local else version_local + return (v_remote > v_local, str(v_remote) if v_remote > v_local else str(v_local)) + + +def update_available(): + version_local = version.parse(iblrig.__version__) + version_remote = version.parse(Remote().version_str()) + return version_remote > version_local + + +class Remote(object): + _version = None + + @staticmethod + def version(): + + if Remote._version: + return Remote._version + + if not is_git(): + return None + try: + dir_base = Path(iblrig.__file__).parents[1] + branch = check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"], + cwd=dir_base) + branch = sub(r'\n', '', branch.decode()) + check_call(["git", "fetch", "origin", branch, "-q"], + cwd=dir_base, timeout=5) + version_str = check_output(["git", "describe", "--tags", "--abbrev=0"], + cwd=dir_base) + except (SubprocessError, FileNotFoundError): + return None + + version_str = sub(r'[^\d\.]', '', version_str.decode()) + try: + Remote._version = version.parse(version_str) + return Remote._version + except (version.InvalidVersion, TypeError): + return None + + +def is_git(): + return Path(iblrig.__file__).parents[1].joinpath('.git').exists() + + +def upgrade(): + if not is_git(): + raise Exception('This installation of IBLRIG is not managed through git.') + if sys.base_prefix == sys.prefix: + raise Exception('You need to be in the IBLRIG venv in order to upgrade.') + if not Remote.version(): + raise Exception('Could not obtain remote version.') + + local_version = version.parse(iblrig.__version__) + remote_version = Remote.version() + + print(f'Local version: {local_version}') + print(f'Remote version: {remote_version}') + + if local_version >= remote_version: + print('No need to upgrade.') + return 0 + + if iblrig.__version__.endswith('+dirty'): + print('There are changes in your local copy of IBLRIG that will be lost when ' + 'upgrading.') + while True: + user_input = input('Do you want to proceed? [y, N] ') + if user_input.lower() in ['n', 'no', '']: + return + if user_input.lower() in ['y', 'yes']: + break + + check_call([sys.executable, "-m", "pip", "install", "-U", "-e", "."]) diff --git a/pyproject.toml b/pyproject.toml index 1f925f1c9..00b7f219f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,6 +56,7 @@ transfer_video_data = "iblrig.commands:transfer_video_data" flush = "iblrig.commands:flush" remove-old-sessions = "iblrig.commands:remove_local_sessions" iblrig = "iblrig.gui.wizard:main" +upgrade_iblrig = "iblrig.version_management:upgrade" [tool.setuptools.dynamic] readme = {file = "README.md", content-type = "text/markdown"}