diff --git a/kiauh/components/webui_client/client_utils.py b/kiauh/components/webui_client/client_utils.py index f4b485a..db7f057 100644 --- a/kiauh/components/webui_client/client_utils.py +++ b/kiauh/components/webui_client/client_utils.py @@ -38,7 +38,7 @@ from core.types import ComponentStatus from utils.common import get_install_status from utils.fs_utils import create_symlink, remove_file from utils.git_utils import ( - get_latest_tag, + get_latest_remote_tag, get_latest_unstable_tag, ) @@ -137,7 +137,7 @@ def get_local_client_version(client: BaseWebClient) -> str | None: def get_remote_client_version(client: BaseWebClient) -> str | None: try: - if (tag := get_latest_tag(client.repo_path)) != "": + if (tag := get_latest_remote_tag(client.repo_path)) != "": return str(tag) return None except Exception: diff --git a/kiauh/core/menus/main_menu.py b/kiauh/core/menus/main_menu.py index 53141de..b7dec43 100644 --- a/kiauh/core/menus/main_menu.py +++ b/kiauh/core/menus/main_menu.py @@ -44,6 +44,7 @@ from core.menus.settings_menu import SettingsMenu from core.menus.update_menu import UpdateMenu from core.types import ComponentStatus, StatusMap, StatusText from extensions.extensions_menu import ExtensionsMenu +from utils.common import get_kiauh_version # noinspection PyUnusedLocal @@ -55,6 +56,7 @@ class MainMenu(BaseMenu): self.header: bool = True self.footer_type: FooterType = FooterType.QUIT + self.version = "" self.kl_status = self.kl_repo = self.mr_status = self.mr_repo = "" self.ms_status = self.fl_status = self.ks_status = self.mb_status = "" self.cn_status = self.cc_status = self.oe_status = "" @@ -86,6 +88,7 @@ class MainMenu(BaseMenu): ) def _fetch_status(self) -> None: + self.version = get_kiauh_version() self._get_component_status("kl", get_klipper_status) self._get_component_status("mr", get_moonraker_status) self._get_component_status("ms", get_client_status, MainsailData()) @@ -125,7 +128,7 @@ class MainMenu(BaseMenu): self._fetch_status() header = " [ Main Menu ] " - footer1 = f"{COLOR_CYAN}KIAUH v6.0.0{RESET_FORMAT}" + footer1 = f"{COLOR_CYAN}{self.version}{RESET_FORMAT}" footer2 = f"Changelog: {COLOR_MAGENTA}https://git.io/JnmlX{RESET_FORMAT}" color = COLOR_CYAN count = 62 - len(color) - len(RESET_FORMAT) diff --git a/kiauh/utils/common.py b/kiauh/utils/common.py index a50b016..7c0ba22 100644 --- a/kiauh/utils/common.py +++ b/kiauh/utils/common.py @@ -22,7 +22,12 @@ from core.constants import ( ) from core.logger import DialogType, Logger from core.types import ComponentStatus, StatusCode -from utils.git_utils import get_local_commit, get_remote_commit, get_repo_name +from utils.git_utils import ( + get_local_commit, + get_local_tags, + get_remote_commit, + get_repo_name, +) from utils.instance_utils import get_instances from utils.sys_utils import ( check_package_install, @@ -31,6 +36,14 @@ from utils.sys_utils import ( ) +def get_kiauh_version() -> str: + """ + Helper method to get the current KIAUH version by reading the latest tag + :return: string of the latest tag + """ + return get_local_tags(Path(__file__).parent.parent)[-1] + + def convert_camelcase_to_kebabcase(name: str) -> str: return re.sub(r"(? str | None: return None -def get_tags(repo_path: str) -> List[str]: +def get_local_tags(repo_path: Path, _filter: str | None = None) -> List[str]: + """ + Get all tags of a local Git repository + :param repo_path: Path to the local Git repository + :param _filter: Optional filter to filter the tags by + :return: List of tags + """ + try: + cmd = ["git", "tag", "-l"] + + if _filter is not None: + cmd.append(f"'${_filter}'") + + result: str = check_output( + cmd, + stderr=DEVNULL, + cwd=repo_path.as_posix(), + ).decode(encoding="utf-8") + + tags = result.split("\n") + return tags[:-1] + + except CalledProcessError: + return [] + + +def get_remote_tags(repo_path: str) -> List[str]: + """ + Gets the tags of a GitHub repostiory + :param repo_path: path of the GitHub repository - e.g. `/` + :return: List of tags + """ try: url = f"https://api.github.com/repos/{repo_path}/tags" with urllib.request.urlopen(url) as r: @@ -102,14 +133,14 @@ def get_tags(repo_path: str) -> List[str]: raise -def get_latest_tag(repo_path: str) -> str: +def get_latest_remote_tag(repo_path: str) -> str: """ Gets the latest stable tag of a GitHub repostiory :param repo_path: path of the GitHub repository - e.g. `/` :return: tag or empty string """ try: - if len(latest_tag := get_tags(repo_path)) > 0: + if len(latest_tag := get_remote_tags(repo_path)) > 0: return latest_tag[0] else: return "" @@ -124,7 +155,10 @@ def get_latest_unstable_tag(repo_path: str) -> str: :return: tag or empty string """ try: - if len(unstable_tags := [t for t in get_tags(repo_path) if "-" in t]) > 0: + if ( + len(unstable_tags := [t for t in get_remote_tags(repo_path) if "-" in t]) + > 0 + ): return unstable_tags[0] else: return "" @@ -133,6 +167,34 @@ def get_latest_unstable_tag(repo_path: str) -> str: raise +def compare_semver_tags(tag1: str, tag2: str) -> bool: + """ + Compare two semver version strings. + Does not support comparing pre-release versions (e.g. 1.0.0-rc.1, 1.0.0-beta.1) + :param tag1: First version string + :param tag2: Second version string + :return: True if tag1 is greater than tag2, False otherwise + """ + if tag1 == tag2: + return False + + def parse_version(v): + return list(map(int, v[1:].split("."))) + + tag1_parts = parse_version(tag1) + tag2_parts = parse_version(tag2) + + max_len = max(len(tag1_parts), len(tag2_parts)) + tag1_parts += [0] * (max_len - len(tag1_parts)) + tag2_parts += [0] * (max_len - len(tag2_parts)) + + for part1, part2 in zip(tag1_parts, tag2_parts): + if part1 != part2: + return part1 > part2 + + return False + + def get_local_commit(repo: Path) -> str | None: if not repo.exists() or not repo.joinpath(".git").exists(): return None diff --git a/scripts/ui/main_menu.sh b/scripts/ui/main_menu.sh index e917562..14cc1a4 100755 --- a/scripts/ui/main_menu.sh +++ b/scripts/ui/main_menu.sh @@ -40,7 +40,7 @@ function main_ui() { function get_kiauh_version() { local version cd "${KIAUH_SRCDIR}" - version="$(git describe HEAD --always --tags | cut -d "-" -f 1,2)" + version="$(git tag -l 'v5*' | tail -1)" echo "${version}" }