Skip to content

Commit 3fa49b8

Browse files
committed
feat(utils): add unasync util to generate sync version of the client
1 parent 9f0fbd9 commit 3fa49b8

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

utils/run-unasync.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import argparse
2+
import filecmp
3+
import os
4+
import re
5+
import shutil
6+
from pathlib import Path
7+
8+
import unasync
9+
10+
11+
ASYNC_DIR = Path("src/typesense/async_")
12+
SYNC_DIR = Path("src/typesense/sync")
13+
CHECK_DIR = Path("src/typesense/sync_check")
14+
15+
16+
def collect_class_replacements(source_dir: Path) -> dict[str, str]:
17+
replacements: dict[str, str] = {}
18+
pattern = re.compile(r"^class\s+(Async\w+)", re.MULTILINE)
19+
for path in source_dir.rglob("*.py"):
20+
text = path.read_text()
21+
for match in pattern.finditer(text):
22+
async_name = match.group(1)
23+
replacements[async_name] = async_name[len("Async") :]
24+
return replacements
25+
26+
27+
def collect_files(source_dir: Path) -> list[str]:
28+
filepaths: list[str] = []
29+
for root, _, filenames in os.walk(source_dir):
30+
for filename in filenames:
31+
if filename.endswith(".py"):
32+
filepaths.append(os.path.join(root, filename))
33+
return filepaths
34+
35+
36+
def run_unasync(output_dir: Path, check: bool = False) -> None:
37+
source_dir = ASYNC_DIR.resolve()
38+
target_dir = output_dir.resolve()
39+
target_dir.mkdir(parents=True, exist_ok=True)
40+
41+
replacements = collect_class_replacements(source_dir)
42+
rule = unasync.Rule(
43+
fromdir=f"{source_dir.as_posix()}/",
44+
todir=f"{target_dir.as_posix()}/",
45+
additional_replacements=replacements,
46+
)
47+
filepaths = collect_files(source_dir)
48+
unasync.unasync_files(filepaths, [rule])
49+
50+
if check:
51+
diffs: list[str] = []
52+
for path in target_dir.rglob("*.py"):
53+
rel = path.relative_to(target_dir)
54+
expected = SYNC_DIR / rel
55+
if not expected.exists():
56+
diffs.append(f"Missing in sync: {expected}")
57+
continue
58+
if not filecmp.cmp(path, expected, shallow=False):
59+
diffs.append(f"Differs: {expected}")
60+
if diffs:
61+
header = [
62+
"Sync sources are out of date.",
63+
"Run: uv run python utils/run-unasync.py",
64+
"",
65+
"Differences:",
66+
]
67+
raise SystemExit("\n".join([*header, *diffs]))
68+
69+
70+
def main() -> None:
71+
parser = argparse.ArgumentParser()
72+
parser.add_argument("--check", action="store_true")
73+
args = parser.parse_args()
74+
75+
if args.check:
76+
if CHECK_DIR.exists():
77+
shutil.rmtree(CHECK_DIR)
78+
run_unasync(CHECK_DIR, check=True)
79+
shutil.rmtree(CHECK_DIR)
80+
return
81+
82+
run_unasync(SYNC_DIR)
83+
84+
85+
if __name__ == "__main__":
86+
main()

0 commit comments

Comments
 (0)