From 436e12f2904e68acb57a059b1c44f1e0321e2d3f Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Wed, 1 Jun 2022 20:20:02 +0200 Subject: [PATCH] Add script to ease migration to black (#3038) * Add script to ease migration to black * Update CHANGES.md Co-authored-by: Cooper Lees --- CHANGES.md | 2 + scripts/migrate-black.py | 95 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100755 scripts/migrate-black.py diff --git a/CHANGES.md b/CHANGES.md index 6bc67f9db06..a6b6594b57a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -39,6 +39,8 @@ +- Add migrate-black.py script to ease migration to black formatted git project (#3038) + ### Output diff --git a/scripts/migrate-black.py b/scripts/migrate-black.py new file mode 100755 index 00000000000..5a6bc424824 --- /dev/null +++ b/scripts/migrate-black.py @@ -0,0 +1,95 @@ +#!/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 check_output, run, Popen, PIPE + + +def git(*args: str) -> str: + return check_output(["git"] + list(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 brach 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( + "Could not find a common commit for current head and %s" % base_branch + ) + return 1 + + commits = git( + "log", "--reverse", "--pretty=format:%H", "%s~1..HEAD" % merge_base + ).split() + for commit in commits: + git("checkout", commit, "-b%s-black" % commit) + check_output(black_command, shell=True) + git("commit", "-aqm", "blackify") + + git("checkout", base_branch, "-b%s-black" % current_branch) + + for last_commit, commit in zip(commits, commits[1:]): + 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", + "--find-copies", + "%s-black..%s-black" % (last_commit, commit), + ], + 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", "%s-black" % commit) + + 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))