Created
May 4, 2012 16:14
-
-
Save GregSutcliffe/2595830 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# IRC notification post-receive hook. | |
# Based on https://wiki.icinga.org/display/community/GIT+Commit+Bot | |
# | |
# Author: Mikael Fridh <frimik@gmail.com> | |
# Modified by: Greg Sutcliffe <gsutcliffe@ibahn.com | |
# | |
# This script pulls out the commit information and sends it to | |
# the RemoteCtl plugin in rbot via quassel.office:7268 using | |
# a preconfigured user via: | |
# | |
# user create puppet password | |
# permissions set +remotectl for puppet | |
# permissions set +basics::talk::do for puppet | |
# | |
# FIXME read user, password, host and port from git config | |
# TODO add hooks.gitweb.url to point to http://example.com/gitweb | |
# | |
# Settings needed: | |
# git config hooks.irc.channel "#channel1 #channel2" | |
# git config hooks.irc.prefix "[repoprefix]" | |
# | |
# Optional settings: | |
# git config hooks.gitweb.baseurl "http://git.example.com/gitweb/?p=" | |
# This option should contain everything prior to the repo name which will be | |
# appended. | |
# | |
max=5 | |
function notify () | |
{ | |
oldrev=$(git rev-parse $1) | |
newrev=$(git rev-parse $2) | |
refname="$3" | |
# --- Interpret | |
# 0000->1234 (create) | |
# 1234->2345 (update) | |
# 2345->0000 (delete) | |
if expr "$oldrev" : '0*$' >/dev/null | |
then | |
change_type="create" | |
else | |
if expr "$newrev" : '0*$' >/dev/null | |
then | |
change_type="delete" | |
else | |
change_type="update" | |
fi | |
fi | |
# --- Get the revision types | |
newrev_type=$(git cat-file -t $newrev 2> /dev/null) | |
oldrev_type=$(git cat-file -t "$oldrev" 2> /dev/null) | |
case "$change_type" in | |
create|update) | |
rev="$newrev" | |
rev_type="$newrev_type" | |
;; | |
delete) | |
rev="$oldrev" | |
rev_type="$oldrev_type" | |
;; | |
esac | |
# The revision type tells us what type the commit is, combined with | |
# the location of the ref we can decide between | |
# - working branch | |
# - tracking branch | |
# - unannoted tag | |
# - annotated tag | |
case "$refname","$rev_type" in | |
refs/tags/*,commit) | |
# un-annotated tag | |
refname_type="tag" | |
short_refname=${refname##refs/tags/} | |
;; | |
refs/tags/*,tag) | |
# annotated tag | |
refname_type="annotated tag" | |
short_refname=${refname##refs/tags/} | |
# change recipients | |
if [ -n "$announcerecipients" ]; then | |
recipients="$announcerecipients" | |
fi | |
;; | |
refs/heads/*,commit) | |
# branch | |
refname_type="branch" | |
short_refname=${refname##refs/heads/} | |
;; | |
refs/remotes/*,commit) | |
# tracking branch | |
refname_type="tracking branch" | |
short_refname=${refname##refs/remotes/} | |
echo >&2 "*** Push-update of tracking branch, $refname" | |
echo >&2 "*** - no notification generated." | |
return 0 | |
;; | |
*) | |
# Anything else (is there anything else?) | |
echo >&2 "*** Unknown type of update to $refname ($rev_type)" | |
echo >&2 "*** - no notification generated" | |
return 0 | |
;; | |
esac | |
# plural suffix, default "", changed to "s" if commits > 1 | |
s="" | |
# Repo name, either Gitolite or normal repo. | |
if [ -n "$GL_REPO" ]; then | |
# it's a gitolite repo | |
repodir=$(basename `pwd`) | |
repo=$GL_REPO | |
else | |
repodir=$(basename `pwd`) | |
repo=${repodir%.git} | |
fi | |
gitweb_baseurl=$(git config hooks.gitweb.baseurl) | |
if [ -z "$gitweb_baseurl" ]; then | |
# if there is no value for gitweb_baseurl, fall back to some Marin | |
# default values | |
if [ -n "$GL_REPO" ]; then | |
# gitolite repo, add special gitolite/ prefix (Marin hardcoded until we | |
# move everything to gitolite hosting) | |
gitweb_baseurl="http://git.example.com/gitweb/?p=gitolite/" | |
else | |
# non-gitolite repo, no special prefix | |
gitweb_baseurl="http://git.example.com/gitweb/?p=" | |
fi | |
fi | |
# otherwise, assume git config value is good: | |
url="${gitweb_baseurl}${repodir};a=commit;h=" | |
head="${gitweb_baseurl}${repodir};a=shortlog;h=${3}" | |
# ETV override, we don't use gitweb | |
url="" | |
head="" | |
repoprefix=$(git config hooks.irc.prefix || git config hooks.emailprefix || echo "[$repo]") | |
# Get the user information | |
# If $GL_USER is set we're running under gitolite. | |
if [ -n "$GL_USER" ]; then | |
user=$GL_USER | |
else | |
user=$USER | |
fi | |
case ${change_type} in | |
"create") | |
header="${repoprefix} $user ${change_type}d the $refname_type $short_refname: ${head}." | |
;; | |
"delete") | |
header="${repoprefix} $user ${change_type}d the $refname_type $short_refname." | |
;; | |
"update") | |
num=$(git log --pretty=oneline ${1}..${2}|wc -l) | |
branch=${3/refs\/heads\//} | |
if [ ${num} -gt 1 ]; then | |
s="s" | |
fi | |
header="${repoprefix} $user pushed ${num} new commit${s} to ${branch}: ${head}" | |
;; | |
*) | |
# most weird ... this should never happen | |
echo >&2 "*** Unknown type of update to $refname ($rev_type)" | |
echo >&2 "*** - notifications will probably screw up." | |
;; | |
esac | |
channels=$(git config hooks.irc.channel) | |
auth=$(git config hooks.irc.auth) | |
host=$(echo $auth|cut -d':' -f1) | |
port=$(echo $auth|cut -d':' -f2) | |
user=$(echo $auth|cut -d':' -f3) | |
pass=$(echo $auth|cut -d':' -f4) | |
# Run once for each channel in the notify list: | |
for chan in $channels | |
do | |
echo "${header}" | rbot-remote -u "${user}" -p "${pass}" -d "${chan}" -r "druby://${host}:${port}" 2>&1 >/dev/null | |
if [ "${change_type}" == "update" ]; then | |
if [ ${num} -lt ${max} ]; then | |
git log --pretty=format:"%h by %an: %s" ${1}..${2} | rbot-remote -u "${user}" -p "${pass}" -d "${chan}" -r "druby://${host}:${port}" 2>&1 >/dev/null | |
fi | |
fi | |
done | |
} | |
# MAIN PROGRAM | |
# Read all refs from stdin, notify for each | |
while read line; do | |
set -- $line | |
notify $* | |
RET=$? | |
done | |
exit $RET | |
# vim: set filetype=sh: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment