|
| 1 | +"""Cherry-pick a commit from typeshed. |
| 2 | +
|
| 3 | +Usage: |
| 4 | +
|
| 5 | + python3 misc/cherry-pick-typeshed.py --typeshed-dir dir hash |
| 6 | +""" |
| 7 | + |
| 8 | +import argparse |
| 9 | +import os.path |
| 10 | +import re |
| 11 | +import subprocess |
| 12 | +import sys |
| 13 | +import tempfile |
| 14 | + |
| 15 | + |
| 16 | +def parse_commit_title(diff: str) -> str: |
| 17 | + m = re.search("\n ([^ ].*)", diff) |
| 18 | + assert m is not None, "Could not parse diff" |
| 19 | + return m.group(1) |
| 20 | + |
| 21 | + |
| 22 | +def main() -> None: |
| 23 | + parser = argparse.ArgumentParser() |
| 24 | + parser.add_argument( |
| 25 | + "--typeshed-dir", help="location of typeshed", metavar="dir", required=True |
| 26 | + ) |
| 27 | + parser.add_argument( |
| 28 | + "commit", help="typeshed commit hash to cherry-pick" |
| 29 | + ) |
| 30 | + args = parser.parse_args() |
| 31 | + typeshed_dir = args.typeshed_dir |
| 32 | + commit = args.commit |
| 33 | + |
| 34 | + if not os.path.isdir(typeshed_dir): |
| 35 | + sys.exit(f"error: {typeshed_dir} does not exist") |
| 36 | + if not re.match("[0-9a-fA-F]+$", commit): |
| 37 | + sys.exit(f"error: Invalid commit {commit!r}") |
| 38 | + |
| 39 | + if not os.path.exists("mypy") or not os.path.exists("mypyc"): |
| 40 | + sys.exit(f"error: This script must be run at the mypy repository root directory") |
| 41 | + |
| 42 | + with tempfile.TemporaryDirectory() as d: |
| 43 | + diff_file = os.path.join(d, "diff") |
| 44 | + out = subprocess.run(["git", "show", commit], |
| 45 | + capture_output=True, |
| 46 | + text=True, |
| 47 | + check=True, |
| 48 | + cwd=typeshed_dir) |
| 49 | + with open(diff_file, "w") as f: |
| 50 | + f.write(out.stdout) |
| 51 | + subprocess.run(["git", |
| 52 | + "apply", |
| 53 | + "--index", |
| 54 | + "--directory=mypy/typeshed", |
| 55 | + "--exclude=**/tests/**", |
| 56 | + diff_file], |
| 57 | + check=True) |
| 58 | + |
| 59 | + title = parse_commit_title(out.stdout) |
| 60 | + subprocess.run(["git", "commit", "-m", f"Typeshed cherry-pick: {title}"], check=True) |
| 61 | + |
| 62 | + print() |
| 63 | + print(f"Cherry-picked commit {commit} from {typeshed_dir}") |
| 64 | + |
| 65 | + |
| 66 | +if __name__ == '__main__': |
| 67 | + main() |
0 commit comments