ansible/roles/batcave/files/zodbot-announce-commits.py
Pierre-Yves Chibon 469a026cb7 batcave: get zodbot to announce commits on the master branch of the dns git repo
Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>
2021-03-16 17:17:27 +01:00

137 lines
3.9 KiB
Python

#!/usr/bin/env python3
# encoding: utf-8
# (c) 2012 Red Hat, Inc.
# Authored by Ricky Elrod
# But when it breaks, don't yell at him because that's mean.
# update hook for FI repos -> zodbot.
import os
import sys
import subprocess
import shlex
import socket
ZODBOT_SERVER = "value01.vpn.fedoraproject.org"
ZODBOT_PORT = 5050
ZODBOT_ANNOUNCE = ["ansible", "dns"]
hook = sys.argv[0]
repodir = sys.argv[1]
channel = sys.argv[2]
old = sys.argv[3]
new = sys.argv[4]
branch = sys.argv[5]
# Split on /, nuke empties from the result, use the last nonempty
# element. This lets us not care if there's a trailing slash.
repodir = [d for d in repodir.split('/') if d][-1]
def run_command(command):
""" Run a command and return a hash with the resulting stdout/stderr."""
escaped = shlex.split(command)
cmd = subprocess.Popen(escaped,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
stdout, stderr = cmd.communicate()
return {"stdout": stdout, "stderr": stderr}
def construct_url(slug):
""" Return a space-padded url to the commit.
If and only if it is handled by pagure. Otherwise, return an empty string.
"""
# Our long url template.
tmpl = "https://pagure.io/fedora-infra/{repo}/c/{slug}"
if repodir in ZODBOT_ANNOUNCE and slug:
return " " + tmpl.format(repo=repodir, slug=slug)
else:
return ""
def parse_commit(commit):
"""
So we're given a commit in the form of:
---
Ricky Elrod - test-repo:a045150 ---- add some more test files...
A foobar/asdf/testfile.1
A foobar/testfile.2
---
Essentially, we rip out the first line and set it aside.
Then all the other lines will begin with M/C/R/A/D/U.
Replace those letters with fancy little symbols (like + for A).
Combine them together in a list/array.
Show the first 4 and if more exist, append '...' to the list.
Lastly, replace the "----" in the original line above with these.
"""
lines = commit.split("\n")
message = lines.pop(0)
files = []
# extract the commit hash from the first line.
slug = None
try:
slug = message.split(' -')[1].strip().split(':')[1]
except IndexError:
print("** Couldn't parse slug from git-rev.", message)
# The remaining lines are files changed.
for changed_file in filter(None, lines):
status, filename = changed_file.split()
if status == "M" or status == "R":
symbol = "*"
elif status == "C" or status == "A":
symbol = "+"
elif status == "D":
symbol = "-"
else:
symbol = "?"
files.append(symbol + filename)
# Show the first 4 files changed, and if there are more, add a '...'
# If no files were changed don't show empty [] because it looks tacky.
fileslist = ' '.join(files[0:4])
if len(files):
fileslist = '[' + fileslist
if len(files) > 4:
fileslist += ' ...'
fileslist += ']'
else:
fileslist = '-'
padded_url = construct_url(slug)
# Replace the ---- with the files list...
return message.replace('----', fileslist, 1) + padded_url
# Get a list of commits to report.
cwd = os.getcwd()
if (cwd.endswith('dns') and branch == 'master') or branch == 'main':
revs = run_command(f"git rev-list ^{old} {new}")["stdout"].split("\n")
revs = [r for r in revs if r]
revs.reverse()
for commit_hash in revs:
# Get the commit in a format that we can deal with
commit = run_command(
f"git show --name-status {commit_hash} --oneline "
f"--format='%an - {repodir}:%h ---- %s'")
parsed_commit = parse_commit(commit["stdout"])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ZODBOT_SERVER, ZODBOT_PORT))
msg = f"{channel} {parsed_commit}"
s.sendall(msg.encode('utf-8'))
s.close()