- Add new subcommands: convert, preflight, server, templates, webpage - Migrate config from bin/config.json to ~/.config/mytoolkit - Fix expand_bookmarks to modify writer objects instead of reader - Improve md_to_pdf with CJK bookmark support - Update README and project metadata
44 lines
1.2 KiB
Python
44 lines
1.2 KiB
Python
"""Utility functions and decorators for bin."""
|
|
|
|
import functools
|
|
import subprocess
|
|
import sys
|
|
|
|
import click
|
|
|
|
|
|
def handle_errors(func):
|
|
"""Decorator to handle common errors gracefully."""
|
|
|
|
@functools.wraps(func)
|
|
def wrapper(*args, **kwargs):
|
|
try:
|
|
return func(*args, **kwargs)
|
|
except FileNotFoundError as e:
|
|
click.secho(f"Command not found: {e.filename}", fg="red", err=True)
|
|
sys.exit(1)
|
|
except subprocess.CalledProcessError as e:
|
|
click.secho(f"Command failed with exit code {e.returncode}", fg="red", err=True)
|
|
if e.stderr:
|
|
click.echo(e.stderr, err=True)
|
|
sys.exit(1)
|
|
except KeyboardInterrupt:
|
|
click.echo("\nAborted.")
|
|
sys.exit(130)
|
|
|
|
return wrapper
|
|
|
|
|
|
def run_command(cmd: list[str], check: bool = True, **kwargs) -> subprocess.CompletedProcess:
|
|
"""Run a subprocess command with consistent error handling.
|
|
|
|
Args:
|
|
cmd: Command and arguments as list
|
|
check: Whether to check return code
|
|
**kwargs: Additional args for subprocess.run
|
|
|
|
Returns:
|
|
CompletedProcess instance
|
|
"""
|
|
return subprocess.run(cmd, check=check, **kwargs)
|