|
| 1 | +import ast |
| 2 | +import os |
| 3 | +import shutil |
| 4 | +import subprocess |
| 5 | +import sys |
| 6 | + |
| 7 | +import black |
| 8 | +from black import check_stability_and_equivalence |
| 9 | +from tokenize_rt import reversed_enumerate |
| 10 | +from tokenize_rt import src_to_tokens |
| 11 | +from tokenize_rt import tokens_to_src |
| 12 | + |
| 13 | +GIT_EXECUTABLE = shutil.which('git') |
| 14 | + |
| 15 | +changes = 0 |
| 16 | + |
| 17 | + |
| 18 | +def _rewrite_file(filename: str) -> int: |
| 19 | + with open(filename, encoding='UTF-8') as f: |
| 20 | + contents = f.read() |
| 21 | + tree = ast.parse(contents, filename=filename) |
| 22 | + tokens = src_to_tokens(contents) |
| 23 | + nodes_on_lines_to_remove = [] |
| 24 | + for tok in tokens: |
| 25 | + if tok.name == 'COMMENT' and 'unasync: remove' in tok.src: |
| 26 | + nodes_on_lines_to_remove.append(tok.line) |
| 27 | + lines_to_remove = set() |
| 28 | + for node in ast.walk(tree): |
| 29 | + if hasattr(node, 'lineno') and node.lineno in nodes_on_lines_to_remove: |
| 30 | + for lineno in range(node.lineno, node.end_lineno + 1): |
| 31 | + lines_to_remove.add(lineno) |
| 32 | + for i, tok in reversed_enumerate(tokens): |
| 33 | + if tok.line in lines_to_remove: |
| 34 | + tokens.pop(i) |
| 35 | + new_contents = tokens_to_src(tokens) |
| 36 | + if new_contents != contents: |
| 37 | + with open(filename, 'w') as f: |
| 38 | + f.write(new_contents) |
| 39 | + return new_contents != contents |
| 40 | + |
| 41 | + |
| 42 | +def _copyfunc(src, dst, *, follow_symlinks=True): |
| 43 | + global changes |
| 44 | + with open(src, encoding='UTF-8') as f: |
| 45 | + contents = f.read() |
| 46 | + if os.path.exists(dst): |
| 47 | + with open(dst, encoding='UTF-8') as dst_f: |
| 48 | + dst_contents = dst_f.read() |
| 49 | + try: |
| 50 | + black.assert_equivalent( |
| 51 | + src=contents, |
| 52 | + dst=dst_contents, |
| 53 | + ) |
| 54 | + except AssertionError: |
| 55 | + changes += 1 |
| 56 | + print('MODIFIED', dst) |
| 57 | + shutil.copy2(src, dst, follow_symlinks=follow_symlinks) |
| 58 | + else: |
| 59 | + changes += 1 |
| 60 | + print('ADDED', dst) |
| 61 | + shutil.copy2(src, dst, follow_symlinks=follow_symlinks) |
| 62 | + if GIT_EXECUTABLE is None: |
| 63 | + print('WARNING could not find git!', file=sys.stderr) |
| 64 | + else: |
| 65 | + subprocess.run([GIT_EXECUTABLE, 'add', '--intent-to-add', dst]) |
| 66 | + return dst |
| 67 | + |
| 68 | + |
| 69 | +def main() -> int: |
| 70 | + if os.path.isdir('build'): |
| 71 | + shutil.rmtree('build') |
| 72 | + subprocess.run([sys.executable, 'setup.py', 'build_py'], check=True) |
| 73 | + for root, dirs, files in os.walk('build/lib/ahk/_sync'): |
| 74 | + for fname in files: |
| 75 | + if fname.endswith('.py'): |
| 76 | + fp = os.path.join(root, fname) |
| 77 | + _rewrite_file(fp) |
| 78 | + subprocess.run([sys.executable, '_tests_setup.py', 'build_py'], check=True) |
| 79 | + for root, dirs, files in os.walk('build/lib/tests/_sync'): |
| 80 | + for fname in files: |
| 81 | + if fname.endswith('.py'): |
| 82 | + fp = os.path.join(root, fname) |
| 83 | + _rewrite_file(fp) |
| 84 | + shutil.copytree('build/lib/ahk/_sync', 'ahk/_sync', dirs_exist_ok=True, copy_function=_copyfunc) |
| 85 | + shutil.copytree('build/lib/tests/_sync', 'tests/_sync', dirs_exist_ok=True, copy_function=_copyfunc) |
| 86 | + |
| 87 | + return changes |
| 88 | + |
| 89 | + |
| 90 | +if __name__ == '__main__': |
| 91 | + raise SystemExit(main()) |
0 commit comments