ElyDoc, ElyTable, ElyShow (LibreOfficeKit), ElyPDF (MuPDF), ElyTree (Git), ElyMark (Milkdown and CodeMirror in CEF). ElyMail and ElyAgent follow.
78 lines
2.8 KiB
Python
Executable File
78 lines
2.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Comments stay on one line and under eleven words."""
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
root = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(__file__).resolve().parents[2]
|
|
PATTERNS = [
|
|
"crates/**/*.rs",
|
|
"apps/**/*.rs",
|
|
"scripts/*.sh",
|
|
"tests/**/*.sh",
|
|
"tests/**/*.py",
|
|
"packaging/**/*.sh",
|
|
"packaging/**/*.nsi",
|
|
"packaging/**/*.py",
|
|
"packaging/**/*.swift",
|
|
"tests/engines/*.c",
|
|
"crates/**/*.c",
|
|
"crates/**/*.h",
|
|
"patches/**/*.patch",
|
|
"tests/**/*.swift",
|
|
"apps/*/web/src/**/*.js",
|
|
]
|
|
LINE_COMMENT = {
|
|
".rs": re.compile(r"^\s*//[!/]?\s?(.*)$"),
|
|
".c": re.compile(r"^\s*(?://[!/]?\s?(.*)|/\*\s?(.*?)\s*\*/)$"),
|
|
".h": re.compile(r"^\s*(?://[!/]?\s?(.*)|/\*\s?(.*?)\s*\*/)$"),
|
|
".nsi": re.compile(r"^\s*;\s?(.*)$"),
|
|
".swift": re.compile(r"^\s*//\s?(.*)$"),
|
|
".js": re.compile(r"^\s*(?://\s?(.*)|/\*\*?\s?(.*?)\s*\*/)$"),
|
|
}
|
|
|
|
|
|
def comment_re(path):
|
|
if path.suffix == ".patch":
|
|
return re.compile(r"^\+\s*(?://[!/]?\s?(.*)|/\*\s?(.*?)\s*\*/)$")
|
|
return LINE_COMMENT.get(path.suffix, re.compile(r"^\s*#\s?(.*)$"))
|
|
|
|
|
|
too_long = []
|
|
repeated = {}
|
|
for pattern in PATTERNS:
|
|
for path in sorted(root.glob(pattern)):
|
|
comment = comment_re(path)
|
|
previous = None
|
|
lines = path.read_text().split("\n")
|
|
if path.suffix == ".py":
|
|
start = 1 if lines and lines[0].startswith("#!") else 0
|
|
if start < len(lines) and lines[start].startswith('"""'):
|
|
doc = []
|
|
for line in lines[start:]:
|
|
doc.append(line.strip('" '))
|
|
if line.count('"""') >= 2 or (len(doc) > 1 and '"""' in line):
|
|
break
|
|
lines = lines[:start] + [f"# {text}" for text in doc] + lines[start + len(doc):]
|
|
for number, line in enumerate(lines, 1):
|
|
if line.startswith("#!"):
|
|
continue
|
|
# A block comment left open spans lines.
|
|
if path.suffix in (".c", ".h", ".js") and re.search(r"/\*(?!.*\*/)", line):
|
|
repeated.setdefault(path, number)
|
|
match = comment.match(line)
|
|
said = match and next(group for group in match.groups() if group is not None)
|
|
if match and len(said.split()) > 10:
|
|
too_long.append(f"{path.relative_to(root)}:{number}: {said[:60]}")
|
|
if match and previous == number - 1:
|
|
repeated.setdefault(path, number)
|
|
previous = number if match else None
|
|
|
|
problems = too_long + [
|
|
f"{path.relative_to(root)}:{number}: comment runs past one line"
|
|
for path, number in sorted(repeated.items())
|
|
]
|
|
if problems:
|
|
sys.exit("FAIL: comments break the one-line ten-word rule:\n" + "\n".join(problems))
|
|
print("comments: every comment is one line and ten words or fewer")
|