Port to the new pygit2 fedmsg git hook.
See https://github.com/fedora-infra/fedmsg/pull/310
This commit is contained in:
parent
beb5348251
commit
9e6b062936
2 changed files with 101 additions and 41 deletions
|
@ -1,50 +1,24 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import getpass
|
import getpass
|
||||||
import git
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
import pygit2
|
||||||
|
|
||||||
import fedmsg
|
import fedmsg
|
||||||
import fedmsg.config
|
import fedmsg.config
|
||||||
|
|
||||||
# Read in all the rev information git-receive-pack hands us.
|
|
||||||
lines = [line.split() for line in sys.stdin.readlines()]
|
|
||||||
|
|
||||||
# Use $GIT_DIR to determine where this repo is.
|
# Use $GIT_DIR to determine where this repo is.
|
||||||
abspath = os.path.abspath(os.environ['GIT_DIR'])
|
abspath = os.path.abspath(os.environ['GIT_DIR'])
|
||||||
|
# This assumes git root dir is named "repo_name.git"
|
||||||
repo_name = '.'.join(abspath.split(os.path.sep)[-1].split('.')[:-1])
|
repo_name = '.'.join(abspath.split(os.path.sep)[-1].split('.')[:-1])
|
||||||
|
|
||||||
username = getpass.getuser()
|
username = getpass.getuser()
|
||||||
|
|
||||||
repo = git.repo.Repo(abspath)
|
repo = pygit2.Repository(abspath)
|
||||||
def _build_commit(rev):
|
|
||||||
old, rev, branch = rev
|
|
||||||
branch = '/'.join(branch.split('/')[2:])
|
|
||||||
commit = repo.rev_parse(rev=rev)
|
|
||||||
|
|
||||||
# We just don't handle these
|
|
||||||
if isinstance(commit, git.TagObject):
|
|
||||||
return None
|
|
||||||
|
|
||||||
return dict(
|
|
||||||
name=commit.author.name,
|
|
||||||
email=commit.author.email,
|
|
||||||
username=username,
|
|
||||||
summary=commit.summary,
|
|
||||||
message=commit.message,
|
|
||||||
stats=dict(
|
|
||||||
files=commit.stats.files,
|
|
||||||
total=commit.stats.total,
|
|
||||||
),
|
|
||||||
rev=rev,
|
|
||||||
path=abspath,
|
|
||||||
repo=repo_name,
|
|
||||||
branch=branch,
|
|
||||||
agent=os.getlogin(),
|
|
||||||
)
|
|
||||||
|
|
||||||
commits = map(_build_commit, lines)
|
|
||||||
|
|
||||||
print "Emitting a message to the fedmsg bus."
|
print "Emitting a message to the fedmsg bus."
|
||||||
config = fedmsg.config.load_config([], None)
|
config = fedmsg.config.load_config([], None)
|
||||||
|
@ -52,14 +26,96 @@ config['active'] = True
|
||||||
config['endpoints']['relay_inbound'] = config['relay_inbound']
|
config['endpoints']['relay_inbound'] = config['relay_inbound']
|
||||||
fedmsg.init(name='relay_inbound', cert_prefix='scm', **config)
|
fedmsg.init(name='relay_inbound', cert_prefix='scm', **config)
|
||||||
|
|
||||||
for commit in commits:
|
def revs_between(head, base):
|
||||||
|
bail = False
|
||||||
|
|
||||||
if commit is None:
|
yield unicode(head.id)
|
||||||
|
|
||||||
|
for parent in head.parents:
|
||||||
|
if parent.id == base.id:
|
||||||
|
bail = True
|
||||||
|
|
||||||
|
if not bail:
|
||||||
|
for parent in head.parents:
|
||||||
|
for rev in revs_between(parent, base):
|
||||||
|
yield rev
|
||||||
|
|
||||||
|
|
||||||
|
def build_stats(commit):
|
||||||
|
files = defaultdict(lambda: defaultdict(int))
|
||||||
|
|
||||||
|
# Calculate diffs against all parent commits
|
||||||
|
diffs = [repo.diff(parent, commit) for parent in commit.parents]
|
||||||
|
# Unless this is the first commit, with no parents.
|
||||||
|
diffs = diffs or [commit.tree.diff_to_tree(swap=True)]
|
||||||
|
|
||||||
|
for diff in diffs:
|
||||||
|
for patch in diff:
|
||||||
|
path = patch.new_file_path
|
||||||
|
files[path]['additions'] += patch.additions
|
||||||
|
files[path]['deletions'] += patch.deletions
|
||||||
|
files[path]['lines'] += patch.additions + patch.deletions
|
||||||
|
|
||||||
|
total = defaultdict(int)
|
||||||
|
for name, stats in files.items():
|
||||||
|
total['additions'] += stats['additions']
|
||||||
|
total['deletions'] += stats['deletions']
|
||||||
|
total['lines'] += stats['lines']
|
||||||
|
total['files'] += 1
|
||||||
|
|
||||||
|
return files, total
|
||||||
|
|
||||||
|
|
||||||
|
# Read in all the rev information git-receive-pack hands us.
|
||||||
|
lines = [line.split() for line in sys.stdin.readlines()]
|
||||||
|
for line in lines:
|
||||||
|
base, head, branch = line
|
||||||
|
branch = '/'.join(branch.split('/')[2:])
|
||||||
|
|
||||||
|
try:
|
||||||
|
head = repo.revparse_single(head)
|
||||||
|
except KeyError:
|
||||||
|
# This means they are deleting this branch.. and we don't have a fedmsg
|
||||||
|
# for that (yet?). It is disallowed by dist-git in Fedora anyways.
|
||||||
continue
|
continue
|
||||||
|
|
||||||
fedmsg.publish(
|
try:
|
||||||
# Expect this to change to just "receive" in the future.
|
base = repo.revparse_single(base)
|
||||||
topic="receive",
|
revs = revs_between(head, base)
|
||||||
msg=dict(commit=commit),
|
except KeyError:
|
||||||
modname="git",
|
revs = [unicode(head.id)]
|
||||||
)
|
|
||||||
|
def _build_commit(rev):
|
||||||
|
commit = repo.revparse_single(rev)
|
||||||
|
|
||||||
|
files, total = build_stats(commit)
|
||||||
|
|
||||||
|
return dict(
|
||||||
|
name=commit.author.name,
|
||||||
|
email=commit.author.email,
|
||||||
|
username=username,
|
||||||
|
summary=commit.message.split('\n')[0],
|
||||||
|
message=commit.message,
|
||||||
|
stats=dict(
|
||||||
|
files=files,
|
||||||
|
total=total,
|
||||||
|
),
|
||||||
|
rev=rev,
|
||||||
|
path=abspath,
|
||||||
|
repo=repo_name,
|
||||||
|
branch=branch,
|
||||||
|
agent=os.getlogin(),
|
||||||
|
)
|
||||||
|
|
||||||
|
commits = map(_build_commit, revs)
|
||||||
|
|
||||||
|
for commit in commits:
|
||||||
|
|
||||||
|
if commit is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
fedmsg.publish(
|
||||||
|
topic="receive",
|
||||||
|
msg=dict(commit=commit),
|
||||||
|
modname="git",
|
||||||
|
)
|
||||||
|
|
|
@ -5,10 +5,14 @@
|
||||||
yum: pkg={{item}} state=present
|
yum: pkg={{item}} state=present
|
||||||
with_items:
|
with_items:
|
||||||
- git
|
- git
|
||||||
- GitPython
|
|
||||||
- moreutils
|
- moreutils
|
||||||
- python-kitchen
|
- python-kitchen
|
||||||
|
|
||||||
|
- name: install needed packages from epel testing
|
||||||
|
yum: pkg={{item}} state=present enablerepo=epel-testing
|
||||||
|
with_items:
|
||||||
|
- pygit2
|
||||||
|
|
||||||
- name: install the git hooks
|
- name: install the git hooks
|
||||||
copy: src={{item}} dest=/usr/share/git-core/ mode=0755
|
copy: src={{item}} dest=/usr/share/git-core/ mode=0755
|
||||||
with_items:
|
with_items:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue