yaziPlugins: update on 2025-06-06 (#414418)

This commit is contained in:
Austin Horstman 2025-06-08 15:33:45 -05:00 committed by GitHub
commit e9a3f3ca88
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 240 additions and 84 deletions

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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__":