File: migrate-black.py

package info (click to toggle)
black 25.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,180 kB
  • sloc: python: 113,389; makefile: 25
file content (96 lines) | stat: -rwxr-xr-x 2,979 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env python3
# check out every commit added by the current branch, blackify them,
# and generate diffs to reconstruct the original commits, but then
# blackified
import logging
import os
import sys
from subprocess import PIPE, Popen, check_output, run


def git(*args: str) -> str:
    return check_output(["git", *args]).decode("utf8").strip()


def blackify(base_branch: str, black_command: str, logger: logging.Logger) -> int:
    current_branch = git("branch", "--show-current")

    if not current_branch or base_branch == current_branch:
        logger.error("You need to check out a feature branch to work on")
        return 1

    if not os.path.exists(".git"):
        logger.error("Run me in the root of your repo")
        return 1

    merge_base = git("merge-base", "HEAD", base_branch)
    if not merge_base:
        logger.error(
            f"Could not find a common commit for current head and {base_branch}"
        )
        return 1

    commits = git(
        "log", "--reverse", "--pretty=format:%H", f"{merge_base}~1..HEAD"
    ).split()
    for commit in commits:
        git("checkout", commit, f"-b{commit}-black")
        check_output(black_command, shell=True)
        git("commit", "-aqm", "blackify")

    git("checkout", base_branch, f"-b{current_branch}-black")

    for last_commit, commit in zip(commits, commits[1:], strict=False):
        allow_empty = (
            b"--allow-empty" in run(["git", "apply", "-h"], stdout=PIPE).stdout
        )
        quiet = b"--quiet" in run(["git", "apply", "-h"], stdout=PIPE).stdout
        git_diff = Popen(
            [
                "git",
                "diff",
                "--binary",
                "--find-copies",
                f"{last_commit}-black..{commit}-black",
            ],
            stdout=PIPE,
        )
        git_apply = Popen(
            [
                "git",
                "apply",
            ]
            + (["--quiet"] if quiet else [])
            + [
                "-3",
                "--intent-to-add",
            ]
            + (["--allow-empty"] if allow_empty else [])
            + [
                "-",
            ],
            stdin=git_diff.stdout,
        )
        if git_diff.stdout is not None:
            git_diff.stdout.close()
        git_apply.communicate()
        git("commit", "--allow-empty", "-aqC", commit)

    for commit in commits:
        git("branch", "-qD", f"{commit}-black")

    return 0


if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument("base_branch")
    parser.add_argument("--black_command", default="black -q .")
    parser.add_argument("--logfile", type=argparse.FileType("w"), default=sys.stdout)
    args = parser.parse_args()
    logger = logging.getLogger(__name__)
    logger.addHandler(logging.StreamHandler(args.logfile))
    logger.setLevel(logging.INFO)
    sys.exit(blackify(args.base_branch, args.black_command, logger))