Skip to content

Commit 19f577a

Browse files
authored
Bug | Fix rogue-tui auto update (#143)
* Auto update TUI on version drift * Make sure rogue-tui will match current python package's version * Improve version drift
1 parent 4167fa8 commit 19f577a

File tree

4 files changed

+92
-30
lines changed

4 files changed

+92
-30
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.3.0
1+
0.3.1

rogue/common/tui_installer.py

Lines changed: 88 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import os
44
import platform
5+
import re
56
import shutil
7+
import subprocess # nosec: B404
68
import tempfile
79
from functools import lru_cache
810
from pathlib import Path
@@ -13,6 +15,8 @@
1315
from loguru import logger
1416
from rich.console import Console
1517

18+
from .version import get_version
19+
1620

1721
class RogueTuiInstaller:
1822
def __init__(self, repo: str = "qualifire-dev/rogue"):
@@ -42,15 +46,18 @@ def _os(self) -> str:
4246
"""Get the operating system name."""
4347
return platform.system().lower()
4448

45-
def _get_latest_github_release(self) -> Optional[dict]:
46-
"""Get the latest release information from GitHub."""
49+
def _get_release_from_github(
50+
self,
51+
version: str,
52+
) -> Optional[dict]:
53+
"""Get the release information from GitHub."""
4754
console = Console()
4855

4956
try:
50-
url = f"https://api.github.com/repos/{self._repo}/releases/latest"
57+
url = f"https://api.github.com/repos/{self._repo}/releases/{version}"
5158

5259
with console.status(
53-
"[bold blue]Fetching latest release information...",
60+
f"[bold blue]Fetching {version} release information...",
5461
spinner="dots",
5562
):
5663
response = requests.get(
@@ -61,7 +68,7 @@ def _get_latest_github_release(self) -> Optional[dict]:
6168
response.raise_for_status()
6269
return response.json()
6370
except Exception:
64-
logger.exception("Error fetching latest release")
71+
logger.exception(f"Error fetching {version} release")
6572
return None
6673

6774
def _find_asset_for_platform(
@@ -83,13 +90,19 @@ def _find_asset_for_platform(
8390

8491
return None
8592

86-
def _download_rogue_tui_to_temp(self) -> str:
93+
def _download_rogue_tui_to_temp(
94+
self,
95+
latest_version_override: bool = False,
96+
) -> str:
8797
console = Console()
8898

89-
# Get latest release
90-
release_data = self._get_latest_github_release()
99+
version = "latest" if latest_version_override else f"v{get_version()}"
100+
101+
# Get github release
102+
console.print(f"[bold blue]Fetching {version} release information...")
103+
release_data = self._get_release_from_github(version)
91104
if not release_data:
92-
raise Exception("Failed to fetch latest release information.")
105+
raise Exception(f"Failed to fetch rogue-tui {version} release information.")
93106

94107
# Find appropriate asset
95108
download_url = self._find_asset_for_platform(release_data)
@@ -165,27 +178,78 @@ def _is_rogue_tui_installed(self) -> bool:
165178
else:
166179
return False
167180

168-
def install_rogue_tui(
169-
self,
170-
upgrade: bool = False,
171-
) -> bool:
172-
"""Install rogue-tui from GitHub releases if not already installed."""
173-
console = Console()
174-
# Check if rogue-tui is already available
175-
if self._is_rogue_tui_installed() and not upgrade:
176-
console.print("[green]✅ rogue-tui is already installed.[/green]")
181+
@lru_cache(1)
182+
def _get_installed_tui_version(self) -> Optional[str]:
183+
"""Get the version of the installed rogue-tui binary."""
184+
try:
185+
result = subprocess.run( # nosec: B603 B607
186+
["rogue-tui", "--version"],
187+
capture_output=True,
188+
text=True,
189+
timeout=5,
190+
check=True,
191+
)
192+
# Parse output like "rogue-tui v0.2.2"
193+
match = re.search(r"v?(\d+\.\d+\.\d+)", result.stdout)
194+
if match:
195+
return match.group(1)
196+
return None
197+
except Exception:
198+
logger.debug("Failed to get rogue-tui version")
199+
return None
200+
201+
@lru_cache(1)
202+
def _should_reinstall_tui(self) -> bool:
203+
"""Check if rogue-tui should be reinstalled due to version mismatch."""
204+
installed_version = self._get_installed_tui_version()
205+
if not installed_version:
177206
return True
178207

179-
console.print(
180-
"[yellow]📦 Installing rogue-tui from GitHub releases...[/yellow]",
181-
)
208+
current_version = get_version("rogue-ai")
209+
return installed_version != current_version
210+
211+
def install_rogue_tui(self) -> bool:
212+
"""Install rogue-tui from GitHub releases if not installed or needs update."""
213+
console = Console()
214+
215+
# Check if rogue-tui is already available
216+
if self._is_rogue_tui_installed():
217+
# Check if version matches
218+
if not self._should_reinstall_tui():
219+
console.print(
220+
"[green]✅ rogue-tui is already installed and up to date.[/green]",
221+
)
222+
return True
223+
else:
224+
installed_version = self._get_installed_tui_version()
225+
current_version = get_version("rogue-ai")
226+
console.print(
227+
f"[yellow]📦 Updating rogue-tui from "
228+
f"v{installed_version} to v{current_version}...[/yellow]",
229+
)
230+
else:
231+
console.print(
232+
"[yellow]📦 Installing rogue-tui from GitHub releases...[/yellow]",
233+
)
182234

183235
try:
184236
tmp_path = self._download_rogue_tui_to_temp()
185237
except Exception:
186-
console.print("[red]❌ Failed to download rogue-tui.[/red]")
187-
logger.exception("Failed to download rogue-tui.")
188-
return False
238+
logger.exception(f"Failed to download rogue-tui for {get_version()}.")
239+
console.print(
240+
f"[red]❌ Failed to download rogue-tui for {get_version()}.[/red]",
241+
)
242+
console.print("[yellow]Trying latest version[/yellow]")
243+
try:
244+
tmp_path = self._download_rogue_tui_to_temp(
245+
latest_version_override=True,
246+
)
247+
except Exception:
248+
logger.exception("Failed to download rogue-tui for latest version.")
249+
console.print(
250+
"[red]❌ Failed to download rogue-tui for latest version.[/red]",
251+
)
252+
return False
189253

190254
try:
191255
# Move to final location

rogue/common/update_checker.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,8 @@ def run_update_command() -> None:
216216
)
217217

218218
if result.returncode == 0:
219-
# Install TUI
220-
RogueTuiInstaller().install_rogue_tui(
221-
upgrade=True,
222-
)
219+
# Install/Upgrade TUI
220+
RogueTuiInstaller().install_rogue_tui()
223221

224222
if result.returncode == 0:
225223
console.print("[bold green]✅ Update completed successfully![/bold green]")

rogue/common/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pathlib import Path
66

77

8-
def get_version(package_name: str) -> str:
8+
def get_version(package_name: str = "rogue-ai") -> str:
99
"""
1010
Retrieves the package version.
1111

0 commit comments

Comments
 (0)