83 lines
2 KiB
Python
Executable file
83 lines
2 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
from pathlib import Path
|
|
from pprint import pprint
|
|
from itertools import chain
|
|
from subprocess import check_call, run, PIPE
|
|
import sys
|
|
from typing import List, Optional, Iterable
|
|
|
|
|
|
def log(*args):
|
|
print(*args, file=sys.stderr)
|
|
|
|
|
|
DIR = Path(__file__).absolute().parent
|
|
|
|
# hmm. I guess I need to check all subpackages separately
|
|
# otherwise pylint doesn't work and mypy doesn't discover everything
|
|
|
|
# TODO could reuse in readme??
|
|
# returns None if not a package
|
|
def package_name(p: Path) -> Optional[str]:
|
|
def mname(p: Path):
|
|
nosuf = p.with_suffix('')
|
|
return str(nosuf).replace('/', '.')
|
|
|
|
if p.suffix == '.py':
|
|
return mname(p)
|
|
|
|
if p.is_dir() and (p / '__init__.py').exists():
|
|
return mname(p)
|
|
|
|
return None
|
|
|
|
|
|
def packages() -> Iterable[str]:
|
|
for p in sorted(p.relative_to(DIR) for p in (DIR / 'my').iterdir()):
|
|
res = package_name(p)
|
|
if res is not None:
|
|
yield res
|
|
|
|
|
|
def pylint():
|
|
# TODO ugh. pylint still doesn't like checking my.config or my.books
|
|
# only top level .py files seem ok??
|
|
pass
|
|
|
|
|
|
def mypy(package: str):
|
|
return run([
|
|
'mypy',
|
|
'--color-output', # TODO eh? doesn't work..
|
|
'--namespace-packages',
|
|
'-p', package,
|
|
], stdout=PIPE, stderr=PIPE)
|
|
|
|
|
|
def mypy_all() -> Iterable[Exception]:
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
pkgs = list(packages())
|
|
log(f"Checking {pkgs}")
|
|
with ThreadPoolExecutor() as pool:
|
|
for p, res in zip(pkgs, pool.map(mypy, pkgs)):
|
|
ret = res.returncode
|
|
if ret > 0:
|
|
log(f'FAILED: {p}')
|
|
else:
|
|
log(f'OK: {p}')
|
|
print(res.stdout.decode('utf8'))
|
|
print(res.stderr.decode('utf8'), file=sys.stderr)
|
|
try:
|
|
res.check_returncode()
|
|
except Exception as e:
|
|
yield e
|
|
|
|
|
|
def main():
|
|
errors = list(mypy_all())
|
|
if len(errors) > 0:
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|