-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathformat_docs.py
More file actions
99 lines (77 loc) · 2.79 KB
/
format_docs.py
File metadata and controls
99 lines (77 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/env python3
"""Reformat YAML docs-db files to ensure literal block scalars for code examples.
Usage:
forge format docs-db # reformat all YAML files in place
forge format docs-db --check # check only, exit 1 if any need reformatting
forge format docs-db/Config.yaml # reformat a single file
"""
from __future__ import annotations
import logging
import sys
from pathlib import Path
import yaml
from utils import LiteralStr, LiteralDumper
log = logging.getLogger("format")
def needs_reformatting(path: Path) -> bool:
"""Check if any multiline code example uses flow-scalar (quoted) instead of |- block."""
import re
content = path.read_text(encoding="utf-8")
# Look for patterns like `swift: "...\n..."` or `kotlin: "...\n..."`
# These indicate flow-scalar strings with escaped newlines
return bool(re.search(r'(?:ts|swift|kotlin):\s*["\'].*\\n', content))
def reformat(data: dict) -> dict:
"""Convert all multiline code examples to LiteralStr for |- rendering."""
for ex_val in data.get("examples", {}).values():
code = ex_val.get("code", {})
for lang in ("ts", "swift", "kotlin"):
val = code.get(lang)
if isinstance(val, str) and "\n" in val:
code[lang] = LiteralStr(val)
return data
def main(argv: list[str] | None = None) -> int:
argv = list(argv or [])
check_only = "--check" in argv
if check_only:
argv.remove("--check")
if not argv:
print("Usage: forge format <docs-dir-or-file> [--check]", file=sys.stderr)
return 2
target = Path(argv[0])
if target.is_dir():
files = sorted(target.glob("*.yaml"))
elif target.is_file():
files = [target]
else:
print(f"Not found: {target}", file=sys.stderr)
return 2
reformatted = 0
for f in files:
data = yaml.safe_load(f.read_text(encoding="utf-8"))
if not isinstance(data, dict):
continue
if not needs_reformatting(f):
continue
reformatted += 1
if check_only:
print(f" needs formatting: {f}")
continue
reformat(data)
with f.open("w", encoding="utf-8") as out:
yaml.dump(
data,
out,
Dumper=LiteralDumper,
default_flow_style=False,
allow_unicode=True,
sort_keys=False,
width=120,
)
log.info("reformatted %s", f)
if check_only and reformatted:
print(f"\n{reformatted} file(s) need reformatting. Run: forge format {target}")
return 1
if not check_only:
print(f"Reformatted {reformatted} of {len(files)} files")
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv[1:]))