Skip to content

Commit 54ab4d3

Browse files
committed
feat(utils): add unasync util to generate sync version of the client
1 parent 133bb02 commit 54ab4d3

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

utils/run-unasync.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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+
replacements["aclose"] = "close"
25+
return replacements
26+
27+
28+
def collect_files(source_dir: Path) -> list[str]:
29+
filepaths: list[str] = []
30+
for root, _, filenames in os.walk(source_dir):
31+
for filename in filenames:
32+
if filename.endswith(".py"):
33+
filepaths.append(os.path.join(root, filename))
34+
return filepaths
35+
36+
37+
def run_unasync(output_dir: Path, check: bool = False) -> None:
38+
source_dir = ASYNC_DIR.resolve()
39+
target_dir = output_dir.resolve()
40+
target_dir.mkdir(parents=True, exist_ok=True)
41+
42+
replacements = collect_class_replacements(source_dir)
43+
rule = unasync.Rule(
44+
fromdir=f"{source_dir.as_posix()}/",
45+
todir=f"{target_dir.as_posix()}/",
46+
additional_replacements=replacements,
47+
)
48+
filepaths = collect_files(source_dir)
49+
unasync.unasync_files(filepaths, [rule])
50+
51+
if check:
52+
diffs: list[str] = []
53+
for path in target_dir.rglob("*.py"):
54+
rel = path.relative_to(target_dir)
55+
expected = SYNC_DIR / rel
56+
if not expected.exists():
57+
diffs.append(f"Missing in sync: {expected}")
58+
continue
59+
if not filecmp.cmp(path, expected, shallow=False):
60+
diffs.append(f"Differs: {expected}")
61+
if diffs:
62+
header = [
63+
"Sync sources are out of date.",
64+
"Run: uv run python utils/run-unasync.py",
65+
"",
66+
"Differences:",
67+
]
68+
raise SystemExit("\n".join([*header, *diffs]))
69+
70+
71+
def main() -> None:
72+
parser = argparse.ArgumentParser()
73+
parser.add_argument("--check", action="store_true")
74+
args = parser.parse_args()
75+
76+
if args.check:
77+
if CHECK_DIR.exists():
78+
shutil.rmtree(CHECK_DIR)
79+
run_unasync(CHECK_DIR, check=True)
80+
shutil.rmtree(CHECK_DIR)
81+
return
82+
83+
run_unasync(SYNC_DIR)
84+
85+
86+
if __name__ == "__main__":
87+
main()

0 commit comments

Comments
 (0)