function help() {
echo "Required config settings:"
echo " git config hooks.slack.webhook-url 'https://hooks.slack.com/services/...'"
echo " git config hooks.slack.channel 'general'"
echo " git config hooks.slack.show-only-last-commit true #optional"
echo " git config hooks.slack.show-full-commit true #optional"
echo " git config hooks.slack.username 'git' #optional"
echo " git config hooks.slack.icon-url 'http://imgur/icon.png' #optional"
echo " git config hooks.slack.icon-emoji ':twisted_rightwards_arrows:' #optional"
echo " git config hooks.slack.repo-nice-name 'MyRepo' #optional"
echo " git config hooks.slack.repos-root '/path/to/repos' #optional"
echo " git config hooks.slack.changeset-url-pattern 'http://yourserver/%repo_path%/changeset/%rev_hash%' #optional"
echo " git config hooks.slack.compare-url-pattern 'http://yourserver/%repo_path%/changeset/%old_rev_hash%..%new_rev_hash%' #optional"
echo " git config hooks.slack.branch-regexp 'regexp' #optional"
}
function replace_variables() {
sed "s|%repo_path%|$repopath|g;s|%old_rev_hash%|$oldrev|g;s|%new_rev_hash%|$newrev|g;s|%rev_hash%|$newrev|g;s|%repo_prefix%|$repoprefix|g"
}
function notify() {
oldrev=$(git rev-parse $1)
newrev=$(git rev-parse $2)
refname="$3"
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
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
case "$refname","$rev_type" in
refs/tags/*,commit)
refname_type="tag"
short_refname=${refname##refs/tags/}
;;
refs/tags/*,tag)
refname_type="annotated tag"
short_refname=${refname##refs/tags/}
if [ -n "$announcerecipients" ]; then
recipients="$announcerecipients"
fi
;;
refs/heads/*,commit)
refname_type="branch"
short_refname=${refname##refs/heads/}
;;
refs/remotes/*,commit)
refname_type="tracking branch"
short_refname=${refname##refs/remotes/}
echo >&2 "*** Push-update of tracking branch, $refname"
echo >&2 "*** - no notification generated."
return 0
;;
*)
echo >&2 "*** Unknown type of update to $refname ($rev_type)"
echo >&2 "*** - no notification generated"
return 0
;;
esac
branchregexp=$(git config --get hooks.slack.branch-regexp)
if [ -n "$branchregexp" ]; then
if [[ ! $short_refname =~ $branchregexp ]]; then
exit 0;
fi
fi
s=""
if [ -n "$GL_REPO" ]; then
repodir=$(basename $(pwd))
repo=$GL_REPO
else
repodir=$(basename $(pwd))
if [ "$repodir" == ".git" ]; then
repodir=$(dirname $PWD)
repodir=$(basename $repodir)
fi
repo=${repodir%.git}
fi
repoprefix=$(git config hooks.slack.repo-nice-name || git config hooks.irc.prefix || git config hooks.emailprefix || echo "$repo")
onlylast=$(git config --get hooks.slack.show-only-last-commit)
onlylast=$onlylast && [ -n "$onlylast" ]
fullcommit=$(git config --get hooks.slack.show-full-commit)
if [ -n "$GL_USER" ]; then
user=$GL_USER
else
user=$USER
fi
case ${change_type} in
"create")
header="New ${refname_type} *${short_refname}* has been created in ${repoprefix}"
single_commit_suffix="commit"
;;
"delete")
header="$(tr '[:lower:]' '[:upper:]' <<< ${refname_type:0:1})${refname_type:1} *$short_refname* has been deleted from ${repoprefix}"
single_commit_suffix="commit"
;;
"update")
num=$(git log --pretty=oneline ${1}..${2}|wc -l|tr -d ' ')
branch=${3/refs\/heads\//}
if [ ${num} -gt 1 ]; then
header="${num} new commits *pushed* to *${short_refname}* in ${repoprefix}"
single_commit_suffix="one"
s="s"
else
header="A new commit has been *pushed* to *${short_refname}* in ${repoprefix}"
single_commit_suffix="one"
fi
;;
*)
echo >&2 "*** Unknown type of update to $refname ($rev_type)"
echo >&2 "*** - notifications will probably screw up."
;;
esac
if $onlylast && [[ "${change_type}" != "delete" ]]; then
header="$header, showing last $single_commit_suffix:"
fi
if [[ "${change_type}" != "delete" && "${refname_type}" == "branch" ]]; then
changeseturlpattern=$(git config --get hooks.slack.changeset-url-pattern)
compareurlpattern=$(git config --get hooks.slack.compare-url-pattern)
reporoot=$(git config --get hooks.slack.repos-root)
urlformat=
if [ -n "$changeseturlpattern" -a -n "$reporoot" ]; then
if [[ $PWD == ${reporoot}* ]]; then
repopath=$PWD
base=$(basename $PWD)
if [ "$base" == ".git" ]; then
repopath=$(dirname $repopath)
fi
idx=$(echo $reporoot | wc -c | tr -d ' ')
repopath=$(echo $repopath | cut -c$idx-)
urlformat=$(echo $changeseturlpattern | replace_variables)
if [ -n "$compareurlpattern" ]; then
comparelink=$(echo $compareurlpattern | replace_variables)
header=$(echo $header | sed -e "s|\([a-zA-Z0-9]\{1,\} new commit[s]\{0,1\}\)|\<$comparelink\|\\1\>|")
fi
else
echo >&2 "$PWD is not in $reporoot. Not creating hyperlinks."
fi
fi
formattedurl=""
if [ -n "$urlformat" ]; then
formattedurl="<${urlformat}|%h> "
fi
nl="\\\\n"
if [[ "${change_type}" == "update" ]]; then
start="${1}"
else
start="HEAD"
fi
end="${2}"
if $onlylast; then
countarg="-n 1"
else
countarg=""
fi
if [ "$fullcommit" == "true" ]; then
commitformat="%s%n%n%b"
else
commitformat="%s"
fi
log_out=$( git log --pretty=format:"&&&&&%cN;;;;;${formattedurl}${commitformat}@@@@@" $countarg ${start}..${end} \
| perl -p -e 's/@@@@@\n+/@@@@@/mg' \
| sed -e 's/\\/\\\\/g' \
| sed -e 's/"/\\"/g' \
| sed -e 's/&&&&&\(.*\);;;;;/{ \"fallback\" : \"\", \"color\" : \"good\", \"fields\" : [{"title":"\1","value":"/g' \
| sed -e 's/@@@@@/","short":false},]},/g' \
| sed -e 's/,\]/]/' )
attachments="[${log_out%?}]"
fi
if [ -n "${attachments}" ] && [[ "${attachments}" != "" ]]; then
msg=$(echo -e "\"text\":\"${header}\", \"attachments\" : $attachments")
else
msg=$(echo -e "\"text\":\"${header}\"")
fi
msg=$(echo -n "${msg}" | perl -p -e 's/\n/\\n/mg')
webhook_url=$(git config --get hooks.slack.webhook-url)
channel=$(git config --get hooks.slack.channel)
username=$(git config --get hooks.slack.username)
iconurl=$(git config --get hooks.slack.icon-url)
iconemoji=$(git config --get hooks.slack.icon-emoji)
if [ -z "$webhook_url" ]; then
echo "ERROR: config settings not found"
help
exit 1
fi
payload="{${msg}"
if [ -n "$channel" ]; then
payload="$payload, \"channel\": \"$channel\""
fi
if [ -n "$username" ]; then
payload="$payload, \"username\": \"$username\""
fi
if [ -n "$iconurl" ]; then
payload="$payload, \"icon_url\": \"$iconurl\""
elif [ -n "$iconemoji" ]; then
payload="$payload, \"icon_emoji\": \"$iconemoji\""
fi
payload="$payload}"
if [ -n "$DEBUG" ]; then
echo "POST $webhook_url"
echo "payload=$payload"
return
fi
curl -s \
-d "payload=$payload" \
"$webhook_url" \
>/dev/null
}
while read line; do
set -- $line
notify $*
RET=$?
done
exit $RET