9f97f3abbe
CI - Node Bindings / Build darwin-arm64 (push) Waiting to run
CI - Node Bindings / Build darwin-x64 (push) Waiting to run
CI - Node Bindings / Test win32-x64-msvc (push) Blocked by required conditions
CI - Node Bindings / Build linux-arm64-gnu (push) Waiting to run
CI - Node Bindings / Build linux-x64-gnu (push) Waiting to run
CI - Node Bindings / Build linux-x64-musl (push) Waiting to run
CI - Node Bindings / Build win32-arm64-msvc (push) Waiting to run
CI - Node Bindings / Build win32-x64-msvc (push) Waiting to run
CI - Node Bindings / Test darwin-arm64 (push) Blocked by required conditions
CI - Node Bindings / Test darwin-x64 (push) Blocked by required conditions
CI - Node Bindings / Test linux-x64-gnu (push) Blocked by required conditions
CI - Node Bindings / Test linux-x64-musl (push) Blocked by required conditions
CI - Node Bindings / Test win32-arm64-msvc (push) Blocked by required conditions
CI - Python Bindings / Build aarch64-pc-windows-msvc (push) Waiting to run
CI - Python Bindings / Build x86_64-pc-windows-msvc (push) Waiting to run
CI - Python Bindings / Build x86_64-apple-darwin (push) Waiting to run
CI - Python Bindings / Build aarch64-apple-darwin (push) Waiting to run
CI - Python Bindings / Build aarch64-unknown-linux-gnu (push) Waiting to run
CI - Python Bindings / Test x86_64-apple-darwin (push) Blocked by required conditions
CI - Python Bindings / Test aarch64-apple-darwin (push) Blocked by required conditions
CI - Python Bindings / Test x86_64-unknown-linux-gnu (push) Blocked by required conditions
CI - Python Bindings / Test x86_64-unknown-linux-musl (push) Blocked by required conditions
CI - Python Bindings / Test aarch64-pc-windows-msvc (push) Blocked by required conditions
CI - Python Bindings / Test x86_64-pc-windows-msvc (push) Blocked by required conditions
CI / build-and-test (macos-26-intel) (push) Waiting to run
CI / build-and-test (macos-latest) (push) Waiting to run
CI / build-and-test (windows-11-arm) (push) Waiting to run
CI / build-and-test (windows-latest) (push) Waiting to run
CI - Python Bindings / sdist (push) Failing after 1s
CI - Python Bindings / Build x86_64-unknown-linux-musl (push) Failing after 1s
CI / fmt (push) Failing after 1s
E2E Output Validation / compare-outputs (push) Failing after 1s
Sync Docs to Developer Hub / sync-docs (push) Failing after 1s
CI - Python Bindings / Build x86_64-unknown-linux-gnu (push) Failing after 1s
CI - WASM Bindings / Build WASM (push) Failing after 0s
CI / clippy (push) Failing after 1s
CI / build-and-test (ubuntu-latest) (push) Failing after 0s
CI - WASM Bindings / Edge runtime PDF parse test (push) Has been skipped
CI - WASM Bindings / Browser PDF parse test (push) Has been skipped
E2E Output Validation / upload-dataset (push) Waiting to run
Deploy Demo to GitHub Pages / deploy (push) Failing after 1s
CI / build-docker-image (push) Failing after 3s
201 lines
6.1 KiB
Python
Executable File
201 lines
6.1 KiB
Python
Executable File
#!/usr/bin/env -S uv run --script
|
|
# /// script
|
|
# requires-python = ">=3.10"
|
|
# dependencies = []
|
|
# ///
|
|
|
|
"""Bump the version of LiteParse packages.
|
|
|
|
Updates versions across:
|
|
- crates/liteparse/Cargo.toml
|
|
- crates/liteparse-napi/Cargo.toml (and its liteparse dep)
|
|
- crates/liteparse-python/Cargo.toml (and its liteparse dep)
|
|
- crates/liteparse-wasm/Cargo.toml
|
|
- packages/node/package.json
|
|
- packages/wasm/package.json
|
|
- packages/python/pyproject.toml (PEP 440 form, e.g. 2.0.1b1)
|
|
|
|
Excludes pdfium and pdfium-sys crates.
|
|
|
|
Accepts versions in:
|
|
- major.minor.patch e.g. 2.0.1
|
|
- major.minor.patch-pre.number e.g. 2.0.1-beta.1, 2.0.1-alpha.0, 2.0.1-rc.2
|
|
|
|
Usage:
|
|
scripts/bump-version.py <version> # update all packages
|
|
scripts/bump-version.py <version> --package <pkg> # update only one
|
|
where <pkg> is one of: core, node, python, wasm
|
|
|
|
Examples:
|
|
scripts/bump-version.py 2.0.1
|
|
scripts/bump-version.py 2.0.1-beta.1
|
|
scripts/bump-version.py 2.1.0-rc.0 --package python
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
|
|
SEMVER_RE = re.compile(
|
|
r"^(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)"
|
|
r"(?:-(?P<pre>alpha|beta|rc)\.(?P<num>\d+))?$"
|
|
)
|
|
|
|
PRE_TO_PEP440 = {"alpha": "a", "beta": "b", "rc": "rc"}
|
|
|
|
|
|
def parse_version(v: str) -> tuple[str, str | None, int | None]:
|
|
"""Return (base "X.Y.Z", pre_label or None, pre_num or None)."""
|
|
m = SEMVER_RE.match(v)
|
|
if not m:
|
|
raise SystemExit(
|
|
f"Invalid version: {v!r}. Expected X.Y.Z or X.Y.Z-(alpha|beta|rc).N"
|
|
)
|
|
base = f"{m['major']}.{m['minor']}.{m['patch']}"
|
|
pre = m["pre"]
|
|
num = int(m["num"]) if m["num"] is not None else None
|
|
return base, pre, num
|
|
|
|
|
|
def to_semver(base: str, pre: str | None, num: int | None) -> str:
|
|
if pre is None:
|
|
return base
|
|
return f"{base}-{pre}.{num}"
|
|
|
|
|
|
def to_pep440(base: str, pre: str | None, num: int | None) -> str:
|
|
if pre is None:
|
|
return base
|
|
return f"{base}{PRE_TO_PEP440[pre]}{num}"
|
|
|
|
|
|
def replace_in_file(
|
|
path: Path, pattern: str, replacement: str, *, expect: int = 1
|
|
) -> None:
|
|
text = path.read_text()
|
|
new_text, n = re.subn(pattern, replacement, text, count=expect if expect else 0)
|
|
if expect and n != expect:
|
|
raise SystemExit(
|
|
f"{path}: expected {expect} replacement(s) for /{pattern}/, made {n}"
|
|
)
|
|
if n == 0:
|
|
print(f" (no changes in {path.relative_to(REPO_ROOT)})")
|
|
return
|
|
path.write_text(new_text)
|
|
print(
|
|
f" updated {path.relative_to(REPO_ROOT)} ({n} change{'s' if n != 1 else ''})"
|
|
)
|
|
|
|
|
|
def update_cargo_version(path: Path, new_version: str) -> None:
|
|
# Update the first top-level `version = "..."` line (the [package] version).
|
|
replace_in_file(
|
|
path,
|
|
r'(?m)^version\s*=\s*"[^"]+"',
|
|
f'version = "{new_version}"',
|
|
expect=1,
|
|
)
|
|
|
|
|
|
def update_liteparse_dep(path: Path, new_version: str) -> None:
|
|
# Update the inline `liteparse = { package = "liteparse", version = "..." }` line.
|
|
replace_in_file(
|
|
path,
|
|
r'(liteparse\s*=\s*\{\s*package\s*=\s*"liteparse"\s*,\s*version\s*=\s*)"[^"]+"',
|
|
rf'\1"{new_version}"',
|
|
expect=1,
|
|
)
|
|
|
|
|
|
def update_json_version(path: Path, new_version: str) -> None:
|
|
# Update the top-level "version": "..." field in a package.json.
|
|
replace_in_file(
|
|
path,
|
|
r'("version"\s*:\s*)"[^"]+"',
|
|
rf'\1"{new_version}"',
|
|
expect=1,
|
|
)
|
|
|
|
|
|
def update_pyproject_version(path: Path, new_version: str) -> None:
|
|
# Update the `version = "..."` field in pyproject.toml's [project] table.
|
|
replace_in_file(
|
|
path,
|
|
r'(?m)^version\s*=\s*"[^"]+"',
|
|
f'version = "{new_version}"',
|
|
expect=1,
|
|
)
|
|
|
|
|
|
def bump_core(semver: str) -> None:
|
|
print("• core (crates/liteparse)")
|
|
update_cargo_version(REPO_ROOT / "crates/liteparse/Cargo.toml", semver)
|
|
# Also update the path-dep version pin used by napi/python crates so it
|
|
# stays in sync with the core crate's own version.
|
|
print(" syncing liteparse dep version in dependent crates")
|
|
update_liteparse_dep(REPO_ROOT / "crates/liteparse-napi/Cargo.toml", semver)
|
|
update_liteparse_dep(REPO_ROOT / "crates/liteparse-python/Cargo.toml", semver)
|
|
|
|
|
|
def bump_node(semver: str) -> None:
|
|
print("• node (crates/liteparse-napi + packages/node)")
|
|
update_cargo_version(REPO_ROOT / "crates/liteparse-napi/Cargo.toml", semver)
|
|
update_json_version(REPO_ROOT / "packages/node/package.json", semver)
|
|
|
|
|
|
def bump_python(semver: str, pep440: str) -> None:
|
|
print("• python (crates/liteparse-python + packages/python)")
|
|
update_cargo_version(REPO_ROOT / "crates/liteparse-python/Cargo.toml", semver)
|
|
update_pyproject_version(REPO_ROOT / "packages/python/pyproject.toml", pep440)
|
|
|
|
|
|
def bump_wasm(semver: str) -> None:
|
|
print("• wasm (crates/liteparse-wasm + packages/wasm)")
|
|
update_cargo_version(REPO_ROOT / "crates/liteparse-wasm/Cargo.toml", semver)
|
|
update_json_version(REPO_ROOT / "packages/wasm/package.json", semver)
|
|
|
|
|
|
PACKAGES = ("core", "node", "python", "wasm")
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description="Bump LiteParse package versions.")
|
|
parser.add_argument("version", help="Target version (e.g. 2.0.1 or 2.0.1-beta.1)")
|
|
parser.add_argument(
|
|
"--package",
|
|
choices=PACKAGES,
|
|
help="Update only one package group (default: all)",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
base, pre, num = parse_version(args.version)
|
|
semver = to_semver(base, pre, num)
|
|
pep440 = to_pep440(base, pre, num)
|
|
|
|
print(f"Target semver: {semver}")
|
|
print(f"Target PEP 440: {pep440}")
|
|
print()
|
|
|
|
targets = (args.package,) if args.package else PACKAGES
|
|
for pkg in targets:
|
|
if pkg == "core":
|
|
bump_core(semver)
|
|
elif pkg == "node":
|
|
bump_node(semver)
|
|
elif pkg == "python":
|
|
bump_python(semver, pep440)
|
|
elif pkg == "wasm":
|
|
bump_wasm(semver)
|
|
|
|
print("\nDone.")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|