Files
FastAnime/viu_media/cli/commands/update.py
2025-08-18 01:08:27 +03:00

161 lines
5.0 KiB
Python

"""Update command for Viu CLI."""
import sys
from typing import TYPE_CHECKING
import click
from rich import print
from rich.console import Console
from rich.markdown import Markdown
from ..utils.update import check_for_updates, update_app
if TYPE_CHECKING:
from ...core.config import AppConfig
@click.command(
help="Update Viu to the latest version",
short_help="Update Viu",
epilog="""
\b
\b\bExamples:
# Check for updates and update if available
viu update
\b
# Force update even if already up to date
viu update --force
\b
# Only check for updates without updating
viu update --check-only
\b
# Show release notes for the latest version
viu update --release-notes
""",
)
@click.option(
"--force",
"-f",
is_flag=True,
help="Force update even if already up to date",
)
@click.option(
"--check-only",
"-c",
is_flag=True,
help="Only check for updates without updating",
)
@click.option(
"--release-notes",
"-r",
is_flag=True,
help="Show release notes for the latest version",
)
@click.pass_context
@click.pass_obj
def update(
config: "AppConfig",
ctx: click.Context,
force: bool,
check_only: bool,
release_notes: bool,
) -> None:
"""
Update Viu to the latest version.
This command checks for available updates and optionally updates
the application to the latest version from the configured sources
(pip, uv, pipx, git, or nix depending on installation method).
Args:
config: The application configuration object
ctx: The click context containing CLI options
force: Whether to force update even if already up to date
check_only: Whether to only check for updates without updating
release_notes: Whether to show release notes for the latest version
"""
try:
if release_notes:
print("[cyan]Fetching latest release notes...[/]")
is_latest, release_json = check_for_updates()
if not release_json:
print(
"[yellow]Could not fetch release information. Please check your internet connection.[/]"
)
sys.exit(1)
version = release_json.get("tag_name", "unknown")
release_name = release_json.get("name", version)
release_body = release_json.get("body", "No release notes available.")
published_at = release_json.get("published_at", "unknown")
console = Console()
print(f"[bold cyan]Release: {release_name}[/]")
print(f"[dim]Version: {version}[/]")
print(f"[dim]Published: {published_at}[/]")
print()
# Display release notes as markdown if available
if release_body.strip():
markdown = Markdown(release_body)
console.print(markdown)
else:
print("[dim]No release notes available for this version.[/]")
return
elif check_only:
print("[cyan]Checking for updates...[/]")
is_latest, release_json = check_for_updates()
if not release_json:
print(
"[yellow]Could not check for updates. Please check your internet connection.[/]"
)
sys.exit(1)
if is_latest:
print("[green]Viu is up to date![/]")
print(
f"[dim]Current version: {release_json.get('tag_name', 'unknown')}[/]"
)
else:
latest_version = release_json.get("tag_name", "unknown")
print(f"[yellow]Update available: {latest_version}[/]")
print("[dim]Run 'viu update' to update[/]")
sys.exit(1)
else:
print("[cyan]Checking for updates and updating if necessary...[/]")
success, release_json = update_app(force=force)
if not release_json:
print(
"[red]Could not check for updates. Please check your internet connection.[/]"
)
sys.exit(1)
if success:
latest_version = release_json.get("tag_name", "unknown")
print(f"[green]Successfully updated to version {latest_version}![/]")
else:
if force:
print(
"[red]Update failed. Please check the error messages above.[/]"
)
sys.exit(1)
# If not forced and update failed, it might be because already up to date
# The update_app function already prints appropriate messages
except KeyboardInterrupt:
print("\n[yellow]Update cancelled by user.[/]")
sys.exit(1)
except Exception as e:
print(f"[red]An error occurred during update: {e}[/]")
# Get trace option from parent context
trace = ctx.parent.params.get("trace", False) if ctx.parent else False
if trace:
raise
sys.exit(1)