Standardize USAGE pragmas and typer parsing across mise tasks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erich Blume 2026-03-18 11:42:01 -07:00
commit ef8c2118a1
4 changed files with 54 additions and 39 deletions

View file

@ -1,9 +1,10 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["rich>=13.0.0"]
# dependencies = ["rich>=13.0.0", "typer>=0.15.0"]
# ///
#MISE description="Validate Mikado Branch Invariant on mikado/* branches"
#USAGE arg "[commit_msg_file]" help="Commit message file (passed by commit-msg hook)"
"""Validate the Mikado Branch Invariant for C2 change branches.
Runs as a commit-msg hook on mikado/* branches. Receives the commit message
@ -24,9 +25,10 @@ Exit code 0 if valid (or not on a mikado/* branch), 1 if violations found.
import re
import subprocess
import sys
from pathlib import Path
from typing import Annotated
import typer
from rich.console import Console
REPO_DIR = Path(__file__).parent.parent
@ -242,27 +244,36 @@ def check_invariant(commits: list[dict], chain_stem: str) -> list[str]:
return errors
def main() -> None:
app = typer.Typer()
@app.command()
def main(
commit_msg_file: Annotated[
str | None,
typer.Argument(help="Commit message file (passed by commit-msg hook)"),
] = None,
) -> None:
console = Console(stderr=True)
branch = get_current_branch()
if not branch or not branch.startswith("mikado/"):
# Not on a mikado branch — nothing to check
sys.exit(0)
raise SystemExit(0)
chain_stem = branch.removeprefix("mikado/")
commits = get_branch_commits(branch)
# If called with a commit message file (commit-msg hook), include the
# pending commit in the validation
if len(sys.argv) > 1:
subject = parse_commit_message(sys.argv[1])
if commit_msg_file is not None:
subject = parse_commit_message(commit_msg_file)
if subject:
commits.append(make_pending_commit(subject))
if not commits:
# No commits on branch yet — valid (length-zero case)
sys.exit(0)
raise SystemExit(0)
errors = check_invariant(commits, chain_stem)
@ -286,10 +297,10 @@ def main() -> None:
"[dim]See: docs/how-to/agent-change-process.md "
"§ The Mikado Branch Invariant[/dim]"
)
sys.exit(1)
raise SystemExit(1)
sys.exit(0)
raise SystemExit(0)
if __name__ == "__main__":
main()
app()

View file

@ -1,7 +1,7 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["rich>=13.0.0"]
# dependencies = ["rich>=13.0.0", "typer>=0.15.0"]
# ///
#MISE description="Encrypt a 1Password .1pux export and send to indri for borgmatic"
#USAGE arg "[export_path]" help="Path to .1pux export file (prompted if omitted)"
@ -29,11 +29,12 @@ DISASTER RECOVERY:
import os
import shutil
import subprocess
import sys
import tempfile
from datetime import datetime
from pathlib import Path
from typing import Annotated
import typer
from rich.console import Console
REMOTE_DIR = "/Users/erichblume/Documents/1password-backup"
@ -281,26 +282,35 @@ def transfer_to_indri(encrypted_export: Path, encrypted_key: Path, timestamp: st
return True
def main() -> int:
if not check_dependencies():
return 1
app = typer.Typer()
export_path = get_export_path(sys.argv[1] if len(sys.argv) > 1 else None)
@app.command()
def main(
export_path_arg: Annotated[
str | None,
typer.Argument(help="Path to .1pux export file (prompted if omitted)"),
] = None,
) -> None:
if not check_dependencies():
raise SystemExit(1)
export_path = get_export_path(export_path_arg)
if not export_path:
return 1
raise SystemExit(1)
file_size = f"{export_path.stat().st_size / 1024 / 1024:.1f} MB"
console.print(f"Source: {export_path} ({file_size})")
passphrase = fetch_credentials()
if not passphrase:
return 1
raise SystemExit(1)
with tempfile.TemporaryDirectory() as tmpdir:
result = encrypt(export_path, passphrase, Path(tmpdir))
del passphrase
if not result:
return 1
raise SystemExit(1)
encrypted_export, encrypted_key = result
@ -310,7 +320,7 @@ def main() -> int:
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
if not transfer_to_indri(encrypted_export, encrypted_key, timestamp):
return 1
raise SystemExit(1)
console.print()
console.print("[bold]DISASTER RECOVERY:[/bold]")
@ -320,8 +330,7 @@ def main() -> int:
console.print(" Passphrase: {master_password}:{secret_key}")
console.print(f" 4. age -d -i key.txt < ...age > export.1pux")
console.print(" 5. Open export.1pux with 1Password or unzip to inspect")
return 0
if __name__ == "__main__":
sys.exit(main())
app()

View file

@ -1,7 +1,7 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["httpx>=0.28.0", "rich>=13.0.0"]
# dependencies = ["httpx>=0.28.0", "rich>=13.0.0", "typer>=0.15.0"]
# ///
#MISE description="List unresolved comments on a PR"
#USAGE arg "<pr_number>" help="Pull request number"
@ -14,9 +14,10 @@ if its 'resolver' field is null.
Usage: mise run pr-comments <pr_number>
"""
import sys
from typing import Annotated
import httpx
import typer
from rich.console import Console
from rich.text import Text
@ -43,20 +44,15 @@ def get_review_comments(client: httpx.Client, pr_number: int, review_id: int) ->
return response.json()
def main() -> int:
app = typer.Typer()
@app.command()
def main(
pr_number: Annotated[int, typer.Argument(help="Pull request number")],
) -> None:
console = Console()
if len(sys.argv) < 2:
console.print("[red]Error:[/red] Please provide a PR number")
console.print("Usage: mise run pr-comments <pr_number>")
return 1
try:
pr_number = int(sys.argv[1])
except ValueError:
console.print(f"[red]Error:[/red] '{sys.argv[1]}' is not a valid PR number")
return 1
unresolved_comments: list[tuple[dict, dict]] = [] # (review, comment) pairs
with httpx.Client() as client:
@ -68,7 +64,7 @@ def main() -> int:
console.print(f"[red]Error:[/red] PR #{pr_number} not found")
else:
console.print(f"[red]Error:[/red] API request failed: {e}")
return 1
raise SystemExit(1)
# For each review, get comments and filter to unresolved
for review in reviews:
@ -83,7 +79,7 @@ def main() -> int:
if not unresolved_comments:
console.print(f"[green]No unresolved comments on PR #{pr_number}[/green]")
return 0
raise SystemExit(0)
# Display unresolved comments
console.print(f"[bold]Unresolved Comments on PR #{pr_number}[/bold] ({len(unresolved_comments)} comments)")
@ -111,8 +107,6 @@ def main() -> int:
console.print()
return 0
if __name__ == "__main__":
sys.exit(main())
app()