diff options
Diffstat (limited to 'meson/run_custom_lint.py')
-rwxr-xr-x | meson/run_custom_lint.py | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/meson/run_custom_lint.py b/meson/run_custom_lint.py new file mode 100755 index 000000000..89de9506e --- /dev/null +++ b/meson/run_custom_lint.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +from pathlib import Path +import typing as T + +root = Path(__file__).absolute().parent +mesonbuild = root / 'mesonbuild' + +whitelist = ['mesonbuild/', 'run_', 'ci/', 'tools/', 'docs/'] + +def check_missing_encoding(lines: T.List[str], path: str) -> int: + errors = 0 + functions = ['read_text', 'write_text', 'open'] + for num, line in enumerate(lines): + for func in functions: + l = line + + # Skip ignored lines + if '[ignore encoding]' in l: + continue + + # Do we have a match? + loc = l.find(func + '(') + if loc < 0: + continue + if loc > 0 and ord(l[loc-1].lower()) in [*range(ord('a'), ord('z')), *range(ord('0'), ord('9')), '_']: + continue + loc += len(func) + 1 + # Some preprocessign to make parsing easier + l = l[loc:] + l = l.replace(' ', '') + l = l.replace('\t', '') + l = l.replace('\n', '') + l = l.replace('\'', '"') + + # Parameter begin + args = '' + b_open = 1 + while l: + c = l[0] + l = l[1:] + if c == ')': + b_open -= 1 + if b_open == 0: + break + elif b_open == 1: + args += c + if c == '(': + b_open += 1 + + binary_modes = ['rb', 'br', 'r+b', 'wb', 'bw', 'ab', 'ba'] + is_binary = any([f'"{x}"' in args for x in binary_modes]) + if 'encoding=' not in args and not (func == 'open' and is_binary): + location = f'\x1b[33;1m[\x1b[0;1m{path}:{num+1}\x1b[33m]\x1b[0m' + #print(f'{location:<64}: \x1b[31;1mERROR:\x1b[0m Missing `encoding=` parameter in "{line.strip()}"') + print(f'{location:<72}: \x1b[31;1mERROR:\x1b[0m Missing `encoding=` parameter in `{func}` call') + errors += 1 + return errors + +def main() -> int: + print('Scanning mesonbuild...') + errors = 0 + for i in sorted(root.glob('**/*.py')): + raw = i.read_text(encoding='utf-8') + lines = raw.splitlines() + filename = i.relative_to(root).as_posix() + + if not any([filename.startswith(x) for x in whitelist]): + continue + + errors += check_missing_encoding(lines, filename) + print(f'Found {errors} errors while scanning mesonbuild') + return 0 if errors == 0 else 1 + +if __name__ == '__main__': + raise SystemExit(main()) |