contrib / ciabot / ciabot.shon commit refactor run_receive_hook() (9684e44)
   1#!/bin/sh
   2# Distributed under the terms of the GNU General Public License v2
   3# Copyright (c) 2006 Fernando J. Pereda <ferdy@gentoo.org>
   4# Copyright (c) 2008 Natanael Copa <natanael.copa@gmail.com>
   5# Copyright (c) 2010 Eric S. Raymond <esr@thyrsus.com>
   6#
   7# This is a version 3.x of ciabot.sh; use -V to find the exact
   8# version.  Versions 1 and 2 were shipped in 2006 and 2008 and are not
   9# version-stamped.  The version 2 maintainer has passed the baton.
  10#
  11# Note: This script should be considered obsolete.
  12# There is a faster, better-documented rewrite in Python: find it as ciabot.py
  13# Use this only if your hosting site forbids Python hooks.
  14#
  15# Originally based on Git ciabot.pl by Petr Baudis.
  16# This script contains porcelain and porcelain byproducts.
  17#
  18# usage: ciabot.sh [-V] [-n] [-p projectname] [refname commit]
  19#
  20# This script is meant to be run either in a post-commit hook or in an
  21# update hook.  If there's nothing unusual about your hosting setup,
  22# you can specify the project name with a -p option and avoid having
  23# to modify this script.  Try it with -n first to see the notification
  24# mail dumped to stdout and verify that it looks sane.  Use -V to dump
  25# the version and exit.
  26#
  27# In post-commit, run it without arguments (other than possibly a -p
  28# option). It will query for current HEAD and the latest commit ID to
  29# get the information it needs.
  30#
  31# In update, you have to call it once per merged commit:
  32#
  33#       refname=$1
  34#       oldhead=$2
  35#       newhead=$3
  36#       for merged in $(git rev-list ${oldhead}..${newhead} | tac) ; do
  37#               /path/to/ciabot.bash ${refname} ${merged}
  38#       done
  39#
  40# The reason for the tac call ids that git rev-list emits commits from
  41# most recent to least - better to ship notifactions from oldest to newest.
  42#
  43# Note: this script uses mail, not XML-RPC, in order to avoid stalling
  44# until timeout when the CIA XML-RPC server is down.
  45#
  46
  47#
  48# The project as known to CIA. You will either want to change this
  49# or set the project name with a -p option.
  50#
  51project=
  52
  53#
  54# You may not need to change these:
  55#
  56
  57# Name of the repository.
  58# You can hardwire this to make the script faster.
  59repo="`basename ${PWD}`"
  60
  61# Fully qualified domain name of the repo host.
  62# You can hardwire this to make the script faster.
  63host=`hostname --fqdn`
  64
  65# Changeset URL prefix for your repo: when the commit ID is appended
  66# to this, it should point at a CGI that will display the commit
  67# through gitweb or something similar. The defaults will probably
  68# work if you have a typical gitweb/cgit setup.
  69#urlprefix="http://${host}/cgi-bin/gitweb.cgi?p=${repo};a=commit;h="
  70urlprefix="http://${host}/cgi-bin/cgit.cgi/${repo}/commit/?id="
  71
  72#
  73# You probably will not need to change the following:
  74#
  75
  76# Identify the script. Should change only when the script itself
  77# gets a new home and maintainer.
  78generator="http://www.catb.org/~esr/ciabot/ciabot.sh"
  79
  80# Addresses for the e-mail
  81from="CIABOT-NOREPLY@${host}"
  82to="cia@cia.navi.cx"
  83
  84# SMTP client to use - may need to edit the absolute pathname for your system
  85sendmail="sendmail -t -f ${from}"
  86
  87#
  88# No user-serviceable parts below this line:
  89#
  90
  91# Should include all places sendmail is likely to lurk.
  92PATH="$PATH:/usr/sbin/"
  93
  94mode=mailit
  95while getopts pnV opt
  96do
  97    case $opt in
  98        p) project=$2; shift ; shift ;;
  99        n) mode=dumpit; shift ;;
 100        V) echo "ciabot.sh: version 3.2"; exit 0; shift ;;
 101    esac
 102done
 103
 104# Cough and die if user has not specified a project
 105if [ -z "$project" ]
 106then
 107    echo "ciabot.sh: no project specified, bailing out." >&2
 108    exit 1
 109fi
 110
 111if [ $# -eq 0 ] ; then
 112        refname=$(git symbolic-ref HEAD 2>/dev/null)
 113        merged=$(git rev-parse HEAD)
 114else
 115        refname=$1
 116        merged=$2
 117fi
 118
 119# This tries to turn your gitwebbish URL into a tinyurl so it will take up
 120# less space on the IRC notification line. Some repo sites (I'm looking at
 121# you, berlios.de!) forbid wget calls for security reasons.  On these,
 122# the code will fall back to the full un-tinyfied URL.
 123longurl=${urlprefix}${merged}
 124url=$(wget -O - -q http://tinyurl.com/api-create.php?url=${longurl} 2>/dev/null)
 125if [ -z "$url" ]; then
 126        url="${longurl}"
 127fi
 128
 129refname=${refname##refs/heads/}
 130
 131gitver=$(git --version)
 132gitver=${gitver##* }
 133
 134rev=$(git describe ${merged} 2>/dev/null)
 135# ${merged:0:12} was the only bashism left in the 2008 version of this
 136# script, according to checkbashisms.  Replace it with ${merged} here
 137# because it was just a fallback anyway, and it's worth accepting a
 138# longer fallback for faster execution and removing the bash
 139# dependency.
 140[ -z ${rev} ] && rev=${merged}
 141
 142# This discards the part of the author's address after @.
 143# Might be nice to ship the full email address, if not
 144# for spammers' address harvesters - getting this wrong
 145# would make the freenode #commits channel into harvester heaven.
 146rawcommit=$(git cat-file commit ${merged})
 147author=$(echo "$rawcommit" | sed -n -e '/^author .*<\([^@]*\).*$/s--\1-p')
 148logmessage=$(echo "$rawcommit" | sed -e '1,/^$/d' | head -n 1)
 149logmessage=$(echo "$logmessage" | sed 's/\&/&amp\;/g; s/</&lt\;/g; s/>/&gt\;/g')
 150ts=$(echo "$rawcommit" | sed -n -e '/^author .*> \([0-9]\+\).*$/s--\1-p')
 151files=$(git diff-tree -r --name-only ${merged} | sed -e '1d' -e 's-.*-<file>&</file>-')
 152
 153out="
 154<message>
 155  <generator>
 156    <name>CIA Shell client for Git</name>
 157    <version>${gitver}</version>
 158    <url>${generator}</url>
 159  </generator>
 160  <source>
 161    <project>${project}</project>
 162    <branch>$repo:${refname}</branch>
 163  </source>
 164  <timestamp>${ts}</timestamp>
 165  <body>
 166    <commit>
 167      <author>${author}</author>
 168      <revision>${rev}</revision>
 169      <files>
 170        ${files}
 171      </files>
 172      <log>${logmessage} ${url}</log>
 173      <url>${url}</url>
 174    </commit>
 175  </body>
 176</message>"
 177
 178if [ "$mode" = "dumpit" ]
 179then
 180    sendmail=cat
 181fi
 182
 183${sendmail} << EOM
 184Message-ID: <${merged}.${author}@${project}>
 185From: ${from}
 186To: ${to}
 187Content-type: text/xml
 188Subject: DeliverXML
 189${out}
 190EOM
 191
 192# vim: set tw=70 :