contrib / ciabot / ciabot.shon commit Improved documentation for the ciabot scripts. (6484070)
   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# Assistance and review by Petr Baudis, author of ciabot.pl,
   7# is gratefully acknowledged.
   8#
   9# This is a version 3.x of ciabot.sh; use -V to find the exact
  10# version.  Versions 1 and 2 were shipped in 2006 and 2008 and are not
  11# version-stamped.  The version 2 maintainer has passed the baton.
  12#
  13# Note: This script should be considered obsolete.
  14# There is a faster, better-documented rewrite in Python: find it as ciabot.py
  15# Use this only if your hosting site forbids Python hooks.
  16# It requires: git(1), hostname(1), cut(1), sendmail(1), and wget(1).
  17#
  18# Originally based on Git ciabot.pl by Petr Baudis.
  19# This script contains porcelain and porcelain byproducts.
  20#
  21# usage: ciabot.sh [-V] [-n] [-p projectname] [refname commit]
  22#
  23# This script is meant to be run either in a post-commit hook or in an
  24# update hook.  If there's nothing unusual about your hosting setup,
  25# you can specify the project name and repo with config variables and
  26# avoid having to modify this script.  Try it with -n to see the
  27# notification mail dumped to stdout and verify that it looks
  28# sane. With -V it dumps its version and exits.
  29#
  30# In post-commit, run it without arguments. It will query for
  31# current HEAD and the latest commit ID to get the information it
  32# needs.
  33#
  34# In update, you have to call it once per merged commit:
  35#
  36#       refname=$1
  37#       oldhead=$2
  38#       newhead=$3
  39#       for merged in $(git rev-list ${oldhead}..${newhead} | tac) ; do
  40#               /path/to/ciabot.sh ${refname} ${merged}
  41#       done
  42#
  43# The reason for the tac call is that git rev-list emits commits from
  44# most recent to least - better to ship notifactions from oldest to newest.
  45#
  46# Configuration variables affecting this script:
  47# ciabot.project = name of the project (makes -p option unnecessary)
  48# ciabot.repo = name of the project repo for gitweb/cgit purposes
  49# ciabot.revformat = format in which the revision is shown
  50#
  51# The ciabot.repo defaults to ciabot.project lowercased.
  52#
  53# The revformat variable may have the following values
  54# raw -> full hex ID of commit
  55# short -> first 12 chars of hex ID
  56# describe = -> describe relative to last tag, falling back to short
  57# The default is 'describe'.
  58#
  59# Note: the shell ancestors of this script used mail, not XML-RPC, in
  60# order to avoid stalling until timeout when the CIA XML-RPC server is
  61# down. It is unknown whether this is still an issue in 2010, but
  62# XML-RPC would be annoying to do from sh in any case. (XML-RPC does
  63# have the advantage that it guarantees notification of multiple commits
  64# shpped from an update in their actual order.)
  65#
  66
  67# The project as known to CIA. You can also hardwire this or set it with a
  68# -p option.
  69project=$(git config --get ciabot.project)
  70
  71# Name of the repo for gitweb/cgit purposes
  72repo=$(git config --get ciabot.repo)
  73[ -z $repo] && repo=$(echo "${project}" | tr '[A-Z]' '[a-z]')
  74
  75# What revision format do we want in the summary?
  76revformat=$(git config --get ciabot.revformat)
  77
  78# Fully qualified domain name of the repo host.  You can hardwire this
  79# to make the script faster. The -f option works under Linux and FreeBSD,
  80# but not OpenBSD and NetBSD. But under OpenBSD and NetBSD,
  81# hostname without options gives the FQDN.
  82if hostname -f >/dev/null 2>&1
  83then
  84    hostname=`hostname -f`
  85else
  86    hostname=`hostname`
  87fi
  88
  89# Changeset URL prefix for your repo: when the commit ID is appended
  90# to this, it should point at a CGI that will display the commit
  91# through gitweb or something similar. The defaults will probably
  92# work if you have a typical gitweb/cgit setup.
  93#urlprefix="http://${host}/cgi-bin/gitweb.cgi?p=${repo};a=commit;h="
  94urlprefix="http://${host}/cgi-bin/cgit.cgi/${repo}/commit/?id="
  95
  96#
  97# You probably will not need to change the following:
  98#
  99
 100# Identify the script. The 'generator' variable should change only
 101# when the script itself gets a new home and maintainer.
 102generator="http://www.catb.org/~esr/ciabot/ciabot.sh"
 103version=3.4
 104
 105# Addresses for the e-mail
 106from="CIABOT-NOREPLY@${hostname}"
 107to="cia@cia.vc"
 108
 109# SMTP client to use - may need to edit the absolute pathname for your system
 110sendmail="sendmail -t -f ${from}"
 111
 112#
 113# No user-serviceable parts below this line:
 114#
 115
 116# Should include all places sendmail is likely to lurk.
 117PATH="$PATH:/usr/sbin/"
 118
 119mode=mailit
 120while getopts pnV opt
 121do
 122    case $opt in
 123        p) project=$2; shift ; shift ;;
 124        n) mode=dumpit; shift ;;
 125        V) echo "ciabot.sh: version $version"; exit 0; shift ;;
 126    esac
 127done
 128
 129# Cough and die if user has not specified a project
 130if [ -z "$project" ]
 131then
 132    echo "ciabot.sh: no project specified, bailing out." >&2
 133    exit 1
 134fi
 135
 136if [ $# -eq 0 ] ; then
 137        refname=$(git symbolic-ref HEAD 2>/dev/null)
 138        merged=$(git rev-parse HEAD)
 139else
 140        refname=$1
 141        merged=$2
 142fi
 143
 144# This tries to turn your gitwebbish URL into a tinyurl so it will take up
 145# less space on the IRC notification line. Some repo sites (I'm looking at
 146# you, berlios.de!) forbid wget calls for security reasons.  On these,
 147# the code will fall back to the full un-tinyfied URL.
 148longurl=${urlprefix}${merged}
 149url=$(wget -O - -q http://tinyurl.com/api-create.php?url=${longurl} 2>/dev/null)
 150if [ -z "$url" ]; then
 151        url="${longurl}"
 152fi
 153
 154refname=${refname##refs/heads/}
 155
 156case $revformat in
 157raw) rev=$merged ;;
 158short) rev='' ;;
 159*) rev=$(git describe ${merged} 2>/dev/null) ;;
 160esac
 161[ -z ${rev} ] && rev=$(echo "$merged" | cut -c 1-12)
 162
 163# We discard the part of the author's address after @.
 164# Might be nice to ship the full email address, if not
 165# for spammers' address harvesters - getting this wrong
 166# would make the freenode #commits channel into harvester heaven.
 167author=$(git log -1 '--pretty=format:%an <%ae>' $merged)
 168author=$(echo "$author" | sed -n -e '/^.*<\([^@]*\).*$/s--\1-p')
 169
 170logmessage=$(git log -1 '--pretty=format:%s' $merged)
 171ts=$(git log -1 '--pretty=format:%at' $merged)
 172files=$(git diff-tree -r --name-only ${merged} | sed -e '1d' -e 's-.*-<file>&</file>-')
 173
 174out="
 175<message>
 176  <generator>
 177    <name>CIA Shell client for Git</name>
 178    <version>${version}</version>
 179    <url>${generator}</url>
 180  </generator>
 181  <source>
 182    <project>${project}</project>
 183    <branch>$repo:${refname}</branch>
 184  </source>
 185  <timestamp>${ts}</timestamp>
 186  <body>
 187    <commit>
 188      <author>${author}</author>
 189      <revision>${rev}</revision>
 190      <files>
 191        ${files}
 192      </files>
 193      <log>${logmessage} ${url}</log>
 194      <url>${url}</url>
 195    </commit>
 196  </body>
 197</message>"
 198
 199if [ "$mode" = "dumpit" ]
 200then
 201    sendmail=cat
 202fi
 203
 204${sendmail} << EOM
 205Message-ID: <${merged}.${author}@${project}>
 206From: ${from}
 207To: ${to}
 208Content-type: text/xml
 209Subject: DeliverXML
 210${out}
 211EOM
 212
 213# vim: set tw=70 :