from __future__ import annotations
import argparse
import pathlib
import re
import sys
from typing import Iterable, Optional
try: import tomllib except ModuleNotFoundError: tomllib = None
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--cargo",
default="Cargo.toml",
type=pathlib.Path,
help="Path to the Cargo.toml file to read (default: Cargo.toml)",
)
parser.add_argument(
"--project",
default="julia/PlotPx/Project.toml",
type=pathlib.Path,
help="Path to the Julia Project.toml to rewrite (default: julia/PlotPx/Project.toml)",
)
return parser.parse_args()
def read_cargo_version(path: pathlib.Path) -> str:
text = path.read_text(encoding="utf-8")
if tomllib is not None:
data = tomllib.loads(text)
try:
version = data["package"]["version"]
except KeyError as exc: raise SystemExit(f"Cargo.toml missing package.version ({exc})") from exc
if not isinstance(version, str): raise SystemExit("package.version must be a string")
return version
match: Optional[re.Match[str]] = re.search(
r"(?m)^version\s*=\s*\"([^\"]+)\"",
text,
)
if not match: raise SystemExit("Unable to locate version in Cargo.toml; install tomli or use Python 3.11+.")
return match.group(1)
def rewrite_project(path: pathlib.Path, version: str) -> bool:
if not path.exists():
raise SystemExit(f"Julia Project.toml not found: {path}")
lines: Iterable[str] = path.read_text(encoding="utf-8").splitlines(keepends=True)
updated_lines = []
saw_version = False
for line in lines:
if line.strip().startswith("version ="):
indent = line.split("version =", 1)[0]
updated_lines.append(f'{indent}version = "{version}"\n')
saw_version = True
else:
updated_lines.append(line)
if not saw_version:
inserted = False
new_lines = []
for line in updated_lines:
new_lines.append(line)
if not inserted and line.strip().startswith("uuid ="):
new_lines.append(f'version = "{version}"\n')
inserted = True
if not inserted:
new_lines.append(f'version = "{version}"\n')
updated_lines = new_lines
new_content = "".join(updated_lines)
if new_content == path.read_text(encoding="utf-8"):
return False
path.write_text(new_content, encoding="utf-8")
return True
def main() -> int:
args = parse_args()
version = read_cargo_version(args.cargo)
changed = rewrite_project(args.project, version)
if changed:
print(f"Updated {args.project} to version {version}")
else:
print(f"{args.project} already at version {version}")
return 0
if __name__ == "__main__":
sys.exit(main())