The Meson Build System
http://mesonbuild.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.5 KiB
77 lines
2.5 KiB
3 years ago
|
#!/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())
|