Skills › BMAD Method › bmad-toolsmith › script-template.py
script-template.py
47 lines · skills/bmad-toolsmith/shapes/script-utility/assets/script-template.py at bd70c64
1#!/usr/bin/env python3
2# /// script
3# requires-python = ">=3.11"
4# ///
5"""{script} — {purpose}.
7{What the script reads, what it writes, and the shape of its output. This docstring is the
8`--help` text, so it is the whole reference: say what each result means.}
10Exit codes: 0 with the result as JSON on stdout; 1 with a one-line reason on stderr.
11"""
13from __future__ import annotations
15import argparse
16import json
17import sys
18from pathlib import Path
21class ScriptError(Exception):
22 """A failure the user can act on. Its message is the one line printed on exit."""
25def run(path: Path, *, strict: bool = False) -> dict:
26 """{The work. Return the result as a dict so main() can print it as JSON.}"""
27 if not path.exists():
28 raise ScriptError(f"not found: {path}")
29 return {"path": str(path), "strict": strict}
32def main(argv: list[str] | None = None) -> int:
33 parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
34 parser.add_argument("path", type=Path, help="{what the positional input is}")
35 parser.add_argument("--strict", action="store_true", help="{what strict changes}")
36 args = parser.parse_args(argv)
37 try:
38 result = run(args.path, strict=args.strict)
39 except ScriptError as error:
40 print(f"{parser.prog}: {error}", file=sys.stderr)
41 return 1
42 print(json.dumps(result, ensure_ascii=False, indent=2))
43 return 0
46if __name__ == "__main__":
47 raise SystemExit(main())