diff --git a/pkgs/by-name/ya/yazi/plugins/mediainfo/default.nix b/pkgs/by-name/ya/yazi/plugins/mediainfo/default.nix index 5dffe707c582..1297930d0bdb 100644 --- a/pkgs/by-name/ya/yazi/plugins/mediainfo/default.nix +++ b/pkgs/by-name/ya/yazi/plugins/mediainfo/default.nix @@ -5,13 +5,13 @@ }: mkYaziPlugin { pname = "mediainfo.yazi"; - version = "25.5.28-unstable-2025-05-30"; + version = "25.5.31-unstable-2025-06-05"; src = fetchFromGitHub { owner = "boydaihungst"; repo = "mediainfo.yazi"; - rev = "c6d0de764f6e667c1a7a49f8acc9030c02a1a45c"; - hash = "sha256-CVHY66AcOC0STi+uDwbKe+HI3WN7MPgszlFHB479V/E="; + rev = "a7d1aa69a1a107e64540c17f19ac94be1366769f"; + hash = "sha256-HUD8Sv1C4gzZRvSEIYqcmm+A0mBYDuwZHCNH26kipS0="; }; meta = { diff --git a/pkgs/by-name/ya/yazi/plugins/projects/default.nix b/pkgs/by-name/ya/yazi/plugins/projects/default.nix index 9421f0543958..3ba2308f3ce9 100644 --- a/pkgs/by-name/ya/yazi/plugins/projects/default.nix +++ b/pkgs/by-name/ya/yazi/plugins/projects/default.nix @@ -5,13 +5,13 @@ }: mkYaziPlugin { pname = "projects.yazi"; - version = "0-unstable-2025-05-29"; + version = "0-unstable-2025-06-03"; src = fetchFromGitHub { owner = "MasouShizuka"; repo = "projects.yazi"; - rev = "96af237d2255d5dab5493c020f55561f63c28777"; - hash = "sha256-N8XH6adXPk/iU173fXEViv0NPwFZ0WYiyEJGBs4c6ec="; + rev = "7037dd5eee184ccb7725bdc9f7ea6faa188420d5"; + hash = "sha256-Lc0MeiAuPgJTq4ojNw9hwxqPJ74S4ymn4uPTkxGeZGc="; }; meta = { diff --git a/pkgs/by-name/ya/yazi/plugins/relative-motions/default.nix b/pkgs/by-name/ya/yazi/plugins/relative-motions/default.nix index c899450c6974..641434789824 100644 --- a/pkgs/by-name/ya/yazi/plugins/relative-motions/default.nix +++ b/pkgs/by-name/ya/yazi/plugins/relative-motions/default.nix @@ -5,13 +5,13 @@ }: mkYaziPlugin { pname = "relative-motions.yazi"; - version = "25.4.8-unstable-2025-04-16"; + version = "25.5.28-unstable-2025-06-05"; src = fetchFromGitHub { owner = "dedukun"; repo = "relative-motions.yazi"; - rev = "ce2e890227269cc15cdc71d23b35a58fae6d2c27"; - hash = "sha256-Ijz1wYt+L+24Fb/rzHcDR8JBv84z2UxdCIPqTdzbD14="; + rev = "2e3b6172e6226e0db96aea12d09dea2d2e443fea"; + hash = "sha256-v0e06ieBKNmt9DATdL7R4AyVFa9DlNBwpfME3LHozLA="; }; meta = { diff --git a/pkgs/by-name/ya/yazi/plugins/rich-preview/default.nix b/pkgs/by-name/ya/yazi/plugins/rich-preview/default.nix index ef08195971de..f1738bf96d7a 100644 --- a/pkgs/by-name/ya/yazi/plugins/rich-preview/default.nix +++ b/pkgs/by-name/ya/yazi/plugins/rich-preview/default.nix @@ -5,13 +5,13 @@ }: mkYaziPlugin { pname = "rich-preview.yazi"; - version = "0-unstable-2025-05-30"; + version = "0-unstable-2025-05-31"; src = fetchFromGitHub { owner = "AnirudhG07"; repo = "rich-preview.yazi"; - rev = "de28f504f21ee78b9e4799f116df2aa177384229"; - hash = "sha256-pJ5aMAECK0M4v/8czGP5RZygfRAyS9IdQCeP3ZP1Gcs="; + rev = "843c3faf0a99f5ce31d02372c868d8dae92ca29d"; + hash = "sha256-celObHo9Y3pFCd1mTx1Lz77Tc22SJTleRblAkbH/RqY="; }; meta = { diff --git a/pkgs/by-name/ya/yazi/plugins/rsync/default.nix b/pkgs/by-name/ya/yazi/plugins/rsync/default.nix index 33a824ca6f05..a1267a3c15bf 100644 --- a/pkgs/by-name/ya/yazi/plugins/rsync/default.nix +++ b/pkgs/by-name/ya/yazi/plugins/rsync/default.nix @@ -5,12 +5,12 @@ }: mkYaziPlugin { pname = "rsync.yazi"; - version = "0-unstable-2025-04-24"; + version = "0-unstable-2025-06-07"; src = fetchFromGitHub { owner = "GianniBYoung"; repo = "rsync.yazi"; - rev = "ed7b7f9de971ecd8376d7ccb7a6d0d6f979c1dcb"; - hash = "sha256-xAhkDTNi0MjHqESKk8j60WABYvaF7NElO2W/rsL2w2Y="; + rev = "782481e58316f4b422f5c259f07c63b940555246"; + hash = "sha256-ZrvaJl3nf/CGavvk1QEyOMUbfKQ/JYSmZguvbXIIw9M="; }; meta = { diff --git a/pkgs/by-name/ya/yazi/plugins/starship/default.nix b/pkgs/by-name/ya/yazi/plugins/starship/default.nix index e8596d6ff1e2..a8515a9fac77 100644 --- a/pkgs/by-name/ya/yazi/plugins/starship/default.nix +++ b/pkgs/by-name/ya/yazi/plugins/starship/default.nix @@ -5,13 +5,13 @@ }: mkYaziPlugin { pname = "starship.yazi"; - version = "25.4.8-unstable-2025-05-30"; + version = "25.4.8-unstable-2025-06-01"; src = fetchFromGitHub { owner = "Rolv-Apneseth"; repo = "starship.yazi"; - rev = "428d43ac0846cb1885493a1f01c049a883b70155"; - hash = "sha256-YkDkMC2SJIfpKrt93W/v5R3wOrYcat7QTbPrWqIKXG8="; + rev = "6a0f3f788971b155cbc7cec47f6f11aebbc148c9"; + hash = "sha256-q1G0Y4JAuAv8+zckImzbRvozVn489qiYVGFQbdCxC98="; }; meta = { diff --git a/pkgs/by-name/ya/yazi/plugins/update.py b/pkgs/by-name/ya/yazi/plugins/update.py index 4ad6135906c7..999b04b4f079 100755 --- a/pkgs/by-name/ya/yazi/plugins/update.py +++ b/pkgs/by-name/ya/yazi/plugins/update.py @@ -1,12 +1,13 @@ #!/usr/bin/env nix-shell -#!nix-shell -i python3 -p python3 python3Packages.requests python3Packages.packaging nix curl git +#!nix-shell -i python3 -p python3 python3Packages.requests python3Packages.packaging nix curl git argparse +import argparse +import json import os import re import subprocess import sys from pathlib import Path -from typing import Dict, Tuple import requests from packaging import version @@ -17,13 +18,14 @@ def run_command(cmd: str, capture_output: bool = True) -> str: result = subprocess.run(cmd, shell=True, text=True, capture_output=capture_output) if result.returncode != 0: if capture_output: - print(f"Error running command: {cmd}") - print(f"stderr: {result.stderr}") - sys.exit(1) + error_msg = f"Error running command: {cmd}\nstderr: {result.stderr}" + raise RuntimeError(error_msg) + else: + raise RuntimeError(f"Command failed: {cmd}") return result.stdout.strip() if capture_output else "" -def get_plugin_info(nixpkgs_dir: str, plugin_name: str) -> Dict[str, str]: +def get_plugin_info(nixpkgs_dir: str, plugin_name: str) -> dict[str, str]: """Get plugin repository information from Nix""" owner = run_command(f"nix eval --raw -f {nixpkgs_dir} yaziPlugins.\"{plugin_name}\".src.owner") repo = run_command(f"nix eval --raw -f {nixpkgs_dir} yaziPlugins.\"{plugin_name}\".src.repo") @@ -40,7 +42,7 @@ def get_yazi_version(nixpkgs_dir: str) -> str: -def get_github_headers() -> Dict[str, str]: +def get_github_headers() -> dict[str, str]: """Create headers for GitHub API requests""" headers = {"Accept": "application/vnd.github.v3+json"} github_token = os.environ.get("GITHUB_TOKEN") @@ -49,7 +51,7 @@ def get_github_headers() -> Dict[str, str]: return headers -def get_default_branch(owner: str, repo: str, headers: Dict[str, str]) -> str: +def get_default_branch(owner: str, repo: str, headers: dict[str, str]) -> str: """Get the default branch name for a GitHub repository""" api_url = f"https://api.github.com/repos/{owner}/{repo}" @@ -63,7 +65,7 @@ def get_default_branch(owner: str, repo: str, headers: Dict[str, str]) -> str: print("Falling back to 'main' as default branch") return "main" -def fetch_plugin_content(owner: str, repo: str, plugin_pname: str, headers: Dict[str, str]) -> str: +def fetch_plugin_content(owner: str, repo: str, plugin_pname: str, headers: dict[str, str]) -> str: """Fetch the plugin's main.lua content from GitHub""" default_branch = get_default_branch(owner, repo, headers) plugin_path = f"{plugin_pname}/" if owner == "yazi-rs" else "" @@ -74,8 +76,7 @@ def fetch_plugin_content(owner: str, repo: str, plugin_pname: str, headers: Dict response.raise_for_status() return response.text except requests.RequestException as e: - print(f"Error fetching plugin content: {e}") - sys.exit(1) + raise RuntimeError(f"Error fetching plugin content: {e}") def check_version_compatibility(plugin_content: str, plugin_name: str, yazi_version: str) -> str: @@ -86,15 +87,15 @@ def check_version_compatibility(plugin_content: str, plugin_name: str, yazi_vers if required_version == "0": print(f"No version requirement found for {plugin_name}, assuming compatible with any Yazi version") else: - # Check if the plugin is compatible with current Yazi version if version.parse(required_version) > version.parse(yazi_version): - print(f"{plugin_name} plugin requires Yazi {required_version}, but we have {yazi_version}") - sys.exit(0) + message = f"{plugin_name} plugin requires Yazi {required_version}, but we have {yazi_version}" + print(message) + raise RuntimeError(message) return required_version -def get_latest_commit(owner: str, repo: str, plugin_pname: str, headers: Dict[str, str]) -> Tuple[str, str]: +def get_latest_commit(owner: str, repo: str, plugin_pname: str, headers: dict[str, str]) -> tuple[str, str]: """Get the latest commit hash and date for the plugin""" default_branch = get_default_branch(owner, repo, headers) @@ -110,8 +111,7 @@ def get_latest_commit(owner: str, repo: str, plugin_pname: str, headers: Dict[st response.raise_for_status() commit_data = response.json() except requests.RequestException as e: - print(f"Error fetching commit data: {e}") - sys.exit(1) + raise RuntimeError(f"Error fetching commit data: {e}") if owner == "yazi-rs": latest_commit = commit_data[0]["sha"] @@ -121,8 +121,7 @@ def get_latest_commit(owner: str, repo: str, plugin_pname: str, headers: Dict[st commit_date = commit_data["commit"]["committer"]["date"].split("T")[0] if not latest_commit: - print("Error: Could not get latest commit hash") - sys.exit(1) + raise RuntimeError("Could not get latest commit hash") return latest_commit, commit_date @@ -134,24 +133,18 @@ def calculate_sri_hash(owner: str, repo: str, latest_commit: str) -> str: try: new_hash = run_command(f"nix-prefetch-url --unpack --type sha256 {prefetch_url} 2>/dev/null") - # If the hash is not in SRI format, convert it if not new_hash.startswith("sha256-"): - # Try to convert the hash to SRI format new_hash = run_command(f"nix hash to-sri --type sha256 {new_hash} 2>/dev/null") - # If that fails, try another approach if not new_hash.startswith("sha256-"): print("Warning: Failed to get SRI hash directly, trying alternative method...") raw_hash = run_command(f"nix-prefetch-url --type sha256 {prefetch_url} 2>/dev/null") new_hash = run_command(f"nix hash to-sri --type sha256 {raw_hash} 2>/dev/null") except Exception as e: - print(f"Error calculating hash: {e}") - sys.exit(1) + raise RuntimeError(f"Error calculating hash: {e}") - # Verify we got a valid SRI hash if not new_hash.startswith("sha256-"): - print(f"Error: Failed to generate valid SRI hash. Output was: {new_hash}") - sys.exit(1) + raise RuntimeError(f"Failed to generate valid SRI hash. Output was: {new_hash}") return new_hash @@ -162,8 +155,7 @@ def read_nix_file(file_path: str) -> str: with open(file_path, 'r') as f: return f.read() except IOError as e: - print(f"Error reading file {file_path}: {e}") - sys.exit(1) + raise RuntimeError(f"Error reading file {file_path}: {e}") def write_nix_file(file_path: str, content: str) -> None: @@ -172,101 +164,265 @@ def write_nix_file(file_path: str, content: str) -> None: with open(file_path, 'w') as f: f.write(content) except IOError as e: - print(f"Error writing to file {file_path}: {e}") - sys.exit(1) + raise RuntimeError(f"Error writing to file {file_path}: {e}") def update_nix_file(default_nix_path: str, latest_commit: str, new_version: str, new_hash: str) -> None: """Update the default.nix file with new version, revision and hash""" default_nix_content = read_nix_file(default_nix_path) - # Update the revision in default.nix default_nix_content = re.sub(r'rev = "[^"]*"', f'rev = "{latest_commit}"', default_nix_content) - # Update the version in default.nix if 'version = "' in default_nix_content: default_nix_content = re.sub(r'version = "[^"]*"', f'version = "{new_version}"', default_nix_content) else: - # Add version attribute after pname if it doesn't exist default_nix_content = re.sub(r'(pname = "[^"]*";)', f'\\1\n version = "{new_version}";', default_nix_content) - # Update hash in default.nix if 'hash = "' in default_nix_content: default_nix_content = re.sub(r'hash = "[^"]*"', f'hash = "{new_hash}"', default_nix_content) elif 'fetchFromGitHub' in default_nix_content: default_nix_content = re.sub(r'sha256 = "[^"]*"', f'sha256 = "{new_hash}"', default_nix_content) else: - print(f"Error: Could not find hash attribute in {default_nix_path}") - sys.exit(1) + raise RuntimeError(f"Could not find hash attribute in {default_nix_path}") - # Write the updated content back to the file write_nix_file(default_nix_path, default_nix_content) - # Verify the hash was updated updated_content = read_nix_file(default_nix_path) if f'hash = "{new_hash}"' in updated_content or f'sha256 = "{new_hash}"' in updated_content: print(f"Successfully updated hash to: {new_hash}") else: - print(f"Error: Failed to update hash in {default_nix_path}") - sys.exit(1) + raise RuntimeError(f"Failed to update hash in {default_nix_path}") -def validate_environment() -> Tuple[str, str, str]: +def get_all_plugins(nixpkgs_dir: str) -> list[dict[str, str]]: + """Get all available Yazi plugins from the Nix expression""" + try: + plugin_names_json = run_command(f'nix eval --impure --json --expr "builtins.attrNames (import {nixpkgs_dir} {{}}).yaziPlugins"') + plugin_names = json.loads(plugin_names_json) + + excluded_attrs = ["mkYaziPlugin", "override", "overrideDerivation", "overrideAttrs", "recurseForDerivations"] + plugin_names = [name for name in plugin_names if name not in excluded_attrs] + + plugins = [] + for name in plugin_names: + try: + pname = run_command(f'nix eval --raw -f {nixpkgs_dir} "yaziPlugins.{name}.pname"') + plugins.append({ + "name": name, # Attribute name in yaziPlugins set + "pname": pname # Package name (used in repo paths) + }) + except Exception as e: + print(f"Warning: Could not get pname for plugin {name}, skipping: {e}") + continue + + return plugins + except Exception as e: + raise RuntimeError(f"Error getting plugin list: {e}") + + +def validate_environment(plugin_name: str | None = None, plugin_pname: str | None = None) -> tuple[str, str | None, str | None]: """Validate environment variables and paths""" nixpkgs_dir = os.getcwd() - plugin_name = os.environ.get("PLUGIN_NAME") - plugin_pname = os.environ.get("PLUGIN_PNAME") + if plugin_name and not plugin_pname: + raise RuntimeError(f"pname not provided for plugin {plugin_name}") - if not plugin_name or not plugin_pname: - print("Error: PLUGIN_NAME and PLUGIN_PNAME environment variables must be set") - sys.exit(1) - - plugin_dir = f"{nixpkgs_dir}/pkgs/by-name/ya/yazi/plugins/{plugin_name}" - if not Path(f"{plugin_dir}/default.nix").exists(): - print(f"Error: Could not find default.nix for plugin {plugin_name} at {plugin_dir}") - sys.exit(1) + if plugin_name: + plugin_dir = f"{nixpkgs_dir}/pkgs/by-name/ya/yazi/plugins/{plugin_name}" + if not Path(f"{plugin_dir}/default.nix").exists(): + raise RuntimeError(f"Could not find default.nix for plugin {plugin_name} at {plugin_dir}") return nixpkgs_dir, plugin_name, plugin_pname -def main(): - """Main function to update a Yazi plugin""" - # Basic setup and validation - nixpkgs_dir, plugin_name, plugin_pname = validate_environment() +def update_single_plugin(nixpkgs_dir: str, plugin_name: str, plugin_pname: str) -> dict[str, str] | None: + """Update a single Yazi plugin + + Returns: + dict with update info including old_version, new_version, etc. or None if no change + """ plugin_dir = f"{nixpkgs_dir}/pkgs/by-name/ya/yazi/plugins/{plugin_name}" default_nix_path = f"{plugin_dir}/default.nix" - # Get repository info + nix_content = read_nix_file(default_nix_path) + old_version_match = re.search(r'version = "([^"]*)"', nix_content) + old_version = old_version_match.group(1) if old_version_match else "unknown" + old_commit_match = re.search(r'rev = "([^"]*)"', nix_content) + old_commit = old_commit_match.group(1) if old_commit_match else "unknown" + plugin_info = get_plugin_info(nixpkgs_dir, plugin_name) owner = plugin_info["owner"] repo = plugin_info["repo"] - # Get Yazi version separately yazi_version = get_yazi_version(nixpkgs_dir) - # Setup GitHub API headers headers = get_github_headers() - # Check plugin compatibility with current Yazi version plugin_content = fetch_plugin_content(owner, repo, plugin_pname, headers) required_version = check_version_compatibility(plugin_content, plugin_name, yazi_version) - # Get latest commit info latest_commit, commit_date = get_latest_commit(owner, repo, plugin_pname, headers) - print(f"Updating {plugin_name} to commit {latest_commit} ({commit_date})") + print(f"Checking {plugin_name} latest commit {latest_commit} ({commit_date})") + + if latest_commit == old_commit: + print(f"No changes for {plugin_name}, already at latest commit {latest_commit}") + return None + + print(f"Updating {plugin_name} from commit {old_commit} to {latest_commit}") - # Generate new version string new_version = f"{required_version}-unstable-{commit_date}" - # Calculate hash for the plugin new_hash = calculate_sri_hash(owner, repo, latest_commit) print(f"Generated SRI hash: {new_hash}") - # Update the default.nix file update_nix_file(default_nix_path, latest_commit, new_version, new_hash) - print(f"Successfully updated {plugin_name} to version {new_version} (commit {latest_commit})") + print(f"Successfully updated {plugin_name} from {old_version} to {new_version}") + + return { + "name": plugin_name, + "old_version": old_version, + "new_version": new_version, + "old_commit": old_commit, + "new_commit": latest_commit + } + + +def update_all_plugins(nixpkgs_dir: str) -> list[dict[str, str]]: + """Update all available Yazi plugins + + Returns: + list[dict[str, str]]: List of successfully updated plugin info dicts + """ + plugins = get_all_plugins(nixpkgs_dir) + updated_plugins = [] + + if not plugins: + print("No plugins found to update") + return updated_plugins + + print(f"Found {len(plugins)} plugins to update") + + checked_count = 0 + updated_count = 0 + failed_plugins = [] + + for plugin in plugins: + plugin_name = plugin["name"] + plugin_pname = plugin["pname"] + + try: + print(f"\n{'=' * 50}") + print(f"Checking plugin: {plugin_name}") + print(f"{'=' * 50}") + + try: + update_info = update_single_plugin(nixpkgs_dir, plugin_name, plugin_pname) + checked_count += 1 + + if update_info: + updated_count += 1 + updated_plugins.append(update_info) + except KeyboardInterrupt: + print("\nUpdate process interrupted by user") + sys.exit(1) + except Exception as e: + print(f"Error updating plugin {plugin_name}: {e}") + failed_plugins.append({"name": plugin_name, "error": str(e)}) + continue + except Exception as e: + print(f"Unexpected error with plugin {plugin_name}: {e}") + failed_plugins.append({"name": plugin_name, "error": str(e)}) + continue + + print(f"\n{'=' * 50}") + print(f"Update summary: {updated_count} plugins updated out of {checked_count} checked") + + if updated_count > 0: + print("\nUpdated plugins:") + for plugin in updated_plugins: + print(f" - {plugin['name']}: {plugin['old_version']} → {plugin['new_version']}") + + if failed_plugins: + print(f"\nFailed to update {len(failed_plugins)} plugins:") + for plugin in failed_plugins: + print(f" - {plugin['name']}: {plugin['error']}") + + return updated_plugins + + +def commit_changes(updated_plugins: list[dict[str, str]]) -> None: + """Commit all changes after updating plugins""" + if not updated_plugins: + print("No plugins were updated, skipping commit") + return + + try: + status_output = run_command("git status --porcelain", capture_output=True) + if not status_output: + print("No changes to commit") + return + + current_date = run_command("date +%Y-%m-%d", capture_output=True) + + if len(updated_plugins) == 1: + plugin = updated_plugins[0] + commit_message = f"yaziPlugins.{plugin['name']}: update from {plugin['old_version']} to {plugin['new_version']}" + else: + commit_message = f"yaziPlugins: update on {current_date}\n\n" + for plugin in sorted(updated_plugins, key=lambda x: x['name']): + commit_message += f"- {plugin['name']}: {plugin['old_version']} → {plugin['new_version']}\n" + + run_command("git add pkgs/by-name/ya/yazi/plugins/", capture_output=False) + + run_command(f'git commit -m "{commit_message}"', capture_output=False) + print(f"\nCommitted changes with message: {commit_message}") + except Exception as e: + print(f"Error committing changes: {e}") + + +def main(): + """Main function to update Yazi plugins""" + + parser = argparse.ArgumentParser(description="Update Yazi plugins") + group = parser.add_mutually_exclusive_group() + group.add_argument("--all", action="store_true", help="Update all Yazi plugins") + group.add_argument("--plugin", type=str, help="Update a specific plugin by name") + parser.add_argument("--commit", action="store_true", help="Commit changes after updating") + args = parser.parse_args() + + nixpkgs_dir = os.getcwd() + updated_plugins = [] + + if args.all: + print("Updating all Yazi plugins...") + updated_plugins = update_all_plugins(nixpkgs_dir) + + elif args.plugin: + plugin_name = args.plugin + try: + plugin_pname = run_command(f'nix eval --raw -f {nixpkgs_dir} "yaziPlugins.{plugin_name}.pname"') + print(f"Updating Yazi plugin: {plugin_name}") + update_info = update_single_plugin(nixpkgs_dir, plugin_name, plugin_pname) + if update_info: + updated_plugins.append(update_info) + except Exception as e: + print(f"Error: {e}") + sys.exit(1) + else: + nixpkgs_dir, plugin_name, plugin_pname = validate_environment() + + if plugin_name and plugin_pname: + print(f"Updating Yazi plugin: {plugin_name}") + update_info = update_single_plugin(nixpkgs_dir, plugin_name, plugin_pname) + if update_info: + updated_plugins.append(update_info) + else: + parser.print_help() + sys.exit(0) + + if args.commit and updated_plugins: + commit_changes(updated_plugins) if __name__ == "__main__":