Skip to content

Instantly share code, notes, and snippets.

@mithro
Last active May 24, 2019 22:12
Show Gist options
  • Save mithro/9bf7ff31e55791c230f00da93de0da0b to your computer and use it in GitHub Desktop.
Save mithro/9bf7ff31e55791c230f00da93de0da0b to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import argparse
import datetime
import getpass
import subprocess
import sys
import tempfile
parser = argparse.ArgumentParser()
parser.add_argument("--user", default=getpass.getuser(), help="")
args = parser.parse_args()
subprocess.check_call("git reset --hard origin/master", shell=True)
# Get the formatting repo
remotes = subprocess.check_output("git remote", shell=True)
if b"format" not in remotes:
print("Adding format remote.")
subprocess.check_call(
"git remote add format git+ssh://github.com/{}/vtr-code-format.git".format(args.user),
shell=True)
subprocess.check_call("git fetch format", shell=True)
subprocess.check_call("git reset --hard origin/master", shell=True)
# Get the formatting repo
remotes = subprocess.check_output("git remote", shell=True)
if b"format" not in remotes:
print("Adding format remote.")
subprocess.check_call("git remote add format git+ssh://github.com/mithro/vtr-code-format.git", shell=True)
subprocess.check_call("git fetch format", shell=True)
git_commit_args = [
'-a',
'--no-verify',
'--author="VtR Robot <robot@verilogtorouting.org>"',
]
git_commit_args = " ".join(git_commit_args)
conflict_markers = [
"<<<<<<",
">>>>>>",
]
# Merge it into the repo
rc = subprocess.call("git merge format/master --allow-unrelated-histories", shell=True)
if rc != 0:
# Check if all conflicts have been autofixed...
files = subprocess.check_output("git diff --name-only --diff-filter=U", shell=True)
files = files.decode("utf-8", errors="replace")
conflicts = []
for fname in files.splitlines():
with open(fname, "r") as f:
data = f.read()
if conflict_markers[0] in data:
conflicts.append(fname)
else:
subprocess.check_output("git add {}".format(fname), shell=True)
print()
if conflicts:
print("Following files have conflicts:")
print(" *", "\n *".join(conflicts))
# Launch a shell as it will probably need fixup.
subprocess.check_call("bash")
subprocess.check_call("git merge --continue", shell=True)
else:
subprocess.check_call("EDITOR=cat git merge --continue", shell=True)
after_merge_diff = subprocess.check_output("git diff origin/master", shell=True)
after_merge_diff = after_merge_diff.decode("utf-8", errors="replace")
for c in conflict_markers:
c = c+c[-1]
assert c not in after_merge_diff, """\
=======================================
{diff}
=======================================
Conflict {c} marker found in above diff
""".format(c=repr(c), diff=after_merge_diff)
now = datetime.datetime.utcnow().isoformat()
# Run `make format`
subprocess.check_call("make format", shell=True)
# Commit the changes caused by `make format`
with tempfile.NamedTemporaryFile("w") as msg:
msg.write("""\
🤖 - Automated reformat.
I'm an auto reformatting bot. Beep boop...
""")
msg.flush()
subprocess.check_call(
"git commit {} --file={msg}".format(git_commit_args, msg=msg.name),
shell=True,
)
# Append the format change to the .git-blame-ignore-revs file.
format_hash = subprocess.check_output(
"git rev-parse --verify HEAD", shell=True)
format_hash = format_hash.decode("utf-8").strip()
with open(".git-blame-ignore-revs", "a+") as bf:
bf.write("""\
# Autoformat run on {}
{}
""".format(now, format_hash))
subprocess.check_call("git add .git-blame-ignore-revs", shell=True)
with tempfile.NamedTemporaryFile("w") as msg:
msg.write("""\
🤖 - Ignore automated reformat in blame.
Ignoring the reformatting change
{}
which I just committed!
I'm an auto reformatting bot. beep boop...
""".format(format_hash))
msg.flush()
subprocess.check_call(
"git commit {} --file={msg}".format(git_commit_args, msg=msg.name),
shell=True,
)
subprocess.check_call("git push {} HEAD:format --force".format(args.user), shell=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment