-
Notifications
You must be signed in to change notification settings - Fork 0
/
check_style.py
83 lines (61 loc) · 2.32 KB
/
check_style.py
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
import json
import pathlib
import os
import re
import sys
from typing import List
TRAILING_WHITESPACE_RE = re.compile(r'\s+$')
TODO_RE = re.compile(r'^TODO \([^)]+, [0-9]{4}-[0-9]{2}-[0-9]{2}\): [A-Z]')
def check(path: pathlib.Path) -> List[str]:
"""Check that the document conforms to the style guide."""
text = path.read_text()
lines = text.splitlines()
if len(lines) < 3:
return [f'Expected at least 3 lines, but found {len(lines)}']
errors = [] # type: List[str]
if not lines[0].startswith('# '):
errors.append(
"Expected the first line to be the title starting with '# ', "
f"but got: {json.dumps(lines[0])}")
prev_line_was_heading = False
in_code_block = False
for i, line in enumerate(lines):
if line.startswith('```'):
in_code_block = not in_code_block
if TRAILING_WHITESPACE_RE.match(line):
errors.append(
f"Unexpected trailing whitespace at line {i + 1}: {json.dumps(line)}")
if not in_code_block:
if line.startswith('TODO') and not TODO_RE.match(line):
errors.append(
f"Expected a TODO at line {i+1} given as "
f"'TODO (username, 2021-03-26): Do something', "
f"but got: {json.dumps(line)}")
if prev_line_was_heading and line.strip() != '':
errors.append(
f"Expected an empty line {i + 1} after a heading at line {i}, "
f"but got: {json.dumps(line)}"
)
if line.startswith("#"):
prev_line_was_heading = True
else:
prev_line_was_heading = False
if not text.endswith('\n'):
errors.append(
f"Expected the document to end with a new line.")
return errors
def main() -> int:
docs_dir = pathlib.Path(os.path.realpath(__file__)).parent / "docs"
success = True
for pth in sorted(docs_dir.glob("**/*.md")):
errors = check(path=pth)
if errors:
print(f"There were style errors in: {pth}", file=sys.stderr)
for error in errors:
print(f"* {error}", file=sys.stderr)
success = False
if not success:
return 1
return 0
if __name__ == "__main__":
sys.exit(main())