|
| 1 | +"""Bump version across all Rex files. |
| 2 | +
|
| 3 | +Usage: uv run src/bump.py 0.2.0 |
| 4 | +""" |
| 5 | + |
| 6 | +from __future__ import annotations |
| 7 | + |
| 8 | +import re |
| 9 | +import sys |
| 10 | +from pathlib import Path |
| 11 | + |
| 12 | +ROOT = Path(__file__).resolve().parent.parent |
| 13 | + |
| 14 | +TARGETS = [ |
| 15 | + ("src/rex/__init__.py", re.compile(r'(__version__\s*=\s*")([^"]+)(")')), |
| 16 | + ("pyproject.toml", re.compile(r'(^version\s*=\s*")([^"]+)(")', re.MULTILINE)), |
| 17 | + (".claude-plugin/plugin.json", re.compile(r'("version":\s*")([^"]+)(")')), |
| 18 | + (".claude-plugin/marketplace.json", re.compile(r'("version":\s*")([^"]+)(")')), |
| 19 | +] |
| 20 | + |
| 21 | + |
| 22 | +def bump(new_version: str) -> None: |
| 23 | + for relpath, pattern in TARGETS: |
| 24 | + path = ROOT / relpath |
| 25 | + text = path.read_text() |
| 26 | + match = pattern.search(text) |
| 27 | + if not match: |
| 28 | + print(f" SKIP {relpath} (pattern not found)") |
| 29 | + continue |
| 30 | + old = match.group(2) |
| 31 | + if old == new_version: |
| 32 | + print(f" OK {relpath} (already {new_version})") |
| 33 | + continue |
| 34 | + text = pattern.sub(rf"\g<1>{new_version}\3", text, count=1) |
| 35 | + path.write_text(text) |
| 36 | + print(f" {old} → {new_version} {relpath}") |
| 37 | + |
| 38 | + |
| 39 | +def _parse_version(v: str) -> tuple[int, ...]: |
| 40 | + return tuple(int(x) for x in v.split(".")) |
| 41 | + |
| 42 | + |
| 43 | +def _current_version() -> str: |
| 44 | + path = ROOT / "src/rex/__init__.py" |
| 45 | + match = re.search(r'__version__\s*=\s*"([^"]+)"', path.read_text()) |
| 46 | + return match.group(1) if match else "0.0.0" |
| 47 | + |
| 48 | + |
| 49 | +def main() -> None: |
| 50 | + if len(sys.argv) != 2: |
| 51 | + print("Usage: uv run src/bump.py <version>") |
| 52 | + sys.exit(1) |
| 53 | + |
| 54 | + version = sys.argv[1].lstrip("v") |
| 55 | + if not re.match(r"^\d+\.\d+\.\d+$", version): |
| 56 | + print(f"Invalid version: {version}") |
| 57 | + sys.exit(1) |
| 58 | + |
| 59 | + current = _current_version() |
| 60 | + if _parse_version(version) <= _parse_version(current): |
| 61 | + print(f"Error: {version} is not higher than current {current}") |
| 62 | + sys.exit(1) |
| 63 | + |
| 64 | + print(f"Bumping {current} → {version}:") |
| 65 | + bump(version) |
| 66 | + |
| 67 | + |
| 68 | +if __name__ == "__main__": |
| 69 | + main() |
0 commit comments